blob: a1ac229f015068305cd31237a73eb1761c802a7c [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
Michael Wright2b3c3302018-03-02 17:19:13 +000022#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080023#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080024#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050025#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070026#include <binder/Binder.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080027#include <ftl/enum.h>
chaviw15fab6f2021-06-07 14:15:52 -050028#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080029#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070030#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000031#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070032#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010033#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070034#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080035
Michael Wright44753b12020-07-08 13:48:11 +010036#include <cerrno>
37#include <cinttypes>
38#include <climits>
39#include <cstddef>
40#include <ctime>
41#include <queue>
42#include <sstream>
43
44#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070045#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010046
Michael Wrightd02c5b62014-02-10 15:10:22 -080047#define INDENT " "
48#define INDENT2 " "
49#define INDENT3 " "
50#define INDENT4 " "
51
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080052using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000053using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080054using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070055using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050056using android::gui::FocusRequest;
57using android::gui::TouchOcclusionMode;
58using android::gui::WindowInfo;
59using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080060using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100061using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080062using android::os::InputEventInjectionResult;
63using android::os::InputEventInjectionSync;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080064
Garfield Tane84e6f92019-08-29 17:28:41 -070065namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
Prabir Pradhancef936d2021-07-21 16:17:52 +000067namespace {
68
Prabir Pradhan61a5d242021-07-26 16:41:09 +000069// Log detailed debug messages about each inbound event notification to the dispatcher.
70constexpr bool DEBUG_INBOUND_EVENT_DETAILS = false;
71
72// Log detailed debug messages about each outbound event processed by the dispatcher.
73constexpr bool DEBUG_OUTBOUND_EVENT_DETAILS = false;
74
75// Log debug messages about the dispatch cycle.
76constexpr bool DEBUG_DISPATCH_CYCLE = false;
77
78// Log debug messages about channel creation
79constexpr bool DEBUG_CHANNEL_CREATION = false;
80
81// Log debug messages about input event injection.
82constexpr bool DEBUG_INJECTION = false;
83
84// Log debug messages about input focus tracking.
85constexpr bool DEBUG_FOCUS = false;
86
Antonio Kantekf16f2832021-09-28 04:39:20 +000087// Log debug messages about touch mode event
88constexpr bool DEBUG_TOUCH_MODE = false;
89
Prabir Pradhan61a5d242021-07-26 16:41:09 +000090// Log debug messages about touch occlusion
Prabir Pradhan61a5d242021-07-26 16:41:09 +000091constexpr bool DEBUG_TOUCH_OCCLUSION = true;
92
93// Log debug messages about the app switch latency optimization.
94constexpr bool DEBUG_APP_SWITCH = false;
95
96// Log debug messages about hover events.
97constexpr bool DEBUG_HOVER = false;
98
Prabir Pradhancef936d2021-07-21 16:17:52 +000099// Temporarily releases a held mutex for the lifetime of the instance.
100// Named to match std::scoped_lock
101class scoped_unlock {
102public:
103 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
104 ~scoped_unlock() { mMutex.lock(); }
105
106private:
107 std::mutex& mMutex;
108};
109
Michael Wrightd02c5b62014-02-10 15:10:22 -0800110// Default input dispatching timeout if there is no focused application or paused window
111// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800112const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
113 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
114 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115
116// Amount of time to allow for all pending events to be processed when an app switch
117// key is on the way. This is used to preempt input dispatch and drop input events
118// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000119constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800120
121// Amount of time to allow for an event to be dispatched (measured since its eventTime)
122// before considering it stale and dropping it.
Vadim Tryshev78548252022-01-27 19:32:46 +0000123const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL // 10sec
124 * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800125
Michael Wrightd02c5b62014-02-10 15:10:22 -0800126// 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 +0000127constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
128
129// Log a warning when an interception call takes longer than this to process.
130constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800131
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700132// Additional key latency in case a connection is still processing some motion events.
133// This will help with the case when a user touched a button that opens a new window,
134// and gives us the chance to dispatch the key to this new window.
135constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
136
Michael Wrightd02c5b62014-02-10 15:10:22 -0800137// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000138constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
139
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000140// Event log tags. See EventLogTags.logtags for reference
141constexpr int LOGTAG_INPUT_INTERACTION = 62000;
142constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000143constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000144
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000145inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800146 return systemTime(SYSTEM_TIME_MONOTONIC);
147}
148
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000149inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800150 return value ? "true" : "false";
151}
152
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000153inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000154 if (binder == nullptr) {
155 return "<null>";
156 }
157 return StringPrintf("%p", binder.get());
158}
159
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000160inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700161 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
162 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163}
164
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000165bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800166 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700167 case AKEY_EVENT_ACTION_DOWN:
168 case AKEY_EVENT_ACTION_UP:
169 return true;
170 default:
171 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172 }
173}
174
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000175bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700176 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800177 ALOGE("Key event has invalid action code 0x%x", action);
178 return false;
179 }
180 return true;
181}
182
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000183bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700185 case AMOTION_EVENT_ACTION_DOWN:
186 case AMOTION_EVENT_ACTION_UP:
187 case AMOTION_EVENT_ACTION_CANCEL:
188 case AMOTION_EVENT_ACTION_MOVE:
189 case AMOTION_EVENT_ACTION_OUTSIDE:
190 case AMOTION_EVENT_ACTION_HOVER_ENTER:
191 case AMOTION_EVENT_ACTION_HOVER_MOVE:
192 case AMOTION_EVENT_ACTION_HOVER_EXIT:
193 case AMOTION_EVENT_ACTION_SCROLL:
194 return true;
195 case AMOTION_EVENT_ACTION_POINTER_DOWN:
196 case AMOTION_EVENT_ACTION_POINTER_UP: {
197 int32_t index = getMotionEventActionPointerIndex(action);
198 return index >= 0 && index < pointerCount;
199 }
200 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
201 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
202 return actionButton != 0;
203 default:
204 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800205 }
206}
207
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000208int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500209 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
210}
211
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000212bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
213 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700214 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800215 ALOGE("Motion event has invalid action code 0x%x", action);
216 return false;
217 }
218 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou01747382022-01-20 13:23:27 -0800219 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %zu.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700220 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 return false;
222 }
223 BitSet32 pointerIdBits;
224 for (size_t i = 0; i < pointerCount; i++) {
225 int32_t id = pointerProperties[i].id;
226 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700227 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
228 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 return false;
230 }
231 if (pointerIdBits.hasBit(id)) {
232 ALOGE("Motion event has duplicate pointer id %d", id);
233 return false;
234 }
235 pointerIdBits.markBit(id);
236 }
237 return true;
238}
239
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000240std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800241 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000242 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800243 }
244
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000245 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800246 bool first = true;
247 Region::const_iterator cur = region.begin();
248 Region::const_iterator const tail = region.end();
249 while (cur != tail) {
250 if (first) {
251 first = false;
252 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800253 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800255 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800256 cur++;
257 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000258 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259}
260
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000261std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500262 constexpr size_t maxEntries = 50; // max events to print
263 constexpr size_t skipBegin = maxEntries / 2;
264 const size_t skipEnd = queue.size() - maxEntries / 2;
265 // skip from maxEntries / 2 ... size() - maxEntries/2
266 // only print from 0 .. skipBegin and then from skipEnd .. size()
267
268 std::string dump;
269 for (size_t i = 0; i < queue.size(); i++) {
270 const DispatchEntry& entry = *queue[i];
271 if (i >= skipBegin && i < skipEnd) {
272 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
273 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
274 continue;
275 }
276 dump.append(INDENT4);
277 dump += entry.eventEntry->getDescription();
278 dump += StringPrintf(", seq=%" PRIu32
279 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
280 entry.seq, entry.targetFlags, entry.resolvedAction,
281 ns2ms(currentTime - entry.eventEntry->eventTime));
282 if (entry.deliveryTime != 0) {
283 // This entry was delivered, so add information on how long we've been waiting
284 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
285 }
286 dump.append("\n");
287 }
288 return dump;
289}
290
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700291/**
292 * Find the entry in std::unordered_map by key, and return it.
293 * If the entry is not found, return a default constructed entry.
294 *
295 * Useful when the entries are vectors, since an empty vector will be returned
296 * if the entry is not found.
297 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
298 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700299template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000300V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700301 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700302 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800303}
304
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000305bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700306 if (first == second) {
307 return true;
308 }
309
310 if (first == nullptr || second == nullptr) {
311 return false;
312 }
313
314 return first->getToken() == second->getToken();
315}
316
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000317bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000318 if (first == nullptr || second == nullptr) {
319 return false;
320 }
321 return first->applicationInfo.token != nullptr &&
322 first->applicationInfo.token == second->applicationInfo.token;
323}
324
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000325bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800326 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
327}
328
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000329std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
330 std::shared_ptr<EventEntry> eventEntry,
331 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700332 if (inputTarget.useDefaultPointerTransform()) {
333 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700334 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700335 inputTarget.displayTransform,
336 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000337 }
338
339 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
340 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
341
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700342 std::vector<PointerCoords> pointerCoords;
343 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000344
345 // Use the first pointer information to normalize all other pointers. This could be any pointer
346 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700347 // uses the transform for the normalized pointer.
348 const ui::Transform& firstPointerTransform =
349 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
350 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000351
352 // Iterate through all pointers in the event to normalize against the first.
353 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
354 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
355 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700356 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000357
358 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700359 // First, apply the current pointer's transform to update the coordinates into
360 // window space.
361 pointerCoords[pointerIndex].transform(currTransform);
362 // Next, apply the inverse transform of the normalized coordinates so the
363 // current coordinates are transformed into the normalized coordinate space.
364 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000365 }
366
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700367 std::unique_ptr<MotionEntry> combinedMotionEntry =
368 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
369 motionEntry.deviceId, motionEntry.source,
370 motionEntry.displayId, motionEntry.policyFlags,
371 motionEntry.action, motionEntry.actionButton,
372 motionEntry.flags, motionEntry.metaState,
373 motionEntry.buttonState, motionEntry.classification,
374 motionEntry.edgeFlags, motionEntry.xPrecision,
375 motionEntry.yPrecision, motionEntry.xCursorPosition,
376 motionEntry.yCursorPosition, motionEntry.downTime,
377 motionEntry.pointerCount, motionEntry.pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +0000378 pointerCoords.data());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000379
380 if (motionEntry.injectionState) {
381 combinedMotionEntry->injectionState = motionEntry.injectionState;
382 combinedMotionEntry->injectionState->refCount += 1;
383 }
384
385 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700386 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700387 firstPointerTransform, inputTarget.displayTransform,
388 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000389 return dispatchEntry;
390}
391
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000392status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
393 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700394 std::unique_ptr<InputChannel> uniqueServerChannel;
395 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
396
397 serverChannel = std::move(uniqueServerChannel);
398 return result;
399}
400
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500401template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000402bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500403 if (lhs == nullptr && rhs == nullptr) {
404 return true;
405 }
406 if (lhs == nullptr || rhs == nullptr) {
407 return false;
408 }
409 return *lhs == *rhs;
410}
411
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000412KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000413 KeyEvent event;
414 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
415 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
416 entry.repeatCount, entry.downTime, entry.eventTime);
417 return event;
418}
419
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000420bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000421 // Do not keep track of gesture monitors. They receive every event and would disproportionately
422 // affect the statistics.
423 if (connection.monitor) {
424 return false;
425 }
426 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
427 if (!connection.responsive) {
428 return false;
429 }
430 return true;
431}
432
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000433bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000434 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
435 const int32_t& inputEventId = eventEntry.id;
436 if (inputEventId != dispatchEntry.resolvedEventId) {
437 // Event was transmuted
438 return false;
439 }
440 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
441 return false;
442 }
443 // Only track latency for events that originated from hardware
444 if (eventEntry.isSynthesized()) {
445 return false;
446 }
447 const EventEntry::Type& inputEventEntryType = eventEntry.type;
448 if (inputEventEntryType == EventEntry::Type::KEY) {
449 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
450 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
451 return false;
452 }
453 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
454 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
455 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
456 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
457 return false;
458 }
459 } else {
460 // Not a key or a motion
461 return false;
462 }
463 if (!shouldReportMetricsForConnection(connection)) {
464 return false;
465 }
466 return true;
467}
468
Prabir Pradhancef936d2021-07-21 16:17:52 +0000469/**
470 * Connection is responsive if it has no events in the waitQueue that are older than the
471 * current time.
472 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000473bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000474 const nsecs_t currentTime = now();
475 for (const DispatchEntry* entry : connection.waitQueue) {
476 if (entry->timeoutTime < currentTime) {
477 return false;
478 }
479 }
480 return true;
481}
482
Antonio Kantekf16f2832021-09-28 04:39:20 +0000483// Returns true if the event type passed as argument represents a user activity.
484bool isUserActivityEvent(const EventEntry& eventEntry) {
485 switch (eventEntry.type) {
486 case EventEntry::Type::FOCUS:
487 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
488 case EventEntry::Type::DRAG:
489 case EventEntry::Type::TOUCH_MODE_CHANGED:
490 case EventEntry::Type::SENSOR:
491 case EventEntry::Type::CONFIGURATION_CHANGED:
492 return false;
493 case EventEntry::Type::DEVICE_RESET:
494 case EventEntry::Type::KEY:
495 case EventEntry::Type::MOTION:
496 return true;
497 }
498}
499
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800500// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhand65552b2021-10-07 11:23:50 -0700501bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, int32_t x, int32_t y,
502 bool isStylus) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800503 if (windowInfo.displayId != displayId || !windowInfo.visible) {
504 return false;
505 }
506 const auto flags = windowInfo.flags;
Prabir Pradhand65552b2021-10-07 11:23:50 -0700507 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
508 if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800509 return false;
510 }
511 const bool isModalWindow = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
512 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
513 if (!isModalWindow && !windowInfo.touchableRegionContainsPoint(x, y)) {
514 return false;
515 }
516 return true;
517}
518
Prabir Pradhand65552b2021-10-07 11:23:50 -0700519bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
520 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
521 (entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS ||
522 entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_ERASER);
523}
524
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000525} // namespace
526
Michael Wrightd02c5b62014-02-10 15:10:22 -0800527// --- InputDispatcher ---
528
Garfield Tan00f511d2019-06-12 16:55:40 -0700529InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
530 : mPolicy(policy),
531 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700532 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800533 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700534 mAppSwitchSawKeyDown(false),
535 mAppSwitchDueTime(LONG_LONG_MAX),
536 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800537 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700538 mDispatchEnabled(false),
539 mDispatchFrozen(false),
540 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800541 // mInTouchMode will be initialized by the WindowManager to the default device config.
542 // To avoid leaking stack in case that call never comes, and for tests,
543 // initialize it here anyways.
Antonio Kantekf16f2832021-09-28 04:39:20 +0000544 mInTouchMode(kDefaultInTouchMode),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100545 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000546 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800547 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000548 mLatencyAggregator(),
Siarhei Vishniakoubd252722022-01-06 03:49:35 -0800549 mLatencyTracker(&mLatencyAggregator) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800550 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800551 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800552
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700553 mWindowInfoListener = new DispatcherWindowListener(*this);
554 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
555
Yi Kong9b14ac62018-07-17 13:48:38 -0700556 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800557
558 policy->getDispatcherConfiguration(&mConfig);
559}
560
561InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000562 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800563
Prabir Pradhancef936d2021-07-21 16:17:52 +0000564 resetKeyRepeatLocked();
565 releasePendingEventLocked();
566 drainInboundQueueLocked();
567 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000569 while (!mConnectionsByToken.empty()) {
570 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000571 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
572 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800573 }
574}
575
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700576status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700577 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700578 return ALREADY_EXISTS;
579 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700580 mThread = std::make_unique<InputThread>(
581 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
582 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700583}
584
585status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700586 if (mThread && mThread->isCallingThread()) {
587 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700588 return INVALID_OPERATION;
589 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700590 mThread.reset();
591 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700592}
593
Michael Wrightd02c5b62014-02-10 15:10:22 -0800594void InputDispatcher::dispatchOnce() {
595 nsecs_t nextWakeupTime = LONG_LONG_MAX;
596 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800597 std::scoped_lock _l(mLock);
598 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800599
600 // Run a dispatch loop if there are no pending commands.
601 // The dispatch loop might enqueue commands to run afterwards.
602 if (!haveCommandsLocked()) {
603 dispatchOnceInnerLocked(&nextWakeupTime);
604 }
605
606 // Run all pending commands if there are any.
607 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000608 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800609 nextWakeupTime = LONG_LONG_MIN;
610 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800611
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700612 // If we are still waiting for ack on some events,
613 // we might have to wake up earlier to check if an app is anr'ing.
614 const nsecs_t nextAnrCheck = processAnrsLocked();
615 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
616
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800617 // We are about to enter an infinitely long sleep, because we have no commands or
618 // pending or queued events
619 if (nextWakeupTime == LONG_LONG_MAX) {
620 mDispatcherEnteredIdle.notify_all();
621 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800622 } // release lock
623
624 // Wait for callback or timeout or wake. (make sure we round up, not down)
625 nsecs_t currentTime = now();
626 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
627 mLooper->pollOnce(timeoutMillis);
628}
629
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700630/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500631 * Raise ANR if there is no focused window.
632 * Before the ANR is raised, do a final state check:
633 * 1. The currently focused application must be the same one we are waiting for.
634 * 2. Ensure we still don't have a focused window.
635 */
636void InputDispatcher::processNoFocusedWindowAnrLocked() {
637 // Check if the application that we are waiting for is still focused.
638 std::shared_ptr<InputApplicationHandle> focusedApplication =
639 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
640 if (focusedApplication == nullptr ||
641 focusedApplication->getApplicationToken() !=
642 mAwaitedFocusedApplication->getApplicationToken()) {
643 // Unexpected because we should have reset the ANR timer when focused application changed
644 ALOGE("Waited for a focused window, but focused application has already changed to %s",
645 focusedApplication->getName().c_str());
646 return; // The focused application has changed.
647 }
648
chaviw98318de2021-05-19 16:45:23 -0500649 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500650 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
651 if (focusedWindowHandle != nullptr) {
652 return; // We now have a focused window. No need for ANR.
653 }
654 onAnrLocked(mAwaitedFocusedApplication);
655}
656
657/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700658 * Check if any of the connections' wait queues have events that are too old.
659 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
660 * Return the time at which we should wake up next.
661 */
662nsecs_t InputDispatcher::processAnrsLocked() {
663 const nsecs_t currentTime = now();
664 nsecs_t nextAnrCheck = LONG_LONG_MAX;
665 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
666 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
667 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500668 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700669 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500670 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700671 return LONG_LONG_MIN;
672 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500673 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700674 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
675 }
676 }
677
678 // Check if any connection ANRs are due
679 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
680 if (currentTime < nextAnrCheck) { // most likely scenario
681 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
682 }
683
684 // If we reached here, we have an unresponsive connection.
685 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
686 if (connection == nullptr) {
687 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
688 return nextAnrCheck;
689 }
690 connection->responsive = false;
691 // Stop waking up for this unresponsive connection
692 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000693 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700694 return LONG_LONG_MIN;
695}
696
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800697std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
698 const sp<Connection>& connection) {
699 if (connection->monitor) {
700 return mMonitorDispatchingTimeout;
701 }
702 const sp<WindowInfoHandle> window =
703 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700704 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500705 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700706 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500707 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700708}
709
Michael Wrightd02c5b62014-02-10 15:10:22 -0800710void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
711 nsecs_t currentTime = now();
712
Jeff Browndc5992e2014-04-11 01:27:26 -0700713 // Reset the key repeat timer whenever normal dispatch is suspended while the
714 // device is in a non-interactive state. This is to ensure that we abort a key
715 // repeat if the device is just coming out of sleep.
716 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800717 resetKeyRepeatLocked();
718 }
719
720 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
721 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100722 if (DEBUG_FOCUS) {
723 ALOGD("Dispatch frozen. Waiting some more.");
724 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800725 return;
726 }
727
728 // Optimize latency of app switches.
729 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
730 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
731 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
732 if (mAppSwitchDueTime < *nextWakeupTime) {
733 *nextWakeupTime = mAppSwitchDueTime;
734 }
735
736 // Ready to start a new event.
737 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700739 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800740 if (isAppSwitchDue) {
741 // The inbound queue is empty so the app switch key we were waiting
742 // for will never arrive. Stop waiting for it.
743 resetPendingAppSwitchLocked(false);
744 isAppSwitchDue = false;
745 }
746
747 // Synthesize a key repeat if appropriate.
748 if (mKeyRepeatState.lastKeyEntry) {
749 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
750 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
751 } else {
752 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
753 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
754 }
755 }
756 }
757
758 // Nothing to do if there is no pending event.
759 if (!mPendingEvent) {
760 return;
761 }
762 } else {
763 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700764 mPendingEvent = mInboundQueue.front();
765 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800766 traceInboundQueueLengthLocked();
767 }
768
769 // Poke user activity for this event.
770 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700771 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800772 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800773 }
774
775 // Now we have an event to dispatch.
776 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700777 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800778 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700779 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700781 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800782 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700783 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800784 }
785
786 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700787 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 }
789
790 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700791 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700792 const ConfigurationChangedEntry& typedEntry =
793 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700794 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700795 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700796 break;
797 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700799 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700800 const DeviceResetEntry& typedEntry =
801 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700802 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700803 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700804 break;
805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100807 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700808 std::shared_ptr<FocusEntry> typedEntry =
809 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100810 dispatchFocusLocked(currentTime, typedEntry);
811 done = true;
812 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
813 break;
814 }
815
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700816 case EventEntry::Type::TOUCH_MODE_CHANGED: {
817 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
818 dispatchTouchModeChangeLocked(currentTime, typedEntry);
819 done = true;
820 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
821 break;
822 }
823
Prabir Pradhan99987712020-11-10 18:43:05 -0800824 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
825 const auto typedEntry =
826 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
827 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
828 done = true;
829 break;
830 }
831
arthurhungb89ccb02020-12-30 16:19:01 +0800832 case EventEntry::Type::DRAG: {
833 std::shared_ptr<DragEntry> typedEntry =
834 std::static_pointer_cast<DragEntry>(mPendingEvent);
835 dispatchDragLocked(currentTime, typedEntry);
836 done = true;
837 break;
838 }
839
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700840 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700841 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700842 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700843 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700844 resetPendingAppSwitchLocked(true);
845 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700846 } else if (dropReason == DropReason::NOT_DROPPED) {
847 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700848 }
849 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700850 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700851 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700852 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700853 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
854 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700855 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700856 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700857 break;
858 }
859
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700860 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700861 std::shared_ptr<MotionEntry> motionEntry =
862 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700863 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
864 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800865 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700866 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700867 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700868 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700869 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
870 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700871 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700872 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700873 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 }
Chris Yef59a2f42020-10-16 12:55:26 -0700875
876 case EventEntry::Type::SENSOR: {
877 std::shared_ptr<SensorEntry> sensorEntry =
878 std::static_pointer_cast<SensorEntry>(mPendingEvent);
879 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
880 dropReason = DropReason::APP_SWITCH;
881 }
882 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
883 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
884 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
885 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
886 dropReason = DropReason::STALE;
887 }
888 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
889 done = true;
890 break;
891 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 }
893
894 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700895 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700896 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800897 }
Michael Wright3a981722015-06-10 15:26:13 +0100898 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800899
900 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800902 }
903}
904
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700905/**
906 * Return true if the events preceding this incoming motion event should be dropped
907 * Return false otherwise (the default behaviour)
908 */
909bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700910 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700911 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700912
913 // Optimize case where the current application is unresponsive and the user
914 // decides to touch a window in a different application.
915 // If the application takes too long to catch up then we drop all events preceding
916 // the touch into the other window.
917 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700918 int32_t displayId = motionEntry.displayId;
919 int32_t x = static_cast<int32_t>(
920 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
921 int32_t y = static_cast<int32_t>(
922 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Prabir Pradhand65552b2021-10-07 11:23:50 -0700923
924 const bool isStylus = isPointerFromStylus(motionEntry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -0500925 sp<WindowInfoHandle> touchedWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -0700926 findTouchedWindowAtLocked(displayId, x, y, nullptr, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700927 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700928 touchedWindowHandle->getApplicationToken() !=
929 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700930 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700931 ALOGI("Pruning input queue because user touched a different application while waiting "
932 "for %s",
933 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700934 return true;
935 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700936
Prabir Pradhandfabf8a2022-01-21 08:19:30 -0800937 // Alternatively, maybe there's a spy window that could handle this event.
938 const std::vector<sp<WindowInfoHandle>> touchedSpies =
939 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
940 for (const auto& windowHandle : touchedSpies) {
941 const sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000942 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -0800943 // This spy window could take more input. Drop all events preceding this
944 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700945 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -0800946 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700947 mAwaitedFocusedApplication->getName().c_str());
948 return true;
949 }
950 }
951 }
952
953 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
954 // yet been processed by some connections, the dispatcher will wait for these motion
955 // events to be processed before dispatching the key event. This is because these motion events
956 // may cause a new window to be launched, which the user might expect to receive focus.
957 // To prevent waiting forever for such events, just send the key to the currently focused window
958 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
959 ALOGD("Received a new pointer down event, stop waiting for events to process and "
960 "just send the pending key event to the focused window.");
961 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700962 }
963 return false;
964}
965
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700966bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700967 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700968 mInboundQueue.push_back(std::move(newEntry));
969 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800970 traceInboundQueueLengthLocked();
971
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700972 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700973 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700974 // Optimize app switch latency.
975 // If the application takes too long to catch up then we drop all events preceding
976 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700977 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700978 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700979 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700980 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700981 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700982 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000983 if (DEBUG_APP_SWITCH) {
984 ALOGD("App switch is pending!");
985 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700986 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700987 mAppSwitchSawKeyDown = false;
988 needWake = true;
989 }
990 }
991 }
992 break;
993 }
994
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700995 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700996 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
997 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700998 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001000 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001001 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001002 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001003 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1004 break;
1005 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001006 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001007 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001008 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001009 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001010 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1011 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001012 // nothing to do
1013 break;
1014 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001015 }
1016
1017 return needWake;
1018}
1019
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001020void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001021 // Do not store sensor event in recent queue to avoid flooding the queue.
1022 if (entry->type != EventEntry::Type::SENSOR) {
1023 mRecentQueue.push_back(entry);
1024 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001025 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001026 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027 }
1028}
1029
chaviw98318de2021-05-19 16:45:23 -05001030sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1031 int32_t y, TouchState* touchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07001032 bool isStylus,
chaviw98318de2021-05-19 16:45:23 -05001033 bool addOutsideTargets,
1034 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001035 if (addOutsideTargets && touchState == nullptr) {
1036 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001037 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001038 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001039 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001040 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001041 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001042 continue;
1043 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001044
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001045 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhand65552b2021-10-07 11:23:50 -07001046 if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001047 return windowHandle;
1048 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001049
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001050 if (addOutsideTargets && info.flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
1051 touchState->addOrUpdateWindow(windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1052 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053 }
1054 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001055 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001056}
1057
Prabir Pradhand65552b2021-10-07 11:23:50 -07001058std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
1059 int32_t displayId, int32_t x, int32_t y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001060 // Traverse windows from front to back and gather the touched spy windows.
1061 std::vector<sp<WindowInfoHandle>> spyWindows;
1062 const auto& windowHandles = getWindowHandlesLocked(displayId);
1063 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1064 const WindowInfo& info = *windowHandle->getInfo();
1065
Prabir Pradhand65552b2021-10-07 11:23:50 -07001066 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001067 continue;
1068 }
1069 if (!info.isSpy()) {
1070 // The first touched non-spy window was found, so return the spy windows touched so far.
1071 return spyWindows;
1072 }
1073 spyWindows.push_back(windowHandle);
1074 }
1075 return spyWindows;
1076}
1077
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001078void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001079 const char* reason;
1080 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001081 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001082 if (DEBUG_INBOUND_EVENT_DETAILS) {
1083 ALOGD("Dropped event because policy consumed it.");
1084 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001085 reason = "inbound event was dropped because the policy consumed it";
1086 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001087 case DropReason::DISABLED:
1088 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001089 ALOGI("Dropped event because input dispatch is disabled.");
1090 }
1091 reason = "inbound event was dropped because input dispatch is disabled";
1092 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001093 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001094 ALOGI("Dropped event because of pending overdue app switch.");
1095 reason = "inbound event was dropped because of pending overdue app switch";
1096 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001097 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001098 ALOGI("Dropped event because the current application is not responding and the user "
1099 "has started interacting with a different application.");
1100 reason = "inbound event was dropped because the current application is not responding "
1101 "and the user has started interacting with a different application";
1102 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001103 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001104 ALOGI("Dropped event because it is stale.");
1105 reason = "inbound event was dropped because it is stale";
1106 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001107 case DropReason::NO_POINTER_CAPTURE:
1108 ALOGI("Dropped event because there is no window with Pointer Capture.");
1109 reason = "inbound event was dropped because there is no window with Pointer Capture";
1110 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001111 case DropReason::NOT_DROPPED: {
1112 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001113 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001114 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001115 }
1116
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001117 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001118 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1120 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001121 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001123 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001124 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1125 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001126 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1127 synthesizeCancelationEventsForAllConnectionsLocked(options);
1128 } else {
1129 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1130 synthesizeCancelationEventsForAllConnectionsLocked(options);
1131 }
1132 break;
1133 }
Chris Yef59a2f42020-10-16 12:55:26 -07001134 case EventEntry::Type::SENSOR: {
1135 break;
1136 }
arthurhungb89ccb02020-12-30 16:19:01 +08001137 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1138 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001139 break;
1140 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001141 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001142 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001143 case EventEntry::Type::CONFIGURATION_CHANGED:
1144 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001145 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001146 break;
1147 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148 }
1149}
1150
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001151static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001152 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1153 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154}
1155
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001156bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1157 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1158 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1159 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001160}
1161
1162bool InputDispatcher::isAppSwitchPendingLocked() {
1163 return mAppSwitchDueTime != LONG_LONG_MAX;
1164}
1165
1166void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1167 mAppSwitchDueTime = LONG_LONG_MAX;
1168
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001169 if (DEBUG_APP_SWITCH) {
1170 if (handled) {
1171 ALOGD("App switch has arrived.");
1172 } else {
1173 ALOGD("App switch was abandoned.");
1174 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001175 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001176}
1177
Michael Wrightd02c5b62014-02-10 15:10:22 -08001178bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001179 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180}
1181
Prabir Pradhancef936d2021-07-21 16:17:52 +00001182bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001183 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001184 return false;
1185 }
1186
1187 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001188 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001189 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001190 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1191 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001192 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001193 return true;
1194}
1195
Prabir Pradhancef936d2021-07-21 16:17:52 +00001196void InputDispatcher::postCommandLocked(Command&& command) {
1197 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198}
1199
1200void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001201 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001202 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001203 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204 releaseInboundEventLocked(entry);
1205 }
1206 traceInboundQueueLengthLocked();
1207}
1208
1209void InputDispatcher::releasePendingEventLocked() {
1210 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001211 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001212 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001213 }
1214}
1215
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001216void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001217 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001218 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001219 if (DEBUG_DISPATCH_CYCLE) {
1220 ALOGD("Injected inbound event was dropped.");
1221 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001222 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001223 }
1224 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001225 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001226 }
1227 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228}
1229
1230void InputDispatcher::resetKeyRepeatLocked() {
1231 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001232 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001233 }
1234}
1235
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001236std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1237 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001238
Michael Wright2e732952014-09-24 13:26:59 -07001239 uint32_t policyFlags = entry->policyFlags &
1240 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001242 std::shared_ptr<KeyEntry> newEntry =
1243 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1244 entry->source, entry->displayId, policyFlags, entry->action,
1245 entry->flags, entry->keyCode, entry->scanCode,
1246 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001248 newEntry->syntheticRepeat = true;
1249 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001251 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252}
1253
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001254bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001255 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001256 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1257 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1258 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259
1260 // Reset key repeating in case a keyboard device was added or removed or something.
1261 resetKeyRepeatLocked();
1262
1263 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001264 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1265 scoped_unlock unlock(mLock);
1266 mPolicy->notifyConfigurationChanged(eventTime);
1267 };
1268 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001269 return true;
1270}
1271
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001272bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1273 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001274 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1275 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1276 entry.deviceId);
1277 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278
liushenxiang42232912021-05-21 20:24:09 +08001279 // Reset key repeating in case a keyboard device was disabled or enabled.
1280 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1281 resetKeyRepeatLocked();
1282 }
1283
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001284 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001285 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001286 synthesizeCancelationEventsForAllConnectionsLocked(options);
1287 return true;
1288}
1289
Vishnu Nairad321cd2020-08-20 16:40:21 -07001290void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001291 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001292 if (mPendingEvent != nullptr) {
1293 // Move the pending event to the front of the queue. This will give the chance
1294 // for the pending event to get dispatched to the newly focused window
1295 mInboundQueue.push_front(mPendingEvent);
1296 mPendingEvent = nullptr;
1297 }
1298
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001299 std::unique_ptr<FocusEntry> focusEntry =
1300 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1301 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001302
1303 // This event should go to the front of the queue, but behind all other focus events
1304 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001305 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001306 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001307 [](const std::shared_ptr<EventEntry>& event) {
1308 return event->type == EventEntry::Type::FOCUS;
1309 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001310
1311 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001312 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001313}
1314
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001315void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001316 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001317 if (channel == nullptr) {
1318 return; // Window has gone away
1319 }
1320 InputTarget target;
1321 target.inputChannel = channel;
1322 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1323 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001324 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1325 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001326 std::string reason = std::string("reason=").append(entry->reason);
1327 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001328 dispatchEventLocked(currentTime, entry, {target});
1329}
1330
Prabir Pradhan99987712020-11-10 18:43:05 -08001331void InputDispatcher::dispatchPointerCaptureChangedLocked(
1332 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1333 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001334 dropReason = DropReason::NOT_DROPPED;
1335
Prabir Pradhan99987712020-11-10 18:43:05 -08001336 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001337 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001338
1339 if (entry->pointerCaptureRequest.enable) {
1340 // Enable Pointer Capture.
1341 if (haveWindowWithPointerCapture &&
1342 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1343 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1344 "to the window.");
1345 }
1346 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001347 // This can happen if a window requests capture and immediately releases capture.
1348 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001349 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001350 return;
1351 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001352 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1353 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1354 return;
1355 }
1356
Vishnu Nairc519ff72021-01-21 08:23:08 -08001357 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001358 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1359 mWindowTokenWithPointerCapture = token;
1360 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001361 // Disable Pointer Capture.
1362 // We do not check if the sequence number matches for requests to disable Pointer Capture
1363 // for two reasons:
1364 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1365 // to disable capture with the same sequence number: one generated by
1366 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1367 // Capture being disabled in InputReader.
1368 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1369 // actual Pointer Capture state that affects events being generated by input devices is
1370 // in InputReader.
1371 if (!haveWindowWithPointerCapture) {
1372 // Pointer capture was already forcefully disabled because of focus change.
1373 dropReason = DropReason::NOT_DROPPED;
1374 return;
1375 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001376 token = mWindowTokenWithPointerCapture;
1377 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001378 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001379 setPointerCaptureLocked(false);
1380 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001381 }
1382
1383 auto channel = getInputChannelLocked(token);
1384 if (channel == nullptr) {
1385 // Window has gone away, clean up Pointer Capture state.
1386 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001387 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001388 setPointerCaptureLocked(false);
1389 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001390 return;
1391 }
1392 InputTarget target;
1393 target.inputChannel = channel;
1394 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1395 entry->dispatchInProgress = true;
1396 dispatchEventLocked(currentTime, entry, {target});
1397
1398 dropReason = DropReason::NOT_DROPPED;
1399}
1400
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001401void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1402 const std::shared_ptr<TouchModeEntry>& entry) {
1403 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1404 getWindowHandlesLocked(mFocusedDisplayId);
1405 if (windowHandles.empty()) {
1406 return;
1407 }
1408 const std::vector<InputTarget> inputTargets =
1409 getInputTargetsFromWindowHandlesLocked(windowHandles);
1410 if (inputTargets.empty()) {
1411 return;
1412 }
1413 entry->dispatchInProgress = true;
1414 dispatchEventLocked(currentTime, entry, inputTargets);
1415}
1416
1417std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1418 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1419 std::vector<InputTarget> inputTargets;
1420 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1421 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1422 const sp<IBinder>& token = handle->getToken();
1423 if (token == nullptr) {
1424 continue;
1425 }
1426 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1427 if (channel == nullptr) {
1428 continue; // Window has gone away
1429 }
1430 InputTarget target;
1431 target.inputChannel = channel;
1432 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1433 inputTargets.push_back(target);
1434 }
1435 return inputTargets;
1436}
1437
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001438bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001439 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001440 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001441 if (!entry->dispatchInProgress) {
1442 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1443 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1444 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1445 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001446 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001447 // We have seen two identical key downs in a row which indicates that the device
1448 // driver is automatically generating key repeats itself. We take note of the
1449 // repeat here, but we disable our own next key repeat timer since it is clear that
1450 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001451 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1452 // Make sure we don't get key down from a different device. If a different
1453 // device Id has same key pressed down, the new device Id will replace the
1454 // current one to hold the key repeat with repeat count reset.
1455 // In the future when got a KEY_UP on the device id, drop it and do not
1456 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001457 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1458 resetKeyRepeatLocked();
1459 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1460 } else {
1461 // Not a repeat. Save key down state in case we do see a repeat later.
1462 resetKeyRepeatLocked();
1463 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1464 }
1465 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001466 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1467 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001468 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001469 if (DEBUG_INBOUND_EVENT_DETAILS) {
1470 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1471 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001472 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001473 resetKeyRepeatLocked();
1474 }
1475
1476 if (entry->repeatCount == 1) {
1477 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1478 } else {
1479 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1480 }
1481
1482 entry->dispatchInProgress = true;
1483
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001484 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001485 }
1486
1487 // Handle case where the policy asked us to try again later last time.
1488 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1489 if (currentTime < entry->interceptKeyWakeupTime) {
1490 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1491 *nextWakeupTime = entry->interceptKeyWakeupTime;
1492 }
1493 return false; // wait until next wakeup
1494 }
1495 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1496 entry->interceptKeyWakeupTime = 0;
1497 }
1498
1499 // Give the policy a chance to intercept the key.
1500 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1501 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001502 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001503 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001504
1505 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1506 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1507 };
1508 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001509 return false; // wait for the command to run
1510 } else {
1511 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1512 }
1513 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001514 if (*dropReason == DropReason::NOT_DROPPED) {
1515 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001516 }
1517 }
1518
1519 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001520 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001521 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001522 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1523 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001524 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525 return true;
1526 }
1527
1528 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001529 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001530 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001531 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001532 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001533 return false;
1534 }
1535
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001536 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001537 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001538 return true;
1539 }
1540
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001541 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001542 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001543
1544 // Dispatch the key.
1545 dispatchEventLocked(currentTime, entry, inputTargets);
1546 return true;
1547}
1548
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001549void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001550 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1551 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1552 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1553 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1554 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1555 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1556 entry.metaState, entry.repeatCount, entry.downTime);
1557 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001558}
1559
Prabir Pradhancef936d2021-07-21 16:17:52 +00001560void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1561 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001562 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001563 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1564 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1565 "source=0x%x, sensorType=%s",
1566 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001567 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001568 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001569 auto command = [this, entry]() REQUIRES(mLock) {
1570 scoped_unlock unlock(mLock);
1571
1572 if (entry->accuracyChanged) {
1573 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1574 }
1575 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1576 entry->hwTimestamp, entry->values);
1577 };
1578 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001579}
1580
1581bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001582 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1583 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001584 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001585 }
Chris Yef59a2f42020-10-16 12:55:26 -07001586 { // acquire lock
1587 std::scoped_lock _l(mLock);
1588
1589 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1590 std::shared_ptr<EventEntry> entry = *it;
1591 if (entry->type == EventEntry::Type::SENSOR) {
1592 it = mInboundQueue.erase(it);
1593 releaseInboundEventLocked(entry);
1594 }
1595 }
1596 }
1597 return true;
1598}
1599
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001600bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001601 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001602 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001603 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001604 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605 entry->dispatchInProgress = true;
1606
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001607 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001608 }
1609
1610 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001611 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001612 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001613 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1614 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001615 return true;
1616 }
1617
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001618 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001619
1620 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001621 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001622
1623 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001624 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001625 if (isPointerEvent) {
1626 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001627 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001628 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001629 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001630 } else {
1631 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001632 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001633 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001634 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001635 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001636 return false;
1637 }
1638
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001639 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001640 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001641 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1642 return true;
1643 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001644 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001645 CancelationOptions::Mode mode(isPointerEvent
1646 ? CancelationOptions::CANCEL_POINTER_EVENTS
1647 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1648 CancelationOptions options(mode, "input event injection failed");
1649 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650 return true;
1651 }
1652
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001653 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001654 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001655
1656 // Dispatch the motion.
1657 if (conflictingPointerActions) {
1658 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001659 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001660 synthesizeCancelationEventsForAllConnectionsLocked(options);
1661 }
1662 dispatchEventLocked(currentTime, entry, inputTargets);
1663 return true;
1664}
1665
chaviw98318de2021-05-19 16:45:23 -05001666void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001667 bool isExiting, const MotionEntry& motionEntry) {
1668 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1669 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1670 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1671 PointerCoords pointerCoords;
1672 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1673 pointerCoords.transform(windowHandle->getInfo()->transform);
1674
1675 std::unique_ptr<DragEntry> dragEntry =
1676 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1677 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1678 pointerCoords.getY());
1679
1680 enqueueInboundEventLocked(std::move(dragEntry));
1681}
1682
1683void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1684 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1685 if (channel == nullptr) {
1686 return; // Window has gone away
1687 }
1688 InputTarget target;
1689 target.inputChannel = channel;
1690 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1691 entry->dispatchInProgress = true;
1692 dispatchEventLocked(currentTime, entry, {target});
1693}
1694
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001695void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001696 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1697 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1698 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001699 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001700 "metaState=0x%x, buttonState=0x%x,"
1701 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1702 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001703 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1704 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1705 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001706
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001707 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1708 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1709 "x=%f, y=%f, pressure=%f, size=%f, "
1710 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1711 "orientation=%f",
1712 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1713 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1714 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1715 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1716 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1717 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1718 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1719 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1720 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1721 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1722 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001723 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001724}
1725
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001726void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1727 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001728 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001729 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001730 if (DEBUG_DISPATCH_CYCLE) {
1731 ALOGD("dispatchEventToCurrentInputTargets");
1732 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001733
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001734 updateInteractionTokensLocked(*eventEntry, inputTargets);
1735
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1737
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001738 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001740 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001741 sp<Connection> connection =
1742 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001743 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001744 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001745 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001746 if (DEBUG_FOCUS) {
1747 ALOGD("Dropping event delivery to target with channel '%s' because it "
1748 "is no longer registered with the input dispatcher.",
1749 inputTarget.inputChannel->getName().c_str());
1750 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001751 }
1752 }
1753}
1754
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001755void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1756 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1757 // If the policy decides to close the app, we will get a channel removal event via
1758 // unregisterInputChannel, and will clean up the connection that way. We are already not
1759 // sending new pointers to the connection when it blocked, but focused events will continue to
1760 // pile up.
1761 ALOGW("Canceling events for %s because it is unresponsive",
1762 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08001763 if (connection->status == Connection::Status::NORMAL) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001764 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1765 "application not responding");
1766 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001767 }
1768}
1769
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001770void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001771 if (DEBUG_FOCUS) {
1772 ALOGD("Resetting ANR timeouts.");
1773 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001774
1775 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001776 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001777 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001778}
1779
Tiger Huang721e26f2018-07-24 22:26:19 +08001780/**
1781 * Get the display id that the given event should go to. If this event specifies a valid display id,
1782 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1783 * Focused display is the display that the user most recently interacted with.
1784 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001785int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001786 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001787 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001788 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001789 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1790 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001791 break;
1792 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001793 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001794 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1795 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001796 break;
1797 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001798 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001799 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001800 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001801 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001802 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001803 case EventEntry::Type::SENSOR:
1804 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001805 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001806 return ADISPLAY_ID_NONE;
1807 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001808 }
1809 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1810}
1811
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001812bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1813 const char* focusedWindowName) {
1814 if (mAnrTracker.empty()) {
1815 // already processed all events that we waited for
1816 mKeyIsWaitingForEventsTimeout = std::nullopt;
1817 return false;
1818 }
1819
1820 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1821 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001822 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001823 mKeyIsWaitingForEventsTimeout = currentTime +
1824 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1825 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001826 return true;
1827 }
1828
1829 // We still have pending events, and already started the timer
1830 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1831 return true; // Still waiting
1832 }
1833
1834 // Waited too long, and some connection still hasn't processed all motions
1835 // Just send the key to the focused window
1836 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1837 focusedWindowName);
1838 mKeyIsWaitingForEventsTimeout = std::nullopt;
1839 return false;
1840}
1841
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001842InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1843 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1844 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001845 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001846
Tiger Huang721e26f2018-07-24 22:26:19 +08001847 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001848 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001849 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001850 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1851
Michael Wrightd02c5b62014-02-10 15:10:22 -08001852 // If there is no currently focused window and no focused application
1853 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001854 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1855 ALOGI("Dropping %s event because there is no focused window or focused application in "
1856 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001857 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001858 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001859 }
1860
Vishnu Nair062a8672021-09-03 16:07:44 -07001861 // Drop key events if requested by input feature
1862 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1863 return InputEventInjectionResult::FAILED;
1864 }
1865
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001866 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1867 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1868 // start interacting with another application via touch (app switch). This code can be removed
1869 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1870 // an app is expected to have a focused window.
1871 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1872 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1873 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001874 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1875 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1876 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001877 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001878 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001879 ALOGW("Waiting because no window has focus but %s may eventually add a "
1880 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001881 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001882 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001883 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001884 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1885 // Already raised ANR. Drop the event
1886 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001887 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001888 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001889 } else {
1890 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001891 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001892 }
1893 }
1894
1895 // we have a valid, non-null focused window
1896 resetNoFocusedWindowTimeoutLocked();
1897
Michael Wrightd02c5b62014-02-10 15:10:22 -08001898 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001899 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001900 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001901 }
1902
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001903 if (focusedWindowHandle->getInfo()->paused) {
1904 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001905 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001906 }
1907
1908 // If the event is a key event, then we must wait for all previous events to
1909 // complete before delivering it because previous events may have the
1910 // side-effect of transferring focus to a different window and we want to
1911 // ensure that the following keys are sent to the new window.
1912 //
1913 // Suppose the user touches a button in a window then immediately presses "A".
1914 // If the button causes a pop-up window to appear then we want to ensure that
1915 // the "A" key is delivered to the new pop-up window. This is because users
1916 // often anticipate pending UI changes when typing on a keyboard.
1917 // To obtain this behavior, we must serialize key events with respect to all
1918 // prior input events.
1919 if (entry.type == EventEntry::Type::KEY) {
1920 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1921 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001922 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001923 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 }
1925
1926 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001927 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001928 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1929 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001930
1931 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001932 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001933}
1934
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001935/**
1936 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1937 * that are currently unresponsive.
1938 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001939std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
1940 const std::vector<Monitor>& monitors) const {
1941 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001942 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001943 [this](const Monitor& monitor) REQUIRES(mLock) {
1944 sp<Connection> connection =
1945 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001946 if (connection == nullptr) {
1947 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001948 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001949 return false;
1950 }
1951 if (!connection->responsive) {
1952 ALOGW("Unresponsive monitor %s will not get the new gesture",
1953 connection->inputChannel->getName().c_str());
1954 return false;
1955 }
1956 return true;
1957 });
1958 return responsiveMonitors;
1959}
1960
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001961InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1962 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1963 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001964 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001965 enum InjectionPermission {
1966 INJECTION_PERMISSION_UNKNOWN,
1967 INJECTION_PERMISSION_GRANTED,
1968 INJECTION_PERMISSION_DENIED
1969 };
1970
Michael Wrightd02c5b62014-02-10 15:10:22 -08001971 // For security reasons, we defer updating the touch state until we are sure that
1972 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001973 const int32_t displayId = entry.displayId;
1974 const int32_t action = entry.action;
1975 const int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001976
1977 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001978 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001980 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1981 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001983 // Copy current touch state into tempTouchState.
1984 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1985 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001986 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001987 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001988 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
1989 oldState = &(it->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001990 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001991 }
1992
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001993 bool isSplit = tempTouchState.split;
1994 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1995 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1996 tempTouchState.displayId != displayId);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001997
1998 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1999 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2000 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2001 const bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2002 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002003 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002004 bool wrongDevice = false;
2005 if (newGesture) {
2006 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002007 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002008 ALOGI("Dropping event because a pointer for a different device is already down "
2009 "in display %" PRId32,
2010 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002011 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002012 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002013 switchedDevice = false;
2014 wrongDevice = true;
2015 goto Failed;
2016 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002017 tempTouchState.reset();
2018 tempTouchState.down = down;
2019 tempTouchState.deviceId = entry.deviceId;
2020 tempTouchState.source = entry.source;
2021 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002022 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002023 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002024 ALOGI("Dropping move event because a pointer for a different device is already active "
2025 "in display %" PRId32,
2026 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002027 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002028 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002029 switchedDevice = false;
2030 wrongDevice = true;
2031 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002032 }
2033
2034 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2035 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2036
Garfield Tan00f511d2019-06-12 16:55:40 -07002037 int32_t x;
2038 int32_t y;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002039 const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002040 // Always dispatch mouse events to cursor position.
2041 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002042 x = int32_t(entry.xCursorPosition);
2043 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002044 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002045 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2046 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002047 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002048 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Prabir Pradhand65552b2021-10-07 11:23:50 -07002049 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002050 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07002051 isStylus, isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002052
Michael Wrightd02c5b62014-02-10 15:10:22 -08002053 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002054 if (newTouchedWindowHandle == nullptr) {
Arthur Hungb3307ee2021-10-14 10:57:37 +00002055 ALOGD("No new touched window at (%" PRId32 ", %" PRId32 ") in display %" PRId32, x, y,
2056 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002057 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002058 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002059 }
2060
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002061 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002062 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002063 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2064 // New window supports splitting, but we should never split mouse events.
2065 isSplit = !isFromMouse;
2066 } else if (isSplit) {
2067 // New window does not support splitting but we have already split events.
2068 // Ignore the new window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002069 newTouchedWindowHandle = nullptr;
2070 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002071 } else {
2072 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002073 // be delivered to a new window which supports split touch. Pointers from a mouse device
2074 // should never be split.
2075 tempTouchState.split = isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002076 }
2077
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002078 // Update hover state.
Michael Wright3dd60e22019-03-27 22:06:44 +00002079 if (newTouchedWindowHandle != nullptr) {
Garfield Tandf26e862020-07-01 20:18:19 -07002080 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2081 newHoverWindowHandle = nullptr;
2082 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002083 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002084 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002085 }
2086
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002087 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002088 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002089 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002090 // Process the foreground window first so that it is the first to receive the event.
2091 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002092 }
2093
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002094 if (newTouchedWindows.empty()) {
2095 ALOGI("Dropping event because there is no touchable window at (%d, %d) on display %d.",
2096 x, y, displayId);
2097 injectionResult = InputEventInjectionResult::FAILED;
2098 goto Failed;
2099 }
2100
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002101 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
2102 const WindowInfo& info = *windowHandle->getInfo();
2103
2104 if (info.paused) {
2105 ALOGI("Not sending touch event to %s because it is paused",
2106 windowHandle->getName().c_str());
2107 continue;
2108 }
2109
2110 // Ensure the window has a connection and the connection is responsive
2111 const bool isResponsive = hasResponsiveConnectionLocked(*windowHandle);
2112 if (!isResponsive) {
2113 ALOGW("Not sending touch gesture to %s because it is not responsive",
2114 windowHandle->getName().c_str());
2115 continue;
2116 }
2117
2118 // Drop events that can't be trusted due to occlusion
2119 if (mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2120 TouchOcclusionInfo occlusionInfo =
2121 computeTouchOcclusionInfoLocked(windowHandle, x, y);
2122 if (!isTouchTrustedLocked(occlusionInfo)) {
2123 if (DEBUG_TOUCH_OCCLUSION) {
2124 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2125 for (const auto& log : occlusionInfo.debugInfo) {
2126 ALOGD("%s", log.c_str());
2127 }
2128 }
2129 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
2130 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2131 ALOGW("Dropping untrusted touch event due to %s/%d",
2132 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2133 continue;
2134 }
2135 }
2136 }
2137
2138 // Drop touch events if requested by input feature
2139 if (shouldDropInput(entry, windowHandle)) {
2140 continue;
2141 }
2142
2143 // Set target flags.
2144 int32_t targetFlags = InputTarget::FLAG_DISPATCH_AS_IS;
2145
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002146 if (!info.isSpy()) {
2147 // There should only be one new foreground (non-spy) window at this location.
2148 targetFlags |= InputTarget::FLAG_FOREGROUND;
2149 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002150
2151 if (isSplit) {
2152 targetFlags |= InputTarget::FLAG_SPLIT;
2153 }
2154 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
2155 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2156 } else if (isWindowObscuredLocked(windowHandle)) {
2157 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2158 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002159
2160 // Update the temporary touch state.
2161 BitSet32 pointerIds;
2162 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002163 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002164 pointerIds.markBit(pointerId);
2165 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002166
2167 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002169 } else {
2170 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2171
2172 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002173 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002174 if (DEBUG_FOCUS) {
2175 ALOGD("Dropping event because the pointer is not down or we previously "
2176 "dropped the pointer down event in display %" PRId32,
2177 displayId);
2178 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002179 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180 goto Failed;
2181 }
2182
arthurhung6d4bed92021-03-17 11:59:33 +08002183 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002184
Michael Wrightd02c5b62014-02-10 15:10:22 -08002185 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002186 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002187 tempTouchState.isSlippery()) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002188 const int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2189 const int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002190
Prabir Pradhand65552b2021-10-07 11:23:50 -07002191 const bool isStylus = isPointerFromStylus(entry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -05002192 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002193 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhand65552b2021-10-07 11:23:50 -07002194 newTouchedWindowHandle =
2195 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002196
2197 // Drop touch events if requested by input feature
2198 if (newTouchedWindowHandle != nullptr &&
2199 shouldDropInput(entry, newTouchedWindowHandle)) {
2200 newTouchedWindowHandle = nullptr;
2201 }
2202
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002203 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2204 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002205 if (DEBUG_FOCUS) {
2206 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2207 oldTouchedWindowHandle->getName().c_str(),
2208 newTouchedWindowHandle->getName().c_str(), displayId);
2209 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002210 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002211 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2212 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2213 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002214
2215 // Make a slippery entrance into the new window.
2216 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002217 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218 }
2219
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002220 int32_t targetFlags =
2221 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002222 if (isSplit) {
2223 targetFlags |= InputTarget::FLAG_SPLIT;
2224 }
2225 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2226 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002227 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2228 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002229 }
2230
2231 BitSet32 pointerIds;
2232 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002233 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002234 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002235 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002236 }
2237 }
2238 }
2239
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002240 // Update dispatching for hover enter and exit.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002241 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002242 // Let the previous window know that the hover sequence is over, unless we already did
2243 // it when dispatching it as is to newTouchedWindowHandle.
Garfield Tandf26e862020-07-01 20:18:19 -07002244 if (mLastHoverWindowHandle != nullptr &&
2245 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2246 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002247 if (DEBUG_HOVER) {
2248 ALOGD("Sending hover exit event to window %s.",
2249 mLastHoverWindowHandle->getName().c_str());
2250 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002251 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2252 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002253 }
2254
Garfield Tandf26e862020-07-01 20:18:19 -07002255 // Let the new window know that the hover sequence is starting, unless we already did it
2256 // when dispatching it as is to newTouchedWindowHandle.
2257 if (newHoverWindowHandle != nullptr &&
2258 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2259 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002260 if (DEBUG_HOVER) {
2261 ALOGD("Sending hover enter event to window %s.",
2262 newHoverWindowHandle->getName().c_str());
2263 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002264 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2265 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2266 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002267 }
2268 }
2269
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002270 // Ensure that we have at least one foreground or spy window. It's possible that we dropped some
2271 // of the touched windows we previously found if they became paused or unresponsive or were
2272 // removed.
2273 if (std::none_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2274 [](const TouchedWindow& touchedWindow) {
2275 return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 ||
2276 touchedWindow.windowHandle->getInfo()->isSpy();
2277 })) {
2278 ALOGI("Dropping event because there is no touched window on display %d to receive it.",
2279 displayId);
2280 injectionResult = InputEventInjectionResult::FAILED;
2281 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002282 }
2283
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002284 // Check permission to inject into all touched foreground windows.
2285 if (std::any_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2286 [this, &entry](const TouchedWindow& touchedWindow) {
2287 return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 &&
2288 !checkInjectionPermission(touchedWindow.windowHandle,
2289 entry.injectionState);
2290 })) {
2291 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
2292 injectionPermission = INJECTION_PERMISSION_DENIED;
2293 goto Failed;
2294 }
2295 // Permission granted to inject into all touched foreground windows.
2296 injectionPermission = INJECTION_PERMISSION_GRANTED;
2297
Michael Wrightd02c5b62014-02-10 15:10:22 -08002298 // Check whether windows listening for outside touches are owned by the same UID. If it is
2299 // set the policy flag that we will not reveal coordinate information to this window.
2300 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002301 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002302 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002303 if (foregroundWindowHandle) {
2304 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002305 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002306 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002307 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2308 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2309 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002310 InputTarget::FLAG_ZERO_COORDS,
2311 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002312 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002313 }
2314 }
2315 }
2316 }
2317
Michael Wrightd02c5b62014-02-10 15:10:22 -08002318 // If this is the first pointer going down and the touched window has a wallpaper
2319 // then also add the touched wallpaper windows so they are locked in for the duration
2320 // of the touch gesture.
2321 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2322 // engine only supports touch events. We would need to add a mechanism similar
2323 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2324 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002325 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002326 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002327 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002328 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002329 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002330 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2331 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002332 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002333 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002334 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002335 .addOrUpdateWindow(windowHandle,
2336 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2337 InputTarget::
2338 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2339 InputTarget::FLAG_DISPATCH_AS_IS,
2340 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002341 }
2342 }
2343 }
2344 }
2345
2346 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002347 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002348
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002349 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002350 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002351 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352 }
2353
2354 // Drop the outside or hover touch windows since we will not care about them
2355 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002356 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002357
2358Failed:
2359 // Check injection permission once and for all.
2360 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002361 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002362 injectionPermission = INJECTION_PERMISSION_GRANTED;
2363 } else {
2364 injectionPermission = INJECTION_PERMISSION_DENIED;
2365 }
2366 }
2367
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002368 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2369 return injectionResult;
2370 }
2371
Michael Wrightd02c5b62014-02-10 15:10:22 -08002372 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002373 if (!wrongDevice) {
2374 if (switchedDevice) {
2375 if (DEBUG_FOCUS) {
2376 ALOGD("Conflicting pointer actions: Switched to a different device.");
2377 }
2378 *outConflictingPointerActions = true;
2379 }
2380
2381 if (isHoverAction) {
2382 // Started hovering, therefore no longer down.
2383 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002384 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002385 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2386 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002387 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002388 *outConflictingPointerActions = true;
2389 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002390 tempTouchState.reset();
2391 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2392 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2393 tempTouchState.deviceId = entry.deviceId;
2394 tempTouchState.source = entry.source;
2395 tempTouchState.displayId = displayId;
2396 }
2397 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2398 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2399 // All pointers up or canceled.
2400 tempTouchState.reset();
2401 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2402 // First pointer went down.
2403 if (oldState && oldState->down) {
2404 if (DEBUG_FOCUS) {
2405 ALOGD("Conflicting pointer actions: Down received while already down.");
2406 }
2407 *outConflictingPointerActions = true;
2408 }
2409 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2410 // One pointer went up.
2411 if (isSplit) {
2412 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2413 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002414
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002415 for (size_t i = 0; i < tempTouchState.windows.size();) {
2416 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2417 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2418 touchedWindow.pointerIds.clearBit(pointerId);
2419 if (touchedWindow.pointerIds.isEmpty()) {
2420 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2421 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002423 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002424 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002425 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002426 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002427 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002428
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002429 // Save changes unless the action was scroll in which case the temporary touch
2430 // state was only valid for this one action.
2431 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2432 if (tempTouchState.displayId >= 0) {
2433 mTouchStatesByDisplay[displayId] = tempTouchState;
2434 } else {
2435 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002436 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002437 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002438
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002439 // Update hover state.
2440 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002441 }
2442
Michael Wrightd02c5b62014-02-10 15:10:22 -08002443 return injectionResult;
2444}
2445
arthurhung6d4bed92021-03-17 11:59:33 +08002446void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002447 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2448 // have an explicit reason to support it.
2449 constexpr bool isStylus = false;
2450
chaviw98318de2021-05-19 16:45:23 -05002451 const sp<WindowInfoHandle> dropWindow =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002452 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002453 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002454 if (dropWindow) {
2455 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002456 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002457 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002458 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002459 }
2460 mDragState.reset();
2461}
2462
2463void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2464 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002465 return;
2466 }
2467
arthurhung6d4bed92021-03-17 11:59:33 +08002468 if (!mDragState->isStartDrag) {
2469 mDragState->isStartDrag = true;
2470 mDragState->isStylusButtonDownAtStart =
2471 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2472 }
2473
arthurhungb89ccb02020-12-30 16:19:01 +08002474 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2475 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2476 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2477 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002478 // Handle the special case : stylus button no longer pressed.
2479 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2480 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2481 finishDragAndDrop(entry.displayId, x, y);
2482 return;
2483 }
2484
Prabir Pradhand65552b2021-10-07 11:23:50 -07002485 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until
2486 // we have an explicit reason to support it.
2487 constexpr bool isStylus = false;
2488
chaviw98318de2021-05-19 16:45:23 -05002489 const sp<WindowInfoHandle> hoverWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002490 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002491 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002492 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002493 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2494 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2495 if (mDragState->dragHoverWindowHandle != nullptr) {
2496 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2497 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002498 }
arthurhung6d4bed92021-03-17 11:59:33 +08002499 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002500 }
2501 // enqueue drag location if needed.
2502 if (hoverWindowHandle != nullptr) {
2503 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2504 }
arthurhung6d4bed92021-03-17 11:59:33 +08002505 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2506 finishDragAndDrop(entry.displayId, x, y);
2507 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002508 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002509 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002510 }
2511}
2512
chaviw98318de2021-05-19 16:45:23 -05002513void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002514 int32_t targetFlags, BitSet32 pointerIds,
2515 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002516 std::vector<InputTarget>::iterator it =
2517 std::find_if(inputTargets.begin(), inputTargets.end(),
2518 [&windowHandle](const InputTarget& inputTarget) {
2519 return inputTarget.inputChannel->getConnectionToken() ==
2520 windowHandle->getToken();
2521 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002522
chaviw98318de2021-05-19 16:45:23 -05002523 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002524
2525 if (it == inputTargets.end()) {
2526 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002527 std::shared_ptr<InputChannel> inputChannel =
2528 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002529 if (inputChannel == nullptr) {
2530 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2531 return;
2532 }
2533 inputTarget.inputChannel = inputChannel;
2534 inputTarget.flags = targetFlags;
2535 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002536 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2537 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002538 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002539 } else {
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00002540 ALOGE("DisplayInfo not found for window on display: %d", windowInfo->displayId);
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002541 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002542 inputTargets.push_back(inputTarget);
2543 it = inputTargets.end() - 1;
2544 }
2545
2546 ALOG_ASSERT(it->flags == targetFlags);
2547 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2548
chaviw1ff3d1e2020-07-01 15:53:47 -07002549 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002550}
2551
Michael Wright3dd60e22019-03-27 22:06:44 +00002552void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002553 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002554 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2555 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002556
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002557 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2558 InputTarget target;
2559 target.inputChannel = monitor.inputChannel;
2560 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2561 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2562 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002563 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002564 target.setDefaultPointerTransform(target.displayTransform);
2565 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002566 }
2567}
2568
chaviw98318de2021-05-19 16:45:23 -05002569bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002570 const InjectionState* injectionState) {
2571 if (injectionState &&
2572 (windowHandle == nullptr ||
2573 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2574 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002575 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002576 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002577 "owned by uid %d",
2578 injectionState->injectorPid, injectionState->injectorUid,
2579 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002580 } else {
2581 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002582 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583 }
2584 return false;
2585 }
2586 return true;
2587}
2588
Robert Carrc9bf1d32020-04-13 17:21:08 -07002589/**
2590 * Indicate whether one window handle should be considered as obscuring
2591 * another window handle. We only check a few preconditions. Actually
2592 * checking the bounds is left to the caller.
2593 */
chaviw98318de2021-05-19 16:45:23 -05002594static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2595 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002596 // Compare by token so cloned layers aren't counted
2597 if (haveSameToken(windowHandle, otherHandle)) {
2598 return false;
2599 }
2600 auto info = windowHandle->getInfo();
2601 auto otherInfo = otherHandle->getInfo();
2602 if (!otherInfo->visible) {
2603 return false;
chaviw98318de2021-05-19 16:45:23 -05002604 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002605 // Those act as if they were invisible, so we don't need to flag them.
2606 // We do want to potentially flag touchable windows even if they have 0
2607 // opacity, since they can consume touches and alter the effects of the
2608 // user interaction (eg. apps that rely on
2609 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2610 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2611 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002612 } else if (info->ownerUid == otherInfo->ownerUid) {
2613 // If ownerUid is the same we don't generate occlusion events as there
2614 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002615 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002616 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002617 return false;
2618 } else if (otherInfo->displayId != info->displayId) {
2619 return false;
2620 }
2621 return true;
2622}
2623
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002624/**
2625 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2626 * untrusted, one should check:
2627 *
2628 * 1. If result.hasBlockingOcclusion is true.
2629 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2630 * BLOCK_UNTRUSTED.
2631 *
2632 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2633 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2634 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2635 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2636 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2637 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2638 *
2639 * If neither of those is true, then it means the touch can be allowed.
2640 */
2641InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002642 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2643 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002644 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002645 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002646 TouchOcclusionInfo info;
2647 info.hasBlockingOcclusion = false;
2648 info.obscuringOpacity = 0;
2649 info.obscuringUid = -1;
2650 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002651 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002652 if (windowHandle == otherHandle) {
2653 break; // All future windows are below us. Exit early.
2654 }
chaviw98318de2021-05-19 16:45:23 -05002655 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002656 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2657 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002658 if (DEBUG_TOUCH_OCCLUSION) {
2659 info.debugInfo.push_back(
2660 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2661 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002662 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2663 // we perform the checks below to see if the touch can be propagated or not based on the
2664 // window's touch occlusion mode
2665 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2666 info.hasBlockingOcclusion = true;
2667 info.obscuringUid = otherInfo->ownerUid;
2668 info.obscuringPackage = otherInfo->packageName;
2669 break;
2670 }
2671 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2672 uint32_t uid = otherInfo->ownerUid;
2673 float opacity =
2674 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2675 // Given windows A and B:
2676 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2677 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2678 opacityByUid[uid] = opacity;
2679 if (opacity > info.obscuringOpacity) {
2680 info.obscuringOpacity = opacity;
2681 info.obscuringUid = uid;
2682 info.obscuringPackage = otherInfo->packageName;
2683 }
2684 }
2685 }
2686 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002687 if (DEBUG_TOUCH_OCCLUSION) {
2688 info.debugInfo.push_back(
2689 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2690 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002691 return info;
2692}
2693
chaviw98318de2021-05-19 16:45:23 -05002694std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002695 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002696 return StringPrintf(INDENT2
2697 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2698 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2699 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2700 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002701 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002702 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002703 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2704 info->frameTop, info->frameRight, info->frameBottom,
2705 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002706 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2707 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2708 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002709}
2710
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002711bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2712 if (occlusionInfo.hasBlockingOcclusion) {
2713 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2714 occlusionInfo.obscuringUid);
2715 return false;
2716 }
2717 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2718 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2719 "%.2f, maximum allowed = %.2f)",
2720 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2721 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2722 return false;
2723 }
2724 return true;
2725}
2726
chaviw98318de2021-05-19 16:45:23 -05002727bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002728 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002730 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2731 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002732 if (windowHandle == otherHandle) {
2733 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734 }
chaviw98318de2021-05-19 16:45:23 -05002735 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002736 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002737 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002738 return true;
2739 }
2740 }
2741 return false;
2742}
2743
chaviw98318de2021-05-19 16:45:23 -05002744bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002745 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002746 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2747 const WindowInfo* windowInfo = windowHandle->getInfo();
2748 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002749 if (windowHandle == otherHandle) {
2750 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002751 }
chaviw98318de2021-05-19 16:45:23 -05002752 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002753 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002754 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002755 return true;
2756 }
2757 }
2758 return false;
2759}
2760
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002761std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002762 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002763 if (applicationHandle != nullptr) {
2764 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002765 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002766 } else {
2767 return applicationHandle->getName();
2768 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002769 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002770 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002771 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002772 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002773 }
2774}
2775
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002776void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002777 if (!isUserActivityEvent(eventEntry)) {
2778 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002779 return;
2780 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002781 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002782 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002783 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002784 const WindowInfo* info = focusedWindowHandle->getInfo();
2785 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002786 if (DEBUG_DISPATCH_CYCLE) {
2787 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2788 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002789 return;
2790 }
2791 }
2792
2793 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002794 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002795 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002796 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2797 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002798 return;
2799 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002800
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002801 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002802 eventType = USER_ACTIVITY_EVENT_TOUCH;
2803 }
2804 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002805 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002806 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002807 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2808 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002809 return;
2810 }
2811 eventType = USER_ACTIVITY_EVENT_BUTTON;
2812 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002813 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002814 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002815 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002816 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002817 break;
2818 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002819 }
2820
Prabir Pradhancef936d2021-07-21 16:17:52 +00002821 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2822 REQUIRES(mLock) {
2823 scoped_unlock unlock(mLock);
2824 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2825 };
2826 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002827}
2828
2829void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002830 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002831 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002832 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002833 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002834 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002835 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002836 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002837 ATRACE_NAME(message.c_str());
2838 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002839 if (DEBUG_DISPATCH_CYCLE) {
2840 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2841 "globalScaleFactor=%f, pointerIds=0x%x %s",
2842 connection->getInputChannelName().c_str(), inputTarget.flags,
2843 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2844 inputTarget.getPointerInfoString().c_str());
2845 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002846
2847 // Skip this event if the connection status is not normal.
2848 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002849 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002850 if (DEBUG_DISPATCH_CYCLE) {
2851 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002852 connection->getInputChannelName().c_str(),
2853 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002855 return;
2856 }
2857
2858 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002859 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2860 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2861 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002862 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002863
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002864 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002865 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002866 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002867 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002868 if (!splitMotionEntry) {
2869 return; // split event was dropped
2870 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00002871 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
2872 std::string reason = std::string("reason=pointer cancel on split window");
2873 android_log_event_list(LOGTAG_INPUT_CANCEL)
2874 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
2875 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002876 if (DEBUG_FOCUS) {
2877 ALOGD("channel '%s' ~ Split motion event.",
2878 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002879 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002880 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002881 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2882 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002883 return;
2884 }
2885 }
2886
2887 // Not splitting. Enqueue dispatch entries for the event as is.
2888 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2889}
2890
2891void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002892 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002893 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002894 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002895 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002896 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002897 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002898 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002899 ATRACE_NAME(message.c_str());
2900 }
2901
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002902 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002903
2904 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002905 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002906 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002907 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002908 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002909 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002910 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002911 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002912 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002913 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002914 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002915 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002916 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002917
2918 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002919 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002920 startDispatchCycleLocked(currentTime, connection);
2921 }
2922}
2923
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002924void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002925 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002926 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002927 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002928 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002929 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2930 connection->getInputChannelName().c_str(),
2931 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002932 ATRACE_NAME(message.c_str());
2933 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002934 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002935 if (!(inputTargetFlags & dispatchMode)) {
2936 return;
2937 }
2938 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2939
2940 // This is a new event.
2941 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002942 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002943 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002944
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002945 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2946 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002947 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002949 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002950 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002951 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002952 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002953 dispatchEntry->resolvedAction = keyEntry.action;
2954 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002955
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002956 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2957 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002958 if (DEBUG_DISPATCH_CYCLE) {
2959 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2960 "event",
2961 connection->getInputChannelName().c_str());
2962 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002963 return; // skip the inconsistent event
2964 }
2965 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002966 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002967
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002968 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002969 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002970 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2971 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2972 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2973 static_cast<int32_t>(IdGenerator::Source::OTHER);
2974 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002975 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2976 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2977 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2978 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2979 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2980 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2981 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2982 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2983 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2984 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2985 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002986 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002987 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002988 }
2989 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002990 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2991 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002992 if (DEBUG_DISPATCH_CYCLE) {
2993 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
2994 "enter event",
2995 connection->getInputChannelName().c_str());
2996 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002997 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2998 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002999 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3000 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003002 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003003 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3004 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3005 }
3006 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3007 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3008 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003010 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3011 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003012 if (DEBUG_DISPATCH_CYCLE) {
3013 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3014 "event",
3015 connection->getInputChannelName().c_str());
3016 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003017 return; // skip the inconsistent event
3018 }
3019
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003020 dispatchEntry->resolvedEventId =
3021 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3022 ? mIdGenerator.nextId()
3023 : motionEntry.id;
3024 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3025 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3026 ") to MotionEvent(id=0x%" PRIx32 ").",
3027 motionEntry.id, dispatchEntry->resolvedEventId);
3028 ATRACE_NAME(message.c_str());
3029 }
3030
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003031 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3032 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3033 // Skip reporting pointer down outside focus to the policy.
3034 break;
3035 }
3036
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003037 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003038 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003039
3040 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003041 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003042 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003043 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003044 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3045 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003046 break;
3047 }
Chris Yef59a2f42020-10-16 12:55:26 -07003048 case EventEntry::Type::SENSOR: {
3049 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3050 break;
3051 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003052 case EventEntry::Type::CONFIGURATION_CHANGED:
3053 case EventEntry::Type::DEVICE_RESET: {
3054 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003055 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003056 break;
3057 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003058 }
3059
3060 // Remember that we are waiting for this dispatch to complete.
3061 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003062 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003063 }
3064
3065 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003066 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003067 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003068}
3069
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003070/**
3071 * This function is purely for debugging. It helps us understand where the user interaction
3072 * was taking place. For example, if user is touching launcher, we will see a log that user
3073 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3074 * We will see both launcher and wallpaper in that list.
3075 * Once the interaction with a particular set of connections starts, no new logs will be printed
3076 * until the set of interacted connections changes.
3077 *
3078 * The following items are skipped, to reduce the logspam:
3079 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3080 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3081 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3082 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3083 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003084 */
3085void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3086 const std::vector<InputTarget>& targets) {
3087 // Skip ACTION_UP events, and all events other than keys and motions
3088 if (entry.type == EventEntry::Type::KEY) {
3089 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3090 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3091 return;
3092 }
3093 } else if (entry.type == EventEntry::Type::MOTION) {
3094 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3095 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3096 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3097 return;
3098 }
3099 } else {
3100 return; // Not a key or a motion
3101 }
3102
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003103 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003104 std::vector<sp<Connection>> newConnections;
3105 for (const InputTarget& target : targets) {
3106 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3107 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3108 continue; // Skip windows that receive ACTION_OUTSIDE
3109 }
3110
3111 sp<IBinder> token = target.inputChannel->getConnectionToken();
3112 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003113 if (connection == nullptr) {
3114 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003115 }
3116 newConnectionTokens.insert(std::move(token));
3117 newConnections.emplace_back(connection);
3118 }
3119 if (newConnectionTokens == mInteractionConnectionTokens) {
3120 return; // no change
3121 }
3122 mInteractionConnectionTokens = newConnectionTokens;
3123
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003124 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003125 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003126 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003127 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003128 std::string message = "Interaction with: " + targetList;
3129 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003130 message += "<none>";
3131 }
3132 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3133}
3134
chaviwfd6d3512019-03-25 13:23:49 -07003135void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003136 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003137 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003138 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3139 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003140 return;
3141 }
3142
Vishnu Nairc519ff72021-01-21 08:23:08 -08003143 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003144 if (focusedToken == token) {
3145 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003146 return;
3147 }
3148
Prabir Pradhancef936d2021-07-21 16:17:52 +00003149 auto command = [this, token]() REQUIRES(mLock) {
3150 scoped_unlock unlock(mLock);
3151 mPolicy->onPointerDownOutsideFocus(token);
3152 };
3153 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154}
3155
3156void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003157 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003158 if (ATRACE_ENABLED()) {
3159 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003160 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003161 ATRACE_NAME(message.c_str());
3162 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003163 if (DEBUG_DISPATCH_CYCLE) {
3164 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3165 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003166
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003167 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003168 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003170 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003171 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003172
3173 // Publish the event.
3174 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003175 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3176 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003177 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003178 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3179 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003180
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003181 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003182 status = connection->inputPublisher
3183 .publishKeyEvent(dispatchEntry->seq,
3184 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3185 keyEntry.source, keyEntry.displayId,
3186 std::move(hmac), dispatchEntry->resolvedAction,
3187 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3188 keyEntry.scanCode, keyEntry.metaState,
3189 keyEntry.repeatCount, keyEntry.downTime,
3190 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003191 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192 }
3193
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003194 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003195 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003196
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003197 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003198 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003199
chaviw82357092020-01-28 13:13:06 -08003200 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003201 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003202 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3203 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003204 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003205 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3206 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003207 // Don't apply window scale here since we don't want scale to affect raw
3208 // coordinates. The scale will be sent back to the client and applied
3209 // later when requesting relative coordinates.
3210 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3211 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003212 }
3213 usingCoords = scaledCoords;
3214 }
3215 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003216 // We don't want the dispatch target to know.
3217 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003218 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003219 scaledCoords[i].clear();
3220 }
3221 usingCoords = scaledCoords;
3222 }
3223 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003224
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003225 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003226
3227 // Publish the motion event.
3228 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003229 .publishMotionEvent(dispatchEntry->seq,
3230 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003231 motionEntry.deviceId, motionEntry.source,
3232 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003233 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003234 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003235 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003236 motionEntry.edgeFlags, motionEntry.metaState,
3237 motionEntry.buttonState,
3238 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003239 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003240 motionEntry.xPrecision, motionEntry.yPrecision,
3241 motionEntry.xCursorPosition,
3242 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003243 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003244 motionEntry.downTime, motionEntry.eventTime,
3245 motionEntry.pointerCount,
3246 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003247 break;
3248 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003249
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003250 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003251 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003252 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003253 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003254 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003255 break;
3256 }
3257
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003258 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3259 const TouchModeEntry& touchModeEntry =
3260 static_cast<const TouchModeEntry&>(eventEntry);
3261 status = connection->inputPublisher
3262 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3263 touchModeEntry.inTouchMode);
3264
3265 break;
3266 }
3267
Prabir Pradhan99987712020-11-10 18:43:05 -08003268 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3269 const auto& captureEntry =
3270 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3271 status = connection->inputPublisher
3272 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003273 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003274 break;
3275 }
3276
arthurhungb89ccb02020-12-30 16:19:01 +08003277 case EventEntry::Type::DRAG: {
3278 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3279 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3280 dragEntry.id, dragEntry.x,
3281 dragEntry.y,
3282 dragEntry.isExiting);
3283 break;
3284 }
3285
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003286 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003287 case EventEntry::Type::DEVICE_RESET:
3288 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003289 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003290 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003291 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003292 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003293 }
3294
3295 // Check the result.
3296 if (status) {
3297 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003298 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003299 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003300 "This is unexpected because the wait queue is empty, so the pipe "
3301 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003302 "event to it, status=%s(%d)",
3303 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3304 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003305 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3306 } else {
3307 // Pipe is full and we are waiting for the app to finish process some events
3308 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003309 if (DEBUG_DISPATCH_CYCLE) {
3310 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3311 "waiting for the application to catch up",
3312 connection->getInputChannelName().c_str());
3313 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003314 }
3315 } else {
3316 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003317 "status=%s(%d)",
3318 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3319 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003320 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3321 }
3322 return;
3323 }
3324
3325 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003326 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3327 connection->outboundQueue.end(),
3328 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003329 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003330 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003331 if (connection->responsive) {
3332 mAnrTracker.insert(dispatchEntry->timeoutTime,
3333 connection->inputChannel->getConnectionToken());
3334 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003335 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336 }
3337}
3338
chaviw09c8d2d2020-08-24 15:48:26 -07003339std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3340 size_t size;
3341 switch (event.type) {
3342 case VerifiedInputEvent::Type::KEY: {
3343 size = sizeof(VerifiedKeyEvent);
3344 break;
3345 }
3346 case VerifiedInputEvent::Type::MOTION: {
3347 size = sizeof(VerifiedMotionEvent);
3348 break;
3349 }
3350 }
3351 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3352 return mHmacKeyManager.sign(start, size);
3353}
3354
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003355const std::array<uint8_t, 32> InputDispatcher::getSignature(
3356 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003357 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3358 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003359 // Only sign events up and down events as the purely move events
3360 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003361 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003362 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003363
3364 VerifiedMotionEvent verifiedEvent =
3365 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3366 verifiedEvent.actionMasked = actionMasked;
3367 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3368 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003369}
3370
3371const std::array<uint8_t, 32> InputDispatcher::getSignature(
3372 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3373 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3374 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3375 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003376 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003377}
3378
Michael Wrightd02c5b62014-02-10 15:10:22 -08003379void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003380 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003381 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003382 if (DEBUG_DISPATCH_CYCLE) {
3383 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3384 connection->getInputChannelName().c_str(), seq, toString(handled));
3385 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003387 if (connection->status == Connection::Status::BROKEN ||
3388 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003389 return;
3390 }
3391
3392 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003393 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3394 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3395 };
3396 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003397}
3398
3399void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003400 const sp<Connection>& connection,
3401 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003402 if (DEBUG_DISPATCH_CYCLE) {
3403 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3404 connection->getInputChannelName().c_str(), toString(notify));
3405 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003406
3407 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003408 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003409 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003410 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003411 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003412
3413 // The connection appears to be unrecoverably broken.
3414 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003415 if (connection->status == Connection::Status::NORMAL) {
3416 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003417
3418 if (notify) {
3419 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003420 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3421 connection->getInputChannelName().c_str());
3422
3423 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003424 scoped_unlock unlock(mLock);
3425 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3426 };
3427 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003428 }
3429 }
3430}
3431
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003432void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3433 while (!queue.empty()) {
3434 DispatchEntry* dispatchEntry = queue.front();
3435 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003436 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003437 }
3438}
3439
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003440void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003441 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003442 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003443 }
3444 delete dispatchEntry;
3445}
3446
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003447int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3448 std::scoped_lock _l(mLock);
3449 sp<Connection> connection = getConnectionLocked(connectionToken);
3450 if (connection == nullptr) {
3451 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3452 connectionToken.get(), events);
3453 return 0; // remove the callback
3454 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003455
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003456 bool notify;
3457 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3458 if (!(events & ALOOPER_EVENT_INPUT)) {
3459 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3460 "events=0x%x",
3461 connection->getInputChannelName().c_str(), events);
3462 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003463 }
3464
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003465 nsecs_t currentTime = now();
3466 bool gotOne = false;
3467 status_t status = OK;
3468 for (;;) {
3469 Result<InputPublisher::ConsumerResponse> result =
3470 connection->inputPublisher.receiveConsumerResponse();
3471 if (!result.ok()) {
3472 status = result.error().code();
3473 break;
3474 }
3475
3476 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3477 const InputPublisher::Finished& finish =
3478 std::get<InputPublisher::Finished>(*result);
3479 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3480 finish.consumeTime);
3481 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003482 if (shouldReportMetricsForConnection(*connection)) {
3483 const InputPublisher::Timeline& timeline =
3484 std::get<InputPublisher::Timeline>(*result);
3485 mLatencyTracker
3486 .trackGraphicsLatency(timeline.inputEventId,
3487 connection->inputChannel->getConnectionToken(),
3488 std::move(timeline.graphicsTimeline));
3489 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003490 }
3491 gotOne = true;
3492 }
3493 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003494 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003495 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003496 return 1;
3497 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498 }
3499
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003500 notify = status != DEAD_OBJECT || !connection->monitor;
3501 if (notify) {
3502 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3503 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3504 status);
3505 }
3506 } else {
3507 // Monitor channels are never explicitly unregistered.
3508 // We do it automatically when the remote endpoint is closed so don't warn about them.
3509 const bool stillHaveWindowHandle =
3510 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3511 notify = !connection->monitor && stillHaveWindowHandle;
3512 if (notify) {
3513 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3514 connection->getInputChannelName().c_str(), events);
3515 }
3516 }
3517
3518 // Remove the channel.
3519 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3520 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003521}
3522
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003523void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003524 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003525 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003526 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003527 }
3528}
3529
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003530void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003531 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003532 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003533 for (const Monitor& monitor : monitors) {
3534 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003535 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003536 }
3537}
3538
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003540 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003541 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003542 if (connection == nullptr) {
3543 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003544 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003545
3546 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547}
3548
3549void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3550 const sp<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003551 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552 return;
3553 }
3554
3555 nsecs_t currentTime = now();
3556
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003557 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003558 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003559
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003560 if (cancelationEvents.empty()) {
3561 return;
3562 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003563 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3564 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3565 "with reality: %s, mode=%d.",
3566 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3567 options.mode);
3568 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003569
Arthur Hungb3307ee2021-10-14 10:57:37 +00003570 std::string reason = std::string("reason=").append(options.reason);
3571 android_log_event_list(LOGTAG_INPUT_CANCEL)
3572 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3573
Svet Ganov5d3bc372020-01-26 23:11:07 -08003574 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003575 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003576 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3577 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003578 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003579 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003580 target.globalScaleFactor = windowInfo->globalScaleFactor;
3581 }
3582 target.inputChannel = connection->inputChannel;
3583 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3584
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003585 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003586 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003587 switch (cancelationEventEntry->type) {
3588 case EventEntry::Type::KEY: {
3589 logOutboundKeyDetails("cancel - ",
3590 static_cast<const KeyEntry&>(*cancelationEventEntry));
3591 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003592 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003593 case EventEntry::Type::MOTION: {
3594 logOutboundMotionDetails("cancel - ",
3595 static_cast<const MotionEntry&>(*cancelationEventEntry));
3596 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003597 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003598 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003599 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003600 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3601 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003602 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003603 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003604 break;
3605 }
3606 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003607 case EventEntry::Type::DEVICE_RESET:
3608 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003609 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003610 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003611 break;
3612 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613 }
3614
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003615 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3616 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003618
3619 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003620}
3621
Svet Ganov5d3bc372020-01-26 23:11:07 -08003622void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3623 const sp<Connection>& connection) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003624 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003625 return;
3626 }
3627
3628 nsecs_t currentTime = now();
3629
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003630 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003631 connection->inputState.synthesizePointerDownEvents(currentTime);
3632
3633 if (downEvents.empty()) {
3634 return;
3635 }
3636
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003637 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003638 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3639 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003640 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003641
3642 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003643 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003644 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3645 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003646 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003647 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003648 target.globalScaleFactor = windowInfo->globalScaleFactor;
3649 }
3650 target.inputChannel = connection->inputChannel;
3651 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3652
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003653 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003654 switch (downEventEntry->type) {
3655 case EventEntry::Type::MOTION: {
3656 logOutboundMotionDetails("down - ",
3657 static_cast<const MotionEntry&>(*downEventEntry));
3658 break;
3659 }
3660
3661 case EventEntry::Type::KEY:
3662 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003663 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003664 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003665 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003666 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003667 case EventEntry::Type::SENSOR:
3668 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003669 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003670 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003671 break;
3672 }
3673 }
3674
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003675 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3676 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003677 }
3678
3679 startDispatchCycleLocked(currentTime, connection);
3680}
3681
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003682std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3683 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003684 ALOG_ASSERT(pointerIds.value != 0);
3685
3686 uint32_t splitPointerIndexMap[MAX_POINTERS];
3687 PointerProperties splitPointerProperties[MAX_POINTERS];
3688 PointerCoords splitPointerCoords[MAX_POINTERS];
3689
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003690 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003691 uint32_t splitPointerCount = 0;
3692
3693 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003694 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003695 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003696 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003697 uint32_t pointerId = uint32_t(pointerProperties.id);
3698 if (pointerIds.hasBit(pointerId)) {
3699 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3700 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3701 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003702 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003703 splitPointerCount += 1;
3704 }
3705 }
3706
3707 if (splitPointerCount != pointerIds.count()) {
3708 // This is bad. We are missing some of the pointers that we expected to deliver.
3709 // Most likely this indicates that we received an ACTION_MOVE events that has
3710 // different pointer ids than we expected based on the previous ACTION_DOWN
3711 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3712 // in this way.
3713 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003714 "we expected there to be %d pointers. This probably means we received "
3715 "a broken sequence of pointer ids from the input device.",
3716 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003717 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003718 }
3719
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003720 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003721 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003722 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3723 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003724 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3725 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003726 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003727 uint32_t pointerId = uint32_t(pointerProperties.id);
3728 if (pointerIds.hasBit(pointerId)) {
3729 if (pointerIds.count() == 1) {
3730 // The first/last pointer went down/up.
3731 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003732 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003733 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3734 ? AMOTION_EVENT_ACTION_CANCEL
3735 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003736 } else {
3737 // A secondary pointer went down/up.
3738 uint32_t splitPointerIndex = 0;
3739 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3740 splitPointerIndex += 1;
3741 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003742 action = maskedAction |
3743 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003744 }
3745 } else {
3746 // An unrelated pointer changed.
3747 action = AMOTION_EVENT_ACTION_MOVE;
3748 }
3749 }
3750
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003751 int32_t newId = mIdGenerator.nextId();
3752 if (ATRACE_ENABLED()) {
3753 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3754 ") to MotionEvent(id=0x%" PRIx32 ").",
3755 originalMotionEntry.id, newId);
3756 ATRACE_NAME(message.c_str());
3757 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003758 std::unique_ptr<MotionEntry> splitMotionEntry =
3759 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3760 originalMotionEntry.deviceId, originalMotionEntry.source,
3761 originalMotionEntry.displayId,
3762 originalMotionEntry.policyFlags, action,
3763 originalMotionEntry.actionButton,
3764 originalMotionEntry.flags, originalMotionEntry.metaState,
3765 originalMotionEntry.buttonState,
3766 originalMotionEntry.classification,
3767 originalMotionEntry.edgeFlags,
3768 originalMotionEntry.xPrecision,
3769 originalMotionEntry.yPrecision,
3770 originalMotionEntry.xCursorPosition,
3771 originalMotionEntry.yCursorPosition,
3772 originalMotionEntry.downTime, splitPointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00003773 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003774
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003775 if (originalMotionEntry.injectionState) {
3776 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003777 splitMotionEntry->injectionState->refCount += 1;
3778 }
3779
3780 return splitMotionEntry;
3781}
3782
3783void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003784 if (DEBUG_INBOUND_EVENT_DETAILS) {
3785 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3786 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787
Antonio Kantekf16f2832021-09-28 04:39:20 +00003788 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003789 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003790 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003792 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3793 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3794 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003795 } // release lock
3796
3797 if (needWake) {
3798 mLooper->wake();
3799 }
3800}
3801
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003802/**
3803 * If one of the meta shortcuts is detected, process them here:
3804 * Meta + Backspace -> generate BACK
3805 * Meta + Enter -> generate HOME
3806 * This will potentially overwrite keyCode and metaState.
3807 */
3808void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003809 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003810 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3811 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3812 if (keyCode == AKEYCODE_DEL) {
3813 newKeyCode = AKEYCODE_BACK;
3814 } else if (keyCode == AKEYCODE_ENTER) {
3815 newKeyCode = AKEYCODE_HOME;
3816 }
3817 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003818 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003819 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003820 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003821 keyCode = newKeyCode;
3822 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3823 }
3824 } else if (action == AKEY_EVENT_ACTION_UP) {
3825 // In order to maintain a consistent stream of up and down events, check to see if the key
3826 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3827 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003828 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003829 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003830 auto replacementIt = mReplacedKeys.find(replacement);
3831 if (replacementIt != mReplacedKeys.end()) {
3832 keyCode = replacementIt->second;
3833 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003834 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3835 }
3836 }
3837}
3838
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003840 if (DEBUG_INBOUND_EVENT_DETAILS) {
3841 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3842 "policyFlags=0x%x, action=0x%x, "
3843 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3844 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3845 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3846 args->downTime);
3847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003848 if (!validateKeyEvent(args->action)) {
3849 return;
3850 }
3851
3852 uint32_t policyFlags = args->policyFlags;
3853 int32_t flags = args->flags;
3854 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003855 // InputDispatcher tracks and generates key repeats on behalf of
3856 // whatever notifies it, so repeatCount should always be set to 0
3857 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003858 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3859 policyFlags |= POLICY_FLAG_VIRTUAL;
3860 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3861 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003862 if (policyFlags & POLICY_FLAG_FUNCTION) {
3863 metaState |= AMETA_FUNCTION_ON;
3864 }
3865
3866 policyFlags |= POLICY_FLAG_TRUSTED;
3867
Michael Wright78f24442014-08-06 15:55:28 -07003868 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003869 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003870
Michael Wrightd02c5b62014-02-10 15:10:22 -08003871 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003872 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003873 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3874 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875
Michael Wright2b3c3302018-03-02 17:19:13 +00003876 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003878 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3879 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003880 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003882
Antonio Kantekf16f2832021-09-28 04:39:20 +00003883 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003884 { // acquire lock
3885 mLock.lock();
3886
3887 if (shouldSendKeyToInputFilterLocked(args)) {
3888 mLock.unlock();
3889
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003890 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003891 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3892 return; // event was consumed by the filter
3893 }
3894
3895 mLock.lock();
3896 }
3897
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003898 std::unique_ptr<KeyEntry> newEntry =
3899 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3900 args->displayId, policyFlags, args->action, flags,
3901 keyCode, args->scanCode, metaState, repeatCount,
3902 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003903
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003904 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905 mLock.unlock();
3906 } // release lock
3907
3908 if (needWake) {
3909 mLooper->wake();
3910 }
3911}
3912
3913bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3914 return mInputFilterEnabled;
3915}
3916
3917void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003918 if (DEBUG_INBOUND_EVENT_DETAILS) {
3919 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3920 "displayId=%" PRId32 ", policyFlags=0x%x, "
3921 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3922 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3923 "yCursorPosition=%f, downTime=%" PRId64,
3924 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3925 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3926 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3927 args->xCursorPosition, args->yCursorPosition, args->downTime);
3928 for (uint32_t i = 0; i < args->pointerCount; i++) {
3929 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3930 "x=%f, y=%f, pressure=%f, size=%f, "
3931 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3932 "orientation=%f",
3933 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3934 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3935 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3936 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3937 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3938 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3939 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3940 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3941 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3942 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3943 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003944 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003945 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3946 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003947 return;
3948 }
3949
3950 uint32_t policyFlags = args->policyFlags;
3951 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003952
3953 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003954 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003955 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3956 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003957 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003958 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003959
Antonio Kantekf16f2832021-09-28 04:39:20 +00003960 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003961 { // acquire lock
3962 mLock.lock();
3963
3964 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003965 ui::Transform displayTransform;
3966 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
3967 displayTransform = it->second.transform;
3968 }
3969
Michael Wrightd02c5b62014-02-10 15:10:22 -08003970 mLock.unlock();
3971
3972 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003973 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3974 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003975 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003976 displayTransform, args->xPrecision, args->yPrecision,
3977 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003978 args->downTime, args->eventTime, args->pointerCount,
3979 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003980
3981 policyFlags |= POLICY_FLAG_FILTERED;
3982 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3983 return; // event was consumed by the filter
3984 }
3985
3986 mLock.lock();
3987 }
3988
3989 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003990 std::unique_ptr<MotionEntry> newEntry =
3991 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3992 args->source, args->displayId, policyFlags,
3993 args->action, args->actionButton, args->flags,
3994 args->metaState, args->buttonState,
3995 args->classification, args->edgeFlags,
3996 args->xPrecision, args->yPrecision,
3997 args->xCursorPosition, args->yCursorPosition,
3998 args->downTime, args->pointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00003999 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004000
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004001 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4002 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4003 !mInputFilterEnabled) {
4004 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4005 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4006 }
4007
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004008 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004009 mLock.unlock();
4010 } // release lock
4011
4012 if (needWake) {
4013 mLooper->wake();
4014 }
4015}
4016
Chris Yef59a2f42020-10-16 12:55:26 -07004017void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004018 if (DEBUG_INBOUND_EVENT_DETAILS) {
4019 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4020 " sensorType=%s",
4021 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004022 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004023 }
Chris Yef59a2f42020-10-16 12:55:26 -07004024
Antonio Kantekf16f2832021-09-28 04:39:20 +00004025 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004026 { // acquire lock
4027 mLock.lock();
4028
4029 // Just enqueue a new sensor event.
4030 std::unique_ptr<SensorEntry> newEntry =
4031 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4032 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4033 args->sensorType, args->accuracy,
4034 args->accuracyChanged, args->values);
4035
4036 needWake = enqueueInboundEventLocked(std::move(newEntry));
4037 mLock.unlock();
4038 } // release lock
4039
4040 if (needWake) {
4041 mLooper->wake();
4042 }
4043}
4044
Chris Yefb552902021-02-03 17:18:37 -08004045void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004046 if (DEBUG_INBOUND_EVENT_DETAILS) {
4047 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4048 args->deviceId, args->isOn);
4049 }
Chris Yefb552902021-02-03 17:18:37 -08004050 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4051}
4052
Michael Wrightd02c5b62014-02-10 15:10:22 -08004053bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004054 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004055}
4056
4057void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004058 if (DEBUG_INBOUND_EVENT_DETAILS) {
4059 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4060 "switchMask=0x%08x",
4061 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4062 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063
4064 uint32_t policyFlags = args->policyFlags;
4065 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004066 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067}
4068
4069void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004070 if (DEBUG_INBOUND_EVENT_DETAILS) {
4071 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4072 args->deviceId);
4073 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004074
Antonio Kantekf16f2832021-09-28 04:39:20 +00004075 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004077 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004078
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004079 std::unique_ptr<DeviceResetEntry> newEntry =
4080 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4081 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082 } // release lock
4083
4084 if (needWake) {
4085 mLooper->wake();
4086 }
4087}
4088
Prabir Pradhan7e186182020-11-10 13:56:45 -08004089void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004090 if (DEBUG_INBOUND_EVENT_DETAILS) {
4091 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004092 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004093 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004094
Antonio Kantekf16f2832021-09-28 04:39:20 +00004095 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004096 { // acquire lock
4097 std::scoped_lock _l(mLock);
4098 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004099 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004100 needWake = enqueueInboundEventLocked(std::move(entry));
4101 } // release lock
4102
4103 if (needWake) {
4104 mLooper->wake();
4105 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004106}
4107
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004108InputEventInjectionResult InputDispatcher::injectInputEvent(
4109 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4110 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004111 if (DEBUG_INBOUND_EVENT_DETAILS) {
4112 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4113 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4114 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4115 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004116 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004117
4118 policyFlags |= POLICY_FLAG_INJECTED;
4119 if (hasInjectionPermission(injectorPid, injectorUid)) {
4120 policyFlags |= POLICY_FLAG_TRUSTED;
4121 }
4122
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004123 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004124 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4125 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4126 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4127 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4128 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004129 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004130 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004131 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004132 }
4133
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004134 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004135 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004136 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004137 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4138 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004139 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004140 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004141 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004142
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004143 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004144 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4145 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4146 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004147 int32_t keyCode = incomingKey.getKeyCode();
4148 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004149 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004150 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004151 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004152 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004153 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4154 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4155 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004157 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4158 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004159 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004160
4161 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4162 android::base::Timer t;
4163 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4164 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4165 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4166 std::to_string(t.duration().count()).c_str());
4167 }
4168 }
4169
4170 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004171 std::unique_ptr<KeyEntry> injectedEntry =
4172 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004173 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004174 incomingKey.getDisplayId(), policyFlags, action,
4175 flags, keyCode, incomingKey.getScanCode(), metaState,
4176 incomingKey.getRepeatCount(),
4177 incomingKey.getDownTime());
4178 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004179 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004180 }
4181
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004182 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004183 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004184 const int32_t action = motionEvent.getAction();
4185 const bool isPointerEvent =
4186 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4187 // If a pointer event has no displayId specified, inject it to the default display.
4188 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4189 ? ADISPLAY_ID_DEFAULT
4190 : event->getDisplayId();
4191 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004192 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004193 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004194 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004195 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004196 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004197 }
4198
4199 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004200 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004201 android::base::Timer t;
4202 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4203 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4204 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4205 std::to_string(t.duration().count()).c_str());
4206 }
4207 }
4208
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004209 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4210 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4211 }
4212
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004213 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004214 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4215 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004216 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004217 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4218 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004219 displayId, policyFlags, action, actionButton,
4220 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004221 motionEvent.getButtonState(),
4222 motionEvent.getClassification(),
4223 motionEvent.getEdgeFlags(),
4224 motionEvent.getXPrecision(),
4225 motionEvent.getYPrecision(),
4226 motionEvent.getRawXCursorPosition(),
4227 motionEvent.getRawYCursorPosition(),
4228 motionEvent.getDownTime(), uint32_t(pointerCount),
Prabir Pradhan5beda762021-12-10 09:30:08 +00004229 pointerProperties, samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004230 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004231 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004232 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004233 sampleEventTimes += 1;
4234 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004235 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004236 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4237 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004238 displayId, policyFlags, action, actionButton,
4239 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004240 motionEvent.getButtonState(),
4241 motionEvent.getClassification(),
4242 motionEvent.getEdgeFlags(),
4243 motionEvent.getXPrecision(),
4244 motionEvent.getYPrecision(),
4245 motionEvent.getRawXCursorPosition(),
4246 motionEvent.getRawYCursorPosition(),
4247 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004248 uint32_t(pointerCount), pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004249 samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004250 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4251 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004252 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004253 }
4254 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004255 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004256
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004257 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004258 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004259 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004260 }
4261
4262 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004263 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004264 injectionState->injectionIsAsync = true;
4265 }
4266
4267 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004268 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004269
4270 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004271 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004272 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004273 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004274 }
4275
4276 mLock.unlock();
4277
4278 if (needWake) {
4279 mLooper->wake();
4280 }
4281
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004282 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004283 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004284 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004285
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004286 if (syncMode == InputEventInjectionSync::NONE) {
4287 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004288 } else {
4289 for (;;) {
4290 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004291 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004292 break;
4293 }
4294
4295 nsecs_t remainingTimeout = endTime - now();
4296 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004297 if (DEBUG_INJECTION) {
4298 ALOGD("injectInputEvent - Timed out waiting for injection result "
4299 "to become available.");
4300 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004301 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004302 break;
4303 }
4304
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004305 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004306 }
4307
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004308 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4309 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004310 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004311 if (DEBUG_INJECTION) {
4312 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4313 injectionState->pendingForegroundDispatches);
4314 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004315 nsecs_t remainingTimeout = endTime - now();
4316 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004317 if (DEBUG_INJECTION) {
4318 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4319 "dispatches to finish.");
4320 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004321 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004322 break;
4323 }
4324
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004325 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004326 }
4327 }
4328 }
4329
4330 injectionState->release();
4331 } // release lock
4332
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004333 if (DEBUG_INJECTION) {
4334 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4335 injectionResult, injectorPid, injectorUid);
4336 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337
4338 return injectionResult;
4339}
4340
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004341std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004342 std::array<uint8_t, 32> calculatedHmac;
4343 std::unique_ptr<VerifiedInputEvent> result;
4344 switch (event.getType()) {
4345 case AINPUT_EVENT_TYPE_KEY: {
4346 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4347 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4348 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004349 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004350 break;
4351 }
4352 case AINPUT_EVENT_TYPE_MOTION: {
4353 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4354 VerifiedMotionEvent verifiedMotionEvent =
4355 verifiedMotionEventFromMotionEvent(motionEvent);
4356 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004357 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004358 break;
4359 }
4360 default: {
4361 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4362 return nullptr;
4363 }
4364 }
4365 if (calculatedHmac == INVALID_HMAC) {
4366 return nullptr;
4367 }
4368 if (calculatedHmac != event.getHmac()) {
4369 return nullptr;
4370 }
4371 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004372}
4373
Michael Wrightd02c5b62014-02-10 15:10:22 -08004374bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004375 return injectorUid == 0 ||
4376 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004377}
4378
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004379void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004380 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004381 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004382 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004383 if (DEBUG_INJECTION) {
4384 ALOGD("Setting input event injection result to %d. "
4385 "injectorPid=%d, injectorUid=%d",
4386 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4387 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004389 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004390 // Log the outcome since the injector did not wait for the injection result.
4391 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004392 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004393 ALOGV("Asynchronous input event injection succeeded.");
4394 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004395 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004396 ALOGW("Asynchronous input event injection failed.");
4397 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004398 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004399 ALOGW("Asynchronous input event injection permission denied.");
4400 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004401 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004402 ALOGW("Asynchronous input event injection timed out.");
4403 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004404 case InputEventInjectionResult::PENDING:
4405 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4406 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407 }
4408 }
4409
4410 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004411 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004412 }
4413}
4414
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004415void InputDispatcher::transformMotionEntryForInjectionLocked(
4416 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004417 // Input injection works in the logical display coordinate space, but the input pipeline works
4418 // display space, so we need to transform the injected events accordingly.
4419 const auto it = mDisplayInfos.find(entry.displayId);
4420 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004421 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004422
4423 for (uint32_t i = 0; i < entry.pointerCount; i++) {
4424 PointerCoords& pc = entry.pointerCoords[i];
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004425 // Make a copy of the injected coords. We cannot change them in place because some of them
4426 // are interdependent (for example, X coordinate might depend on the Y coordinate).
4427 PointerCoords injectedCoords = entry.pointerCoords[i];
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004428
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004429 BitSet64 bits(injectedCoords.bits);
4430 while (!bits.isEmpty()) {
4431 const auto axis = static_cast<int32_t>(bits.clearFirstMarkedBit());
4432 const float value =
4433 MotionEvent::calculateTransformedAxisValue(axis, entry.source,
4434 transformToDisplay, injectedCoords);
4435 pc.setAxisValue(axis, value);
4436 }
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004437 }
4438}
4439
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004440void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4441 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442 if (injectionState) {
4443 injectionState->pendingForegroundDispatches += 1;
4444 }
4445}
4446
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004447void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4448 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004449 if (injectionState) {
4450 injectionState->pendingForegroundDispatches -= 1;
4451
4452 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004453 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004454 }
4455 }
4456}
4457
chaviw98318de2021-05-19 16:45:23 -05004458const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004459 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004460 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004461 auto it = mWindowHandlesByDisplay.find(displayId);
4462 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004463}
4464
chaviw98318de2021-05-19 16:45:23 -05004465sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004466 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004467 if (windowHandleToken == nullptr) {
4468 return nullptr;
4469 }
4470
Arthur Hungb92218b2018-08-14 12:00:21 +08004471 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004472 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4473 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004474 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004475 return windowHandle;
4476 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004477 }
4478 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004479 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480}
4481
chaviw98318de2021-05-19 16:45:23 -05004482sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4483 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004484 if (windowHandleToken == nullptr) {
4485 return nullptr;
4486 }
4487
chaviw98318de2021-05-19 16:45:23 -05004488 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004489 if (windowHandle->getToken() == windowHandleToken) {
4490 return windowHandle;
4491 }
4492 }
4493 return nullptr;
4494}
4495
chaviw98318de2021-05-19 16:45:23 -05004496sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4497 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004498 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004499 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4500 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004501 if (handle->getId() == windowHandle->getId() &&
4502 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004503 if (windowHandle->getInfo()->displayId != it.first) {
4504 ALOGE("Found window %s in display %" PRId32
4505 ", but it should belong to display %" PRId32,
4506 windowHandle->getName().c_str(), it.first,
4507 windowHandle->getInfo()->displayId);
4508 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004509 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004510 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004511 }
4512 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004513 return nullptr;
4514}
4515
chaviw98318de2021-05-19 16:45:23 -05004516sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004517 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4518 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004519}
4520
chaviw98318de2021-05-19 16:45:23 -05004521bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004522 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4523 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004524 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004525 if (connection != nullptr && noInputChannel) {
4526 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4527 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4528 return false;
4529 }
4530
4531 if (connection == nullptr) {
4532 if (!noInputChannel) {
4533 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4534 }
4535 return false;
4536 }
4537 if (!connection->responsive) {
4538 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4539 return false;
4540 }
4541 return true;
4542}
4543
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004544std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4545 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004546 auto connectionIt = mConnectionsByToken.find(token);
4547 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004548 return nullptr;
4549 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004550 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004551}
4552
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004553void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004554 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4555 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004556 // Remove all handles on a display if there are no windows left.
4557 mWindowHandlesByDisplay.erase(displayId);
4558 return;
4559 }
4560
4561 // Since we compare the pointer of input window handles across window updates, we need
4562 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004563 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4564 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4565 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004566 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004567 }
4568
chaviw98318de2021-05-19 16:45:23 -05004569 std::vector<sp<WindowInfoHandle>> newHandles;
4570 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004571 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004572 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004573 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004574 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4575 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4576 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004577 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004578 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004579 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004580 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004581 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004582 }
4583
4584 if (info->displayId != displayId) {
4585 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4586 handle->getName().c_str(), displayId, info->displayId);
4587 continue;
4588 }
4589
Robert Carredd13602020-04-13 17:24:34 -07004590 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4591 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004592 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004593 oldHandle->updateFrom(handle);
4594 newHandles.push_back(oldHandle);
4595 } else {
4596 newHandles.push_back(handle);
4597 }
4598 }
4599
4600 // Insert or replace
4601 mWindowHandlesByDisplay[displayId] = newHandles;
4602}
4603
Arthur Hung72d8dc32020-03-28 00:48:39 +00004604void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004605 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004606 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004607 { // acquire lock
4608 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004609 for (const auto& [displayId, handles] : handlesPerDisplay) {
4610 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004611 }
4612 }
4613 // Wake up poll loop since it may need to make new input dispatching choices.
4614 mLooper->wake();
4615}
4616
Arthur Hungb92218b2018-08-14 12:00:21 +08004617/**
4618 * Called from InputManagerService, update window handle list by displayId that can receive input.
4619 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4620 * If set an empty list, remove all handles from the specific display.
4621 * For focused handle, check if need to change and send a cancel event to previous one.
4622 * For removed handle, check if need to send a cancel event if already in touch.
4623 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004624void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004625 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004626 if (DEBUG_FOCUS) {
4627 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004628 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004629 windowList += iwh->getName() + " ";
4630 }
4631 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4632 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004633
Prabir Pradhand65552b2021-10-07 11:23:50 -07004634 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05004635 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07004636 const WindowInfo& info = *window->getInfo();
4637
4638 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4639 const bool noInputWindow = info.inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004640 if (noInputWindow && window->getToken() != nullptr) {
4641 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4642 window->getName().c_str());
4643 window->releaseChannel();
4644 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07004645
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004646 // Ensure all spy windows are trusted overlays
4647 LOG_ALWAYS_FATAL_IF(info.isSpy() && !info.trustedOverlay,
4648 "%s has feature SPY, but is not a trusted overlay.",
4649 window->getName().c_str());
4650
Prabir Pradhand65552b2021-10-07 11:23:50 -07004651 // Ensure all stylus interceptors are trusted overlays
4652 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() && !info.trustedOverlay,
4653 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
4654 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004655 }
4656
Arthur Hung72d8dc32020-03-28 00:48:39 +00004657 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004658 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004659
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004660 // Save the old windows' orientation by ID before it gets updated.
4661 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004662 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004663 oldWindowOrientations.emplace(handle->getId(),
4664 handle->getInfo()->transform.getOrientation());
4665 }
4666
chaviw98318de2021-05-19 16:45:23 -05004667 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004668
chaviw98318de2021-05-19 16:45:23 -05004669 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004670 if (mLastHoverWindowHandle &&
4671 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4672 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004673 mLastHoverWindowHandle = nullptr;
4674 }
4675
Vishnu Nairc519ff72021-01-21 08:23:08 -08004676 std::optional<FocusResolver::FocusChanges> changes =
4677 mFocusResolver.setInputWindows(displayId, windowHandles);
4678 if (changes) {
4679 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004680 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004681
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004682 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4683 mTouchStatesByDisplay.find(displayId);
4684 if (stateIt != mTouchStatesByDisplay.end()) {
4685 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004686 for (size_t i = 0; i < state.windows.size();) {
4687 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004688 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004689 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004690 ALOGD("Touched window was removed: %s in display %" PRId32,
4691 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004692 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004693 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004694 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4695 if (touchedInputChannel != nullptr) {
4696 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4697 "touched window was removed");
4698 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004699 // Since we are about to drop the touch, cancel the events for the wallpaper as
4700 // well.
4701 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4702 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4703 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4704 if (wallpaper != nullptr) {
4705 sp<Connection> wallpaperConnection =
4706 getConnectionLocked(wallpaper->getToken());
Siarhei Vishniakou2b030972021-11-18 10:01:27 -08004707 if (wallpaperConnection != nullptr) {
4708 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4709 options);
4710 }
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004711 }
4712 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004713 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004714 state.windows.erase(state.windows.begin() + i);
4715 } else {
4716 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004717 }
4718 }
arthurhungb89ccb02020-12-30 16:19:01 +08004719
arthurhung6d4bed92021-03-17 11:59:33 +08004720 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004721 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004722 if (mDragState &&
4723 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004724 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004725 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004726 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004727 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004728
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00004729 // Determine if the orientation of any of the input windows have changed, and cancel all
4730 // pointer events if necessary.
4731 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4732 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
4733 if (newWindowHandle != nullptr &&
4734 newWindowHandle->getInfo()->transform.getOrientation() !=
4735 oldWindowOrientations[oldWindowHandle->getId()]) {
4736 std::shared_ptr<InputChannel> inputChannel =
4737 getInputChannelLocked(newWindowHandle->getToken());
4738 if (inputChannel != nullptr) {
4739 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4740 "touched window's orientation changed");
4741 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004742 }
4743 }
4744 }
4745
Arthur Hung72d8dc32020-03-28 00:48:39 +00004746 // Release information for windows that are no longer present.
4747 // This ensures that unused input channels are released promptly.
4748 // Otherwise, they might stick around until the window handle is destroyed
4749 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004750 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004751 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004752 if (DEBUG_FOCUS) {
4753 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004754 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004755 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00004756 }
chaviw291d88a2019-02-14 10:33:58 -08004757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004758}
4759
4760void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004761 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004762 if (DEBUG_FOCUS) {
4763 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4764 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4765 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004766 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004767 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004768 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004769 } // release lock
4770
4771 // Wake up poll loop since it may need to make new input dispatching choices.
4772 mLooper->wake();
4773}
4774
Vishnu Nair599f1412021-06-21 10:39:58 -07004775void InputDispatcher::setFocusedApplicationLocked(
4776 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4777 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4778 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4779
4780 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4781 return; // This application is already focused. No need to wake up or change anything.
4782 }
4783
4784 // Set the new application handle.
4785 if (inputApplicationHandle != nullptr) {
4786 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4787 } else {
4788 mFocusedApplicationHandlesByDisplay.erase(displayId);
4789 }
4790
4791 // No matter what the old focused application was, stop waiting on it because it is
4792 // no longer focused.
4793 resetNoFocusedWindowTimeoutLocked();
4794}
4795
Tiger Huang721e26f2018-07-24 22:26:19 +08004796/**
4797 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4798 * the display not specified.
4799 *
4800 * We track any unreleased events for each window. If a window loses the ability to receive the
4801 * released event, we will send a cancel event to it. So when the focused display is changed, we
4802 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4803 * display. The display-specified events won't be affected.
4804 */
4805void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004806 if (DEBUG_FOCUS) {
4807 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4808 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004809 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004810 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004811
4812 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004813 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004814 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004815 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004816 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004817 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004818 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004819 CancelationOptions
4820 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4821 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004822 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004823 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4824 }
4825 }
4826 mFocusedDisplayId = displayId;
4827
Chris Ye3c2d6f52020-08-09 10:39:48 -07004828 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004829 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004830 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004831
Vishnu Nairad321cd2020-08-20 16:40:21 -07004832 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004833 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004834 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004835 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004836 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004837 }
4838 }
4839 }
4840
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004841 if (DEBUG_FOCUS) {
4842 logDispatchStateLocked();
4843 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004844 } // release lock
4845
4846 // Wake up poll loop since it may need to make new input dispatching choices.
4847 mLooper->wake();
4848}
4849
Michael Wrightd02c5b62014-02-10 15:10:22 -08004850void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004851 if (DEBUG_FOCUS) {
4852 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4853 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854
4855 bool changed;
4856 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004857 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004858
4859 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4860 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004861 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004862 }
4863
4864 if (mDispatchEnabled && !enabled) {
4865 resetAndDropEverythingLocked("dispatcher is being disabled");
4866 }
4867
4868 mDispatchEnabled = enabled;
4869 mDispatchFrozen = frozen;
4870 changed = true;
4871 } else {
4872 changed = false;
4873 }
4874
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004875 if (DEBUG_FOCUS) {
4876 logDispatchStateLocked();
4877 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004878 } // release lock
4879
4880 if (changed) {
4881 // Wake up poll loop since it may need to make new input dispatching choices.
4882 mLooper->wake();
4883 }
4884}
4885
4886void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004887 if (DEBUG_FOCUS) {
4888 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4889 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004890
4891 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004892 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004893
4894 if (mInputFilterEnabled == enabled) {
4895 return;
4896 }
4897
4898 mInputFilterEnabled = enabled;
4899 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4900 } // release lock
4901
4902 // Wake up poll loop since there might be work to do to drop everything.
4903 mLooper->wake();
4904}
4905
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004906void InputDispatcher::setInTouchMode(bool inTouchMode) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00004907 bool needWake = false;
4908 {
4909 std::scoped_lock lock(mLock);
4910 if (mInTouchMode == inTouchMode) {
4911 return;
4912 }
4913 if (DEBUG_TOUCH_MODE) {
4914 ALOGD("Request to change touch mode from %s to %s", toString(mInTouchMode),
4915 toString(inTouchMode));
4916 // TODO(b/198487159): Also print the current last interacted apps.
4917 }
4918
4919 // TODO(b/198499018): Store touch mode per display.
4920 mInTouchMode = inTouchMode;
4921
4922 // TODO(b/198487159): Enforce that only last interacted apps can change touch mode.
4923 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode);
4924 needWake = enqueueInboundEventLocked(std::move(entry));
4925 } // release lock
4926
4927 if (needWake) {
4928 mLooper->wake();
4929 }
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004930}
4931
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004932void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4933 if (opacity < 0 || opacity > 1) {
4934 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4935 return;
4936 }
4937
4938 std::scoped_lock lock(mLock);
4939 mMaximumObscuringOpacityForTouch = opacity;
4940}
4941
4942void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4943 std::scoped_lock lock(mLock);
4944 mBlockUntrustedTouchesMode = mode;
4945}
4946
Arthur Hungabbb9d82021-09-01 14:52:30 +00004947std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
4948 const sp<IBinder>& token) {
4949 for (auto& [displayId, state] : mTouchStatesByDisplay) {
4950 for (TouchedWindow& w : state.windows) {
4951 if (w.windowHandle->getToken() == token) {
4952 return std::make_pair(&state, &w);
4953 }
4954 }
4955 }
4956 return std::make_pair(nullptr, nullptr);
4957}
4958
arthurhungb89ccb02020-12-30 16:19:01 +08004959bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4960 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004961 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004962 if (DEBUG_FOCUS) {
4963 ALOGD("Trivial transfer to same window.");
4964 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004965 return true;
4966 }
4967
Michael Wrightd02c5b62014-02-10 15:10:22 -08004968 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004969 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004970
Arthur Hungabbb9d82021-09-01 14:52:30 +00004971 // Find the target touch state and touched window by fromToken.
4972 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
4973 if (state == nullptr || touchedWindow == nullptr) {
4974 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004975 return false;
4976 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00004977
4978 const int32_t displayId = state->displayId;
4979 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
4980 if (toWindowHandle == nullptr) {
4981 ALOGW("Cannot transfer focus because to window not found.");
4982 return false;
4983 }
4984
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004985 if (DEBUG_FOCUS) {
4986 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00004987 touchedWindow->windowHandle->getName().c_str(),
4988 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004989 }
4990
Arthur Hungabbb9d82021-09-01 14:52:30 +00004991 // Erase old window.
4992 int32_t oldTargetFlags = touchedWindow->targetFlags;
4993 BitSet32 pointerIds = touchedWindow->pointerIds;
4994 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004995
Arthur Hungabbb9d82021-09-01 14:52:30 +00004996 // Add new window.
4997 int32_t newTargetFlags = oldTargetFlags &
4998 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4999 InputTarget::FLAG_DISPATCH_AS_IS);
5000 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005001
Arthur Hungabbb9d82021-09-01 14:52:30 +00005002 // Store the dragging window.
5003 if (isDragDrop) {
5004 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005 }
5006
Arthur Hungabbb9d82021-09-01 14:52:30 +00005007 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005008 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5009 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005010 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005011 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005012 CancelationOptions
5013 options(CancelationOptions::CANCEL_POINTER_EVENTS,
5014 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005015 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005016 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005017 }
5018
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005019 if (DEBUG_FOCUS) {
5020 logDispatchStateLocked();
5021 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005022 } // release lock
5023
5024 // Wake up poll loop since it may need to make new input dispatching choices.
5025 mLooper->wake();
5026 return true;
5027}
5028
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005029// Binder call
5030bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5031 sp<IBinder> fromToken;
5032 { // acquire lock
5033 std::scoped_lock _l(mLock);
5034
Arthur Hungabbb9d82021-09-01 14:52:30 +00005035 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5036 [](const auto& pair) { return pair.second.windows.size() == 1; });
5037 if (it == mTouchStatesByDisplay.end()) {
5038 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5039 return false;
5040 }
5041 const int32_t displayId = it->first;
5042 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005043 if (toWindowHandle == nullptr) {
5044 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5045 return false;
5046 }
5047
Arthur Hungabbb9d82021-09-01 14:52:30 +00005048 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005049 const TouchedWindow& touchedWindow = state.windows[0];
5050 fromToken = touchedWindow.windowHandle->getToken();
5051 } // release lock
5052
5053 return transferTouchFocus(fromToken, destChannelToken);
5054}
5055
Michael Wrightd02c5b62014-02-10 15:10:22 -08005056void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005057 if (DEBUG_FOCUS) {
5058 ALOGD("Resetting and dropping all events (%s).", reason);
5059 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005060
5061 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5062 synthesizeCancelationEventsForAllConnectionsLocked(options);
5063
5064 resetKeyRepeatLocked();
5065 releasePendingEventLocked();
5066 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005067 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005068
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005069 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005070 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005071 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005072 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005073}
5074
5075void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005076 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077 dumpDispatchStateLocked(dump);
5078
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005079 std::istringstream stream(dump);
5080 std::string line;
5081
5082 while (std::getline(stream, line, '\n')) {
5083 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005084 }
5085}
5086
Prabir Pradhan99987712020-11-10 18:43:05 -08005087std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5088 std::string dump;
5089
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005090 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5091 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005092
5093 std::string windowName = "None";
5094 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005095 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005096 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5097 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5098 : "token has capture without window";
5099 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005100 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005101
5102 return dump;
5103}
5104
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005105void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005106 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5107 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5108 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005109 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005110
Tiger Huang721e26f2018-07-24 22:26:19 +08005111 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5112 dump += StringPrintf(INDENT "FocusedApplications:\n");
5113 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5114 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005115 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005116 const std::chrono::duration timeout =
5117 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005118 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005119 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005120 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005121 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005122 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005123 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005124 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005125
Vishnu Nairc519ff72021-01-21 08:23:08 -08005126 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005127 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005128
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005129 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005130 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005131 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5132 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005133 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005134 state.displayId, toString(state.down), toString(state.split),
5135 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005136 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005137 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005138 for (size_t i = 0; i < state.windows.size(); i++) {
5139 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005140 dump += StringPrintf(INDENT4
5141 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5142 i, touchedWindow.windowHandle->getName().c_str(),
5143 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005144 }
5145 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005146 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005147 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005148 }
5149 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005150 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005151 }
5152
arthurhung6d4bed92021-03-17 11:59:33 +08005153 if (mDragState) {
5154 dump += StringPrintf(INDENT "DragState:\n");
5155 mDragState->dump(dump, INDENT2);
5156 }
5157
Arthur Hungb92218b2018-08-14 12:00:21 +08005158 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005159 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5160 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5161 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5162 const auto& displayInfo = it->second;
5163 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5164 displayInfo.logicalHeight);
5165 displayInfo.transform.dump(dump, "transform", INDENT4);
5166 } else {
5167 dump += INDENT2 "No DisplayInfo found!\n";
5168 }
5169
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005170 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005171 dump += INDENT2 "Windows:\n";
5172 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005173 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5174 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005175
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005176 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005177 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005178 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005179 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005180 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005181 "applicationInfo.name=%s, "
5182 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005183 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005184 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005185 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005186 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005187 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005188 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005189 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005190 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005191 windowInfo->frameLeft, windowInfo->frameTop,
5192 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005193 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005194 windowInfo->applicationInfo.name.c_str(),
5195 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005196 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005197 dump += StringPrintf(", inputFeatures=%s",
5198 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005199 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005200 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005201 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005202 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005203 millis(windowInfo->dispatchingTimeout),
5204 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005205 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005206 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005207 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005208 }
5209 } else {
5210 dump += INDENT2 "Windows: <none>\n";
5211 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005212 }
5213 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005214 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005215 }
5216
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005217 if (!mGlobalMonitorsByDisplay.empty()) {
5218 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5219 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005220 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005221 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005222 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005223 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005224 }
5225
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005226 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005227
5228 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005229 if (!mRecentQueue.empty()) {
5230 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005231 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005232 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005233 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005234 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005235 }
5236 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005237 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238 }
5239
5240 // Dump event currently being dispatched.
5241 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005242 dump += INDENT "PendingEvent:\n";
5243 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005244 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005245 dump += StringPrintf(", age=%" PRId64 "ms\n",
5246 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005247 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005248 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005249 }
5250
5251 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005252 if (!mInboundQueue.empty()) {
5253 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005254 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005255 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005256 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005257 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005258 }
5259 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005260 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005261 }
5262
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005263 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005264 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005265 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5266 const KeyReplacement& replacement = pair.first;
5267 int32_t newKeyCode = pair.second;
5268 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005269 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005270 }
5271 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005272 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005273 }
5274
Prabir Pradhancef936d2021-07-21 16:17:52 +00005275 if (!mCommandQueue.empty()) {
5276 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5277 } else {
5278 dump += INDENT "CommandQueue: <empty>\n";
5279 }
5280
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005281 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005282 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005283 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005284 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005285 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005286 connection->inputChannel->getFd().get(),
5287 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005288 connection->getWindowName().c_str(),
5289 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005290 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005291
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005292 if (!connection->outboundQueue.empty()) {
5293 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5294 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005295 dump += dumpQueue(connection->outboundQueue, currentTime);
5296
Michael Wrightd02c5b62014-02-10 15:10:22 -08005297 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005298 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005299 }
5300
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005301 if (!connection->waitQueue.empty()) {
5302 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5303 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005304 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005305 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005306 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005307 }
5308 }
5309 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005310 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005311 }
5312
5313 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005314 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5315 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005316 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005317 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005318 }
5319
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005320 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005321 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5322 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5323 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005324 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005325 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005326}
5327
Michael Wright3dd60e22019-03-27 22:06:44 +00005328void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5329 const size_t numMonitors = monitors.size();
5330 for (size_t i = 0; i < numMonitors; i++) {
5331 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005332 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005333 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5334 dump += "\n";
5335 }
5336}
5337
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005338class LooperEventCallback : public LooperCallback {
5339public:
5340 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5341 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5342
5343private:
5344 std::function<int(int events)> mCallback;
5345};
5346
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005347Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005348 if (DEBUG_CHANNEL_CREATION) {
5349 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5350 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005351
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005352 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005353 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005354 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005355
5356 if (result) {
5357 return base::Error(result) << "Failed to open input channel pair with name " << name;
5358 }
5359
Michael Wrightd02c5b62014-02-10 15:10:22 -08005360 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005361 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005362 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005363 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005364 sp<Connection> connection =
5365 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005366
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005367 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5368 ALOGE("Created a new connection, but the token %p is already known", token.get());
5369 }
5370 mConnectionsByToken.emplace(token, connection);
5371
5372 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5373 this, std::placeholders::_1, token);
5374
5375 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005376 } // release lock
5377
5378 // Wake the looper because some connections have changed.
5379 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005380 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005381}
5382
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005383Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005384 const std::string& name,
5385 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005386 std::shared_ptr<InputChannel> serverChannel;
5387 std::unique_ptr<InputChannel> clientChannel;
5388 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5389 if (result) {
5390 return base::Error(result) << "Failed to open input channel pair with name " << name;
5391 }
5392
Michael Wright3dd60e22019-03-27 22:06:44 +00005393 { // acquire lock
5394 std::scoped_lock _l(mLock);
5395
5396 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005397 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5398 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005399 }
5400
Garfield Tan15601662020-09-22 15:32:38 -07005401 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005402 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005403 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005404
5405 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5406 ALOGE("Created a new connection, but the token %p is already known", token.get());
5407 }
5408 mConnectionsByToken.emplace(token, connection);
5409 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5410 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005411
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005412 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005413
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005414 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005415 }
Garfield Tan15601662020-09-22 15:32:38 -07005416
Michael Wright3dd60e22019-03-27 22:06:44 +00005417 // Wake the looper because some connections have changed.
5418 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005419 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005420}
5421
Garfield Tan15601662020-09-22 15:32:38 -07005422status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005423 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005424 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005425
Garfield Tan15601662020-09-22 15:32:38 -07005426 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005427 if (status) {
5428 return status;
5429 }
5430 } // release lock
5431
5432 // Wake the poll loop because removing the connection may have changed the current
5433 // synchronization state.
5434 mLooper->wake();
5435 return OK;
5436}
5437
Garfield Tan15601662020-09-22 15:32:38 -07005438status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5439 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005440 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005441 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005442 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005443 return BAD_VALUE;
5444 }
5445
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005446 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005447
Michael Wrightd02c5b62014-02-10 15:10:22 -08005448 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005449 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005450 }
5451
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005452 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005453
5454 nsecs_t currentTime = now();
5455 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5456
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005457 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005458 return OK;
5459}
5460
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005461void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005462 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5463 auto& [displayId, monitors] = *it;
5464 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5465 return monitor.inputChannel->getConnectionToken() == connectionToken;
5466 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005467
Michael Wright3dd60e22019-03-27 22:06:44 +00005468 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005469 it = mGlobalMonitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005470 } else {
5471 ++it;
5472 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005473 }
5474}
5475
Michael Wright3dd60e22019-03-27 22:06:44 +00005476status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005477 std::scoped_lock _l(mLock);
Michael Wright3dd60e22019-03-27 22:06:44 +00005478
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005479 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5480 if (!requestingChannel) {
5481 ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
5482 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00005483 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005484
5485 auto [statePtr, windowPtr] = findTouchStateAndWindowLocked(token);
5486 if (statePtr == nullptr || windowPtr == nullptr || !statePtr->down) {
5487 ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
5488 " Ignoring.");
5489 return BAD_VALUE;
5490 }
5491
5492 TouchState& state = *statePtr;
5493
5494 // Send cancel events to all the input channels we're stealing from.
5495 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
5496 "input channel stole pointer stream");
5497 options.deviceId = state.deviceId;
5498 options.displayId = state.displayId;
5499 std::string canceledWindows;
5500 for (const TouchedWindow& window : state.windows) {
5501 const std::shared_ptr<InputChannel> channel =
5502 getInputChannelLocked(window.windowHandle->getToken());
5503 if (channel != nullptr && channel->getConnectionToken() != token) {
5504 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5505 canceledWindows += canceledWindows.empty() ? "[" : ", ";
5506 canceledWindows += channel->getName();
5507 }
5508 }
5509 canceledWindows += canceledWindows.empty() ? "[]" : "]";
5510 ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(),
5511 canceledWindows.c_str());
5512
5513 // Then clear the current touch state so we stop dispatching to them as well.
5514 state.split = false;
5515 state.filterWindowsExcept(token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005516 return OK;
5517}
5518
Prabir Pradhan99987712020-11-10 18:43:05 -08005519void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5520 { // acquire lock
5521 std::scoped_lock _l(mLock);
5522 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005523 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005524 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5525 windowHandle != nullptr ? windowHandle->getName().c_str()
5526 : "token without window");
5527 }
5528
Vishnu Nairc519ff72021-01-21 08:23:08 -08005529 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005530 if (focusedToken != windowToken) {
5531 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5532 enabled ? "enable" : "disable");
5533 return;
5534 }
5535
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005536 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005537 ALOGW("Ignoring request to %s Pointer Capture: "
5538 "window has %s requested pointer capture.",
5539 enabled ? "enable" : "disable", enabled ? "already" : "not");
5540 return;
5541 }
5542
Christine Franksb768bb42021-11-29 12:11:31 -08005543 if (enabled) {
5544 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
5545 mIneligibleDisplaysForPointerCapture.end(),
5546 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
5547 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
5548 return;
5549 }
5550 }
5551
Prabir Pradhan99987712020-11-10 18:43:05 -08005552 setPointerCaptureLocked(enabled);
5553 } // release lock
5554
5555 // Wake the thread to process command entries.
5556 mLooper->wake();
5557}
5558
Christine Franksb768bb42021-11-29 12:11:31 -08005559void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
5560 { // acquire lock
5561 std::scoped_lock _l(mLock);
5562 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
5563 if (!isEligible) {
5564 mIneligibleDisplaysForPointerCapture.push_back(displayId);
5565 }
5566 } // release lock
5567}
5568
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005569std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5570 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005571 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005572 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005573 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00005574 }
5575 }
5576 }
5577 return std::nullopt;
5578}
5579
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005580sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005581 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005582 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005583 }
5584
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005585 for (const auto& [token, connection] : mConnectionsByToken) {
5586 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005587 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005588 }
5589 }
Robert Carr4e670e52018-08-15 13:26:12 -07005590
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005591 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005592}
5593
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005594std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5595 sp<Connection> connection = getConnectionLocked(connectionToken);
5596 if (connection == nullptr) {
5597 return "<nullptr>";
5598 }
5599 return connection->getInputChannelName();
5600}
5601
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005602void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005603 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005604 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005605}
5606
Prabir Pradhancef936d2021-07-21 16:17:52 +00005607void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5608 const sp<Connection>& connection, uint32_t seq,
5609 bool handled, nsecs_t consumeTime) {
5610 // Handle post-event policy actions.
5611 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5612 if (dispatchEntryIt == connection->waitQueue.end()) {
5613 return;
5614 }
5615 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5616 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5617 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5618 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5619 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5620 }
5621 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5622 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5623 connection->inputChannel->getConnectionToken(),
5624 dispatchEntry->deliveryTime, consumeTime, finishTime);
5625 }
5626
5627 bool restartEvent;
5628 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5629 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5630 restartEvent =
5631 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5632 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5633 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5634 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5635 handled);
5636 } else {
5637 restartEvent = false;
5638 }
5639
5640 // Dequeue the event and start the next cycle.
5641 // Because the lock might have been released, it is possible that the
5642 // contents of the wait queue to have been drained, so we need to double-check
5643 // a few things.
5644 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5645 if (dispatchEntryIt != connection->waitQueue.end()) {
5646 dispatchEntry = *dispatchEntryIt;
5647 connection->waitQueue.erase(dispatchEntryIt);
5648 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5649 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5650 if (!connection->responsive) {
5651 connection->responsive = isConnectionResponsive(*connection);
5652 if (connection->responsive) {
5653 // The connection was unresponsive, and now it's responsive.
5654 processConnectionResponsiveLocked(*connection);
5655 }
5656 }
5657 traceWaitQueueLength(*connection);
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005658 if (restartEvent && connection->status == Connection::Status::NORMAL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005659 connection->outboundQueue.push_front(dispatchEntry);
5660 traceOutboundQueueLength(*connection);
5661 } else {
5662 releaseDispatchEntry(dispatchEntry);
5663 }
5664 }
5665
5666 // Start the next dispatch cycle for this connection.
5667 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005668}
5669
Prabir Pradhancef936d2021-07-21 16:17:52 +00005670void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5671 const sp<IBinder>& newToken) {
5672 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5673 scoped_unlock unlock(mLock);
5674 mPolicy->notifyFocusChanged(oldToken, newToken);
5675 };
5676 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005677}
5678
Prabir Pradhancef936d2021-07-21 16:17:52 +00005679void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5680 auto command = [this, token, x, y]() REQUIRES(mLock) {
5681 scoped_unlock unlock(mLock);
5682 mPolicy->notifyDropWindow(token, x, y);
5683 };
5684 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005685}
5686
Prabir Pradhancef936d2021-07-21 16:17:52 +00005687void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5688 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5689 scoped_unlock unlock(mLock);
5690 mPolicy->notifyUntrustedTouch(obscuringPackage);
5691 };
5692 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005693}
5694
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005695void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5696 if (connection == nullptr) {
5697 LOG_ALWAYS_FATAL("Caller must check for nullness");
5698 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005699 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5700 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005701 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005702 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005703 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005704 return;
5705 }
5706 /**
5707 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5708 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5709 * has changed. This could cause newer entries to time out before the already dispatched
5710 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5711 * processes the events linearly. So providing information about the oldest entry seems to be
5712 * most useful.
5713 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005714 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005715 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5716 std::string reason =
5717 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005718 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005719 ns2ms(currentWait),
5720 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005721 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005722 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005723
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005724 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5725
5726 // Stop waking up for events on this connection, it is already unresponsive
5727 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005728}
5729
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005730void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5731 std::string reason =
5732 StringPrintf("%s does not have a focused window", application->getName().c_str());
5733 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005734
Prabir Pradhancef936d2021-07-21 16:17:52 +00005735 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5736 scoped_unlock unlock(mLock);
5737 mPolicy->notifyNoFocusedWindowAnr(application);
5738 };
5739 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005740}
5741
chaviw98318de2021-05-19 16:45:23 -05005742void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005743 const std::string& reason) {
5744 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5745 updateLastAnrStateLocked(windowLabel, reason);
5746}
5747
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005748void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5749 const std::string& reason) {
5750 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005751 updateLastAnrStateLocked(windowLabel, reason);
5752}
5753
5754void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5755 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005756 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005757 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005758 struct tm tm;
5759 localtime_r(&t, &tm);
5760 char timestr[64];
5761 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005762 mLastAnrState.clear();
5763 mLastAnrState += INDENT "ANR:\n";
5764 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005765 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5766 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005767 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005768}
5769
Prabir Pradhancef936d2021-07-21 16:17:52 +00005770void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5771 KeyEntry& entry) {
5772 const KeyEvent event = createKeyEvent(entry);
5773 nsecs_t delay = 0;
5774 { // release lock
5775 scoped_unlock unlock(mLock);
5776 android::base::Timer t;
5777 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5778 entry.policyFlags);
5779 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5780 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5781 std::to_string(t.duration().count()).c_str());
5782 }
5783 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005784
5785 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005786 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005787 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005788 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005789 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005790 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5791 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005792 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005793}
5794
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005795void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005796 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5797 scoped_unlock unlock(mLock);
5798 mPolicy->notifyMonitorUnresponsive(pid, reason);
5799 };
5800 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005801}
5802
Prabir Pradhancef936d2021-07-21 16:17:52 +00005803void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005804 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005805 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5806 scoped_unlock unlock(mLock);
5807 mPolicy->notifyWindowUnresponsive(token, reason);
5808 };
5809 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005810}
5811
5812void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005813 auto command = [this, pid]() REQUIRES(mLock) {
5814 scoped_unlock unlock(mLock);
5815 mPolicy->notifyMonitorResponsive(pid);
5816 };
5817 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005818}
5819
Prabir Pradhancef936d2021-07-21 16:17:52 +00005820void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5821 auto command = [this, connectionToken]() REQUIRES(mLock) {
5822 scoped_unlock unlock(mLock);
5823 mPolicy->notifyWindowResponsive(connectionToken);
5824 };
5825 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005826}
5827
5828/**
5829 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5830 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5831 * command entry to the command queue.
5832 */
5833void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5834 std::string reason) {
5835 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5836 if (connection.monitor) {
5837 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5838 reason.c_str());
5839 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5840 if (!pid.has_value()) {
5841 ALOGE("Could not find unresponsive monitor for connection %s",
5842 connection.inputChannel->getName().c_str());
5843 return;
5844 }
5845 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5846 return;
5847 }
5848 // If not a monitor, must be a window
5849 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5850 reason.c_str());
5851 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5852}
5853
5854/**
5855 * Tell the policy that a connection has become responsive so that it can stop ANR.
5856 */
5857void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5858 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5859 if (connection.monitor) {
5860 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5861 if (!pid.has_value()) {
5862 ALOGE("Could not find responsive monitor for connection %s",
5863 connection.inputChannel->getName().c_str());
5864 return;
5865 }
5866 sendMonitorResponsiveCommandLocked(pid.value());
5867 return;
5868 }
5869 // If not a monitor, must be a window
5870 sendWindowResponsiveCommandLocked(connectionToken);
5871}
5872
Prabir Pradhancef936d2021-07-21 16:17:52 +00005873bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005874 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005875 KeyEntry& keyEntry, bool handled) {
5876 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005877 if (!handled) {
5878 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005879 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005880 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005881 return false;
5882 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005883
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005884 // Get the fallback key state.
5885 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005886 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005887 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005888 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005889 connection->inputState.removeFallbackKey(originalKeyCode);
5890 }
5891
5892 if (handled || !dispatchEntry->hasForegroundTarget()) {
5893 // If the application handles the original key for which we previously
5894 // generated a fallback or if the window is not a foreground window,
5895 // then cancel the associated fallback key, if any.
5896 if (fallbackKeyCode != -1) {
5897 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005898 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5899 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5900 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5901 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5902 keyEntry.policyFlags);
5903 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005904 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005905 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005906
5907 mLock.unlock();
5908
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005909 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005910 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005911
5912 mLock.lock();
5913
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005914 // Cancel the fallback key.
5915 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005916 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005917 "application handled the original non-fallback key "
5918 "or is no longer a foreground target, "
5919 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005920 options.keyCode = fallbackKeyCode;
5921 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005922 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005923 connection->inputState.removeFallbackKey(originalKeyCode);
5924 }
5925 } else {
5926 // If the application did not handle a non-fallback key, first check
5927 // that we are in a good state to perform unhandled key event processing
5928 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005929 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005930 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005931 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5932 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5933 "since this is not an initial down. "
5934 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5935 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5936 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005937 return false;
5938 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005939
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005940 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005941 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5942 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5943 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5944 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5945 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005946 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005947
5948 mLock.unlock();
5949
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005950 bool fallback =
5951 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005952 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005953
5954 mLock.lock();
5955
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005956 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005957 connection->inputState.removeFallbackKey(originalKeyCode);
5958 return false;
5959 }
5960
5961 // Latch the fallback keycode for this key on an initial down.
5962 // The fallback keycode cannot change at any other point in the lifecycle.
5963 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005964 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005965 fallbackKeyCode = event.getKeyCode();
5966 } else {
5967 fallbackKeyCode = AKEYCODE_UNKNOWN;
5968 }
5969 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5970 }
5971
5972 ALOG_ASSERT(fallbackKeyCode != -1);
5973
5974 // Cancel the fallback key if the policy decides not to send it anymore.
5975 // We will continue to dispatch the key to the policy but we will no
5976 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005977 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5978 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005979 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5980 if (fallback) {
5981 ALOGD("Unhandled key event: Policy requested to send key %d"
5982 "as a fallback for %d, but on the DOWN it had requested "
5983 "to send %d instead. Fallback canceled.",
5984 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
5985 } else {
5986 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
5987 "but on the DOWN it had requested to send %d. "
5988 "Fallback canceled.",
5989 originalKeyCode, fallbackKeyCode);
5990 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005991 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005992
5993 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5994 "canceling fallback, policy no longer desires it");
5995 options.keyCode = fallbackKeyCode;
5996 synthesizeCancelationEventsForConnectionLocked(connection, options);
5997
5998 fallback = false;
5999 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006000 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006001 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006002 }
6003 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006004
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006005 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6006 {
6007 std::string msg;
6008 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6009 connection->inputState.getFallbackKeys();
6010 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6011 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6012 }
6013 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6014 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006015 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006016 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006017
6018 if (fallback) {
6019 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006020 keyEntry.eventTime = event.getEventTime();
6021 keyEntry.deviceId = event.getDeviceId();
6022 keyEntry.source = event.getSource();
6023 keyEntry.displayId = event.getDisplayId();
6024 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6025 keyEntry.keyCode = fallbackKeyCode;
6026 keyEntry.scanCode = event.getScanCode();
6027 keyEntry.metaState = event.getMetaState();
6028 keyEntry.repeatCount = event.getRepeatCount();
6029 keyEntry.downTime = event.getDownTime();
6030 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006031
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006032 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6033 ALOGD("Unhandled key event: Dispatching fallback key. "
6034 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6035 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6036 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006037 return true; // restart the event
6038 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006039 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6040 ALOGD("Unhandled key event: No fallback key.");
6041 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006042
6043 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006044 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006045 }
6046 }
6047 return false;
6048}
6049
Prabir Pradhancef936d2021-07-21 16:17:52 +00006050bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006051 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006052 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006053 return false;
6054}
6055
Michael Wrightd02c5b62014-02-10 15:10:22 -08006056void InputDispatcher::traceInboundQueueLengthLocked() {
6057 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006058 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006059 }
6060}
6061
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006062void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006063 if (ATRACE_ENABLED()) {
6064 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006065 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6066 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006067 }
6068}
6069
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006070void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006071 if (ATRACE_ENABLED()) {
6072 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006073 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6074 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006075 }
6076}
6077
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006078void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006079 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006080
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006081 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006082 dumpDispatchStateLocked(dump);
6083
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006084 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006085 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006086 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006087 }
6088}
6089
6090void InputDispatcher::monitor() {
6091 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006092 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006093 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006094 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006095}
6096
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006097/**
6098 * Wake up the dispatcher and wait until it processes all events and commands.
6099 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6100 * this method can be safely called from any thread, as long as you've ensured that
6101 * the work you are interested in completing has already been queued.
6102 */
6103bool InputDispatcher::waitForIdle() {
6104 /**
6105 * Timeout should represent the longest possible time that a device might spend processing
6106 * events and commands.
6107 */
6108 constexpr std::chrono::duration TIMEOUT = 100ms;
6109 std::unique_lock lock(mLock);
6110 mLooper->wake();
6111 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6112 return result == std::cv_status::no_timeout;
6113}
6114
Vishnu Naire798b472020-07-23 13:52:21 -07006115/**
6116 * Sets focus to the window identified by the token. This must be called
6117 * after updating any input window handles.
6118 *
6119 * Params:
6120 * request.token - input channel token used to identify the window that should gain focus.
6121 * request.focusedToken - the token that the caller expects currently to be focused. If the
6122 * specified token does not match the currently focused window, this request will be dropped.
6123 * If the specified focused token matches the currently focused window, the call will succeed.
6124 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6125 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6126 * when requesting the focus change. This determines which request gets
6127 * precedence if there is a focus change request from another source such as pointer down.
6128 */
Vishnu Nair958da932020-08-21 17:12:37 -07006129void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6130 { // acquire lock
6131 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006132 std::optional<FocusResolver::FocusChanges> changes =
6133 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6134 if (changes) {
6135 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006136 }
6137 } // release lock
6138 // Wake up poll loop since it may need to make new input dispatching choices.
6139 mLooper->wake();
6140}
6141
Vishnu Nairc519ff72021-01-21 08:23:08 -08006142void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6143 if (changes.oldFocus) {
6144 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006145 if (focusedInputChannel) {
6146 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6147 "focus left window");
6148 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006149 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006150 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006151 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006152 if (changes.newFocus) {
6153 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006154 }
6155
Prabir Pradhan99987712020-11-10 18:43:05 -08006156 // If a window has pointer capture, then it must have focus. We need to ensure that this
6157 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6158 // If the window loses focus before it loses pointer capture, then the window can be in a state
6159 // where it has pointer capture but not focus, violating the contract. Therefore we must
6160 // dispatch the pointer capture event before the focus event. Since focus events are added to
6161 // the front of the queue (above), we add the pointer capture event to the front of the queue
6162 // after the focus events are added. This ensures the pointer capture event ends up at the
6163 // front.
6164 disablePointerCaptureForcedLocked();
6165
Vishnu Nairc519ff72021-01-21 08:23:08 -08006166 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006167 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006168 }
6169}
Vishnu Nair958da932020-08-21 17:12:37 -07006170
Prabir Pradhan99987712020-11-10 18:43:05 -08006171void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006172 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006173 return;
6174 }
6175
6176 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6177
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006178 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006179 setPointerCaptureLocked(false);
6180 }
6181
6182 if (!mWindowTokenWithPointerCapture) {
6183 // No need to send capture changes because no window has capture.
6184 return;
6185 }
6186
6187 if (mPendingEvent != nullptr) {
6188 // Move the pending event to the front of the queue. This will give the chance
6189 // for the pending event to be dropped if it is a captured event.
6190 mInboundQueue.push_front(mPendingEvent);
6191 mPendingEvent = nullptr;
6192 }
6193
6194 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006195 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006196 mInboundQueue.push_front(std::move(entry));
6197}
6198
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006199void InputDispatcher::setPointerCaptureLocked(bool enable) {
6200 mCurrentPointerCaptureRequest.enable = enable;
6201 mCurrentPointerCaptureRequest.seq++;
6202 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006203 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006204 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006205 };
6206 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006207}
6208
Vishnu Nair599f1412021-06-21 10:39:58 -07006209void InputDispatcher::displayRemoved(int32_t displayId) {
6210 { // acquire lock
6211 std::scoped_lock _l(mLock);
6212 // Set an empty list to remove all handles from the specific display.
6213 setInputWindowsLocked(/* window handles */ {}, displayId);
6214 setFocusedApplicationLocked(displayId, nullptr);
6215 // Call focus resolver to clean up stale requests. This must be called after input windows
6216 // have been removed for the removed display.
6217 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006218 // Reset pointer capture eligibility, regardless of previous state.
6219 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006220 } // release lock
6221
6222 // Wake up poll loop since it may need to make new input dispatching choices.
6223 mLooper->wake();
6224}
6225
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006226void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6227 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006228 // The listener sends the windows as a flattened array. Separate the windows by display for
6229 // more convenient parsing.
6230 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006231 for (const auto& info : windowInfos) {
6232 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6233 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6234 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006235
6236 { // acquire lock
6237 std::scoped_lock _l(mLock);
6238 mDisplayInfos.clear();
6239 for (const auto& displayInfo : displayInfos) {
6240 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6241 }
6242
6243 for (const auto& [displayId, handles] : handlesPerDisplay) {
6244 setInputWindowsLocked(handles, displayId);
6245 }
6246 }
6247 // Wake up poll loop since it may need to make new input dispatching choices.
6248 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006249}
6250
Vishnu Nair062a8672021-09-03 16:07:44 -07006251bool InputDispatcher::shouldDropInput(
6252 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6253 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6254 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6255 isWindowObscuredLocked(windowHandle))) {
6256 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6257 "%" PRId32 ".",
6258 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6259 windowHandle->getInfo()->inputFeatures.string().c_str(),
6260 windowHandle->getInfo()->displayId);
6261 return true;
6262 }
6263 return false;
6264}
6265
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006266void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6267 const std::vector<gui::WindowInfo>& windowInfos,
6268 const std::vector<DisplayInfo>& displayInfos) {
6269 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6270}
6271
Arthur Hungdfd528e2021-12-08 13:23:04 +00006272void InputDispatcher::cancelCurrentTouch() {
6273 {
6274 std::scoped_lock _l(mLock);
6275 ALOGD("Canceling all ongoing pointer gestures on all displays.");
6276 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
6277 "cancel current touch");
6278 synthesizeCancelationEventsForAllConnectionsLocked(options);
6279
6280 mTouchStatesByDisplay.clear();
6281 mLastHoverWindowHandle.clear();
6282 }
6283 // Wake up poll loop since there might be work to do.
6284 mLooper->wake();
6285}
6286
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006287void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6288 std::scoped_lock _l(mLock);
6289 mMonitorDispatchingTimeout = timeout;
6290}
6291
Garfield Tane84e6f92019-08-29 17:28:41 -07006292} // namespace android::inputdispatcher