blob: 98a73d412c3145dc6c86de87e6b57198e815af4f [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>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100027#include <binder/IServiceManager.h>
28#include <com/android/internal/compat/IPlatformCompatNative.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080029#include <ftl/enum.h>
chaviw15fab6f2021-06-07 14:15:52 -050030#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080031#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070032#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000033#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070034#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010035#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070036#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080037
Michael Wright44753b12020-07-08 13:48:11 +010038#include <cerrno>
39#include <cinttypes>
40#include <climits>
41#include <cstddef>
42#include <ctime>
43#include <queue>
44#include <sstream>
45
46#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070047#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010048
Michael Wrightd02c5b62014-02-10 15:10:22 -080049#define INDENT " "
50#define INDENT2 " "
51#define INDENT3 " "
52#define INDENT4 " "
53
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080054using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000055using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080056using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070057using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050058using android::gui::FocusRequest;
59using android::gui::TouchOcclusionMode;
60using android::gui::WindowInfo;
61using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080062using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100063using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080064using android::os::InputEventInjectionResult;
65using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100066using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080067
Garfield Tane84e6f92019-08-29 17:28:41 -070068namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080069
Prabir Pradhancef936d2021-07-21 16:17:52 +000070namespace {
71
Prabir Pradhan61a5d242021-07-26 16:41:09 +000072// Log detailed debug messages about each inbound event notification to the dispatcher.
73constexpr bool DEBUG_INBOUND_EVENT_DETAILS = false;
74
75// Log detailed debug messages about each outbound event processed by the dispatcher.
76constexpr bool DEBUG_OUTBOUND_EVENT_DETAILS = false;
77
78// Log debug messages about the dispatch cycle.
79constexpr bool DEBUG_DISPATCH_CYCLE = false;
80
81// Log debug messages about channel creation
82constexpr bool DEBUG_CHANNEL_CREATION = false;
83
84// Log debug messages about input event injection.
85constexpr bool DEBUG_INJECTION = false;
86
87// Log debug messages about input focus tracking.
88constexpr bool DEBUG_FOCUS = false;
89
Antonio Kantekf16f2832021-09-28 04:39:20 +000090// Log debug messages about touch mode event
91constexpr bool DEBUG_TOUCH_MODE = false;
92
Prabir Pradhan61a5d242021-07-26 16:41:09 +000093// Log debug messages about touch occlusion
94// STOPSHIP(b/169067926): Set to false
95constexpr bool DEBUG_TOUCH_OCCLUSION = true;
96
97// Log debug messages about the app switch latency optimization.
98constexpr bool DEBUG_APP_SWITCH = false;
99
100// Log debug messages about hover events.
101constexpr bool DEBUG_HOVER = false;
102
Prabir Pradhancef936d2021-07-21 16:17:52 +0000103// Temporarily releases a held mutex for the lifetime of the instance.
104// Named to match std::scoped_lock
105class scoped_unlock {
106public:
107 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
108 ~scoped_unlock() { mMutex.lock(); }
109
110private:
111 std::mutex& mMutex;
112};
113
Michael Wrightd02c5b62014-02-10 15:10:22 -0800114// Default input dispatching timeout if there is no focused application or paused window
115// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800116const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
117 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
118 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800119
120// Amount of time to allow for all pending events to be processed when an app switch
121// key is on the way. This is used to preempt input dispatch and drop input events
122// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000123constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800124
125// Amount of time to allow for an event to be dispatched (measured since its eventTime)
126// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000127constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800128
Michael Wrightd02c5b62014-02-10 15:10:22 -0800129// 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 +0000130constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
131
132// Log a warning when an interception call takes longer than this to process.
133constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700135// Additional key latency in case a connection is still processing some motion events.
136// This will help with the case when a user touched a button that opens a new window,
137// and gives us the chance to dispatch the key to this new window.
138constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
139
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000141constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
142
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000143// Event log tags. See EventLogTags.logtags for reference
144constexpr int LOGTAG_INPUT_INTERACTION = 62000;
145constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000146constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000147
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000148inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800149 return systemTime(SYSTEM_TIME_MONOTONIC);
150}
151
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000152inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800153 return value ? "true" : "false";
154}
155
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000156inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000157 if (binder == nullptr) {
158 return "<null>";
159 }
160 return StringPrintf("%p", binder.get());
161}
162
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000163inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700164 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
165 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800166}
167
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000168bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800169 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700170 case AKEY_EVENT_ACTION_DOWN:
171 case AKEY_EVENT_ACTION_UP:
172 return true;
173 default:
174 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175 }
176}
177
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000178bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700179 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180 ALOGE("Key event has invalid action code 0x%x", action);
181 return false;
182 }
183 return true;
184}
185
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000186bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800187 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700188 case AMOTION_EVENT_ACTION_DOWN:
189 case AMOTION_EVENT_ACTION_UP:
190 case AMOTION_EVENT_ACTION_CANCEL:
191 case AMOTION_EVENT_ACTION_MOVE:
192 case AMOTION_EVENT_ACTION_OUTSIDE:
193 case AMOTION_EVENT_ACTION_HOVER_ENTER:
194 case AMOTION_EVENT_ACTION_HOVER_MOVE:
195 case AMOTION_EVENT_ACTION_HOVER_EXIT:
196 case AMOTION_EVENT_ACTION_SCROLL:
197 return true;
198 case AMOTION_EVENT_ACTION_POINTER_DOWN:
199 case AMOTION_EVENT_ACTION_POINTER_UP: {
200 int32_t index = getMotionEventActionPointerIndex(action);
201 return index >= 0 && index < pointerCount;
202 }
203 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
204 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
205 return actionButton != 0;
206 default:
207 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800208 }
209}
210
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000211int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500212 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
213}
214
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000215bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
216 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700217 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 ALOGE("Motion event has invalid action code 0x%x", action);
219 return false;
220 }
221 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000222 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700223 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 return false;
225 }
226 BitSet32 pointerIdBits;
227 for (size_t i = 0; i < pointerCount; i++) {
228 int32_t id = pointerProperties[i].id;
229 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700230 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
231 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800232 return false;
233 }
234 if (pointerIdBits.hasBit(id)) {
235 ALOGE("Motion event has duplicate pointer id %d", id);
236 return false;
237 }
238 pointerIdBits.markBit(id);
239 }
240 return true;
241}
242
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000243std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800244 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000245 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800246 }
247
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000248 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800249 bool first = true;
250 Region::const_iterator cur = region.begin();
251 Region::const_iterator const tail = region.end();
252 while (cur != tail) {
253 if (first) {
254 first = false;
255 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800256 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800257 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800258 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259 cur++;
260 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000261 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262}
263
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000264std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500265 constexpr size_t maxEntries = 50; // max events to print
266 constexpr size_t skipBegin = maxEntries / 2;
267 const size_t skipEnd = queue.size() - maxEntries / 2;
268 // skip from maxEntries / 2 ... size() - maxEntries/2
269 // only print from 0 .. skipBegin and then from skipEnd .. size()
270
271 std::string dump;
272 for (size_t i = 0; i < queue.size(); i++) {
273 const DispatchEntry& entry = *queue[i];
274 if (i >= skipBegin && i < skipEnd) {
275 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
276 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
277 continue;
278 }
279 dump.append(INDENT4);
280 dump += entry.eventEntry->getDescription();
281 dump += StringPrintf(", seq=%" PRIu32
282 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
283 entry.seq, entry.targetFlags, entry.resolvedAction,
284 ns2ms(currentTime - entry.eventEntry->eventTime));
285 if (entry.deliveryTime != 0) {
286 // This entry was delivered, so add information on how long we've been waiting
287 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
288 }
289 dump.append("\n");
290 }
291 return dump;
292}
293
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700294/**
295 * Find the entry in std::unordered_map by key, and return it.
296 * If the entry is not found, return a default constructed entry.
297 *
298 * Useful when the entries are vectors, since an empty vector will be returned
299 * if the entry is not found.
300 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
301 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700302template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000303V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700304 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700305 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800306}
307
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000308bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700309 if (first == second) {
310 return true;
311 }
312
313 if (first == nullptr || second == nullptr) {
314 return false;
315 }
316
317 return first->getToken() == second->getToken();
318}
319
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000320bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000321 if (first == nullptr || second == nullptr) {
322 return false;
323 }
324 return first->applicationInfo.token != nullptr &&
325 first->applicationInfo.token == second->applicationInfo.token;
326}
327
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000328bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800329 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
330}
331
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000332std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
333 std::shared_ptr<EventEntry> eventEntry,
334 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700335 if (inputTarget.useDefaultPointerTransform()) {
336 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700337 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700338 inputTarget.displayTransform,
339 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000340 }
341
342 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
343 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
344
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700345 std::vector<PointerCoords> pointerCoords;
346 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000347
348 // Use the first pointer information to normalize all other pointers. This could be any pointer
349 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700350 // uses the transform for the normalized pointer.
351 const ui::Transform& firstPointerTransform =
352 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
353 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000354
355 // Iterate through all pointers in the event to normalize against the first.
356 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
357 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
358 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700359 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000360
361 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700362 // First, apply the current pointer's transform to update the coordinates into
363 // window space.
364 pointerCoords[pointerIndex].transform(currTransform);
365 // Next, apply the inverse transform of the normalized coordinates so the
366 // current coordinates are transformed into the normalized coordinate space.
367 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000368 }
369
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700370 std::unique_ptr<MotionEntry> combinedMotionEntry =
371 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
372 motionEntry.deviceId, motionEntry.source,
373 motionEntry.displayId, motionEntry.policyFlags,
374 motionEntry.action, motionEntry.actionButton,
375 motionEntry.flags, motionEntry.metaState,
376 motionEntry.buttonState, motionEntry.classification,
377 motionEntry.edgeFlags, motionEntry.xPrecision,
378 motionEntry.yPrecision, motionEntry.xCursorPosition,
379 motionEntry.yCursorPosition, motionEntry.downTime,
380 motionEntry.pointerCount, motionEntry.pointerProperties,
Alex Chauf7c99f32021-12-03 10:37:54 +0000381 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000382
383 if (motionEntry.injectionState) {
384 combinedMotionEntry->injectionState = motionEntry.injectionState;
385 combinedMotionEntry->injectionState->refCount += 1;
386 }
387
388 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700389 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700390 firstPointerTransform, inputTarget.displayTransform,
391 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000392 return dispatchEntry;
393}
394
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000395status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
396 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700397 std::unique_ptr<InputChannel> uniqueServerChannel;
398 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
399
400 serverChannel = std::move(uniqueServerChannel);
401 return result;
402}
403
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500404template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000405bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500406 if (lhs == nullptr && rhs == nullptr) {
407 return true;
408 }
409 if (lhs == nullptr || rhs == nullptr) {
410 return false;
411 }
412 return *lhs == *rhs;
413}
414
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000415sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000416 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
417 if (service == nullptr) {
418 ALOGE("Failed to link to compat service");
419 return nullptr;
420 }
421 return interface_cast<IPlatformCompatNative>(service);
422}
423
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000424KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000425 KeyEvent event;
426 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
427 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
428 entry.repeatCount, entry.downTime, entry.eventTime);
429 return event;
430}
431
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000432std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000433 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
434 const sp<IBinder>& token) {
435 for (const auto& it : monitorsByDisplay) {
436 const std::vector<Monitor>& monitors = it.second;
437 for (const Monitor& monitor : monitors) {
438 if (monitor.inputChannel->getConnectionToken() == token) {
439 return monitor.pid;
440 }
441 }
442 }
443 return std::nullopt;
444}
445
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000446bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000447 // Do not keep track of gesture monitors. They receive every event and would disproportionately
448 // affect the statistics.
449 if (connection.monitor) {
450 return false;
451 }
452 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
453 if (!connection.responsive) {
454 return false;
455 }
456 return true;
457}
458
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000459bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000460 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
461 const int32_t& inputEventId = eventEntry.id;
462 if (inputEventId != dispatchEntry.resolvedEventId) {
463 // Event was transmuted
464 return false;
465 }
466 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
467 return false;
468 }
469 // Only track latency for events that originated from hardware
470 if (eventEntry.isSynthesized()) {
471 return false;
472 }
473 const EventEntry::Type& inputEventEntryType = eventEntry.type;
474 if (inputEventEntryType == EventEntry::Type::KEY) {
475 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
476 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
477 return false;
478 }
479 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
480 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
481 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
482 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
483 return false;
484 }
485 } else {
486 // Not a key or a motion
487 return false;
488 }
489 if (!shouldReportMetricsForConnection(connection)) {
490 return false;
491 }
492 return true;
493}
494
Prabir Pradhancef936d2021-07-21 16:17:52 +0000495/**
496 * Connection is responsive if it has no events in the waitQueue that are older than the
497 * current time.
498 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000499bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000500 const nsecs_t currentTime = now();
501 for (const DispatchEntry* entry : connection.waitQueue) {
502 if (entry->timeoutTime < currentTime) {
503 return false;
504 }
505 }
506 return true;
507}
508
Alex Chau663fc832021-12-03 10:37:54 +0000509vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float y) {
510 const vec2 transformedXy = transform.transform(x, y);
511 const vec2 transformedOrigin = transform.transform(0, 0);
512 return transformedXy - transformedOrigin;
513}
514
Antonio Kantekf16f2832021-09-28 04:39:20 +0000515// Returns true if the event type passed as argument represents a user activity.
516bool isUserActivityEvent(const EventEntry& eventEntry) {
517 switch (eventEntry.type) {
518 case EventEntry::Type::FOCUS:
519 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
520 case EventEntry::Type::DRAG:
521 case EventEntry::Type::TOUCH_MODE_CHANGED:
522 case EventEntry::Type::SENSOR:
523 case EventEntry::Type::CONFIGURATION_CHANGED:
524 return false;
525 case EventEntry::Type::DEVICE_RESET:
526 case EventEntry::Type::KEY:
527 case EventEntry::Type::MOTION:
528 return true;
529 }
530}
531
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800532// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhand65552b2021-10-07 11:23:50 -0700533bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, int32_t x, int32_t y,
534 bool isStylus) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800535 if (windowInfo.displayId != displayId || !windowInfo.visible) {
536 return false;
537 }
538 const auto flags = windowInfo.flags;
Prabir Pradhand65552b2021-10-07 11:23:50 -0700539 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
540 if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800541 return false;
542 }
543 const bool isModalWindow = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
544 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
545 if (!isModalWindow && !windowInfo.touchableRegionContainsPoint(x, y)) {
546 return false;
547 }
548 return true;
549}
550
Prabir Pradhand65552b2021-10-07 11:23:50 -0700551bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
552 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
553 (entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS ||
554 entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_ERASER);
555}
556
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000557} // namespace
558
Michael Wrightd02c5b62014-02-10 15:10:22 -0800559// --- InputDispatcher ---
560
Garfield Tan00f511d2019-06-12 16:55:40 -0700561InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
562 : mPolicy(policy),
563 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700564 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800565 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700566 mAppSwitchSawKeyDown(false),
567 mAppSwitchDueTime(LONG_LONG_MAX),
568 mNextUnblockedEvent(nullptr),
569 mDispatchEnabled(false),
570 mDispatchFrozen(false),
571 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800572 // mInTouchMode will be initialized by the WindowManager to the default device config.
573 // To avoid leaking stack in case that call never comes, and for tests,
574 // initialize it here anyways.
Antonio Kantekf16f2832021-09-28 04:39:20 +0000575 mInTouchMode(kDefaultInTouchMode),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100576 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000577 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800578 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000579 mLatencyAggregator(),
580 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000581 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800583 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800584
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700585 mWindowInfoListener = new DispatcherWindowListener(*this);
586 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
587
Yi Kong9b14ac62018-07-17 13:48:38 -0700588 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589
590 policy->getDispatcherConfiguration(&mConfig);
591}
592
593InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000594 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800595
Prabir Pradhancef936d2021-07-21 16:17:52 +0000596 resetKeyRepeatLocked();
597 releasePendingEventLocked();
598 drainInboundQueueLocked();
599 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800600
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000601 while (!mConnectionsByToken.empty()) {
602 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000603 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
604 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800605 }
606}
607
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700608status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700609 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700610 return ALREADY_EXISTS;
611 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700612 mThread = std::make_unique<InputThread>(
613 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
614 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700615}
616
617status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700618 if (mThread && mThread->isCallingThread()) {
619 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700620 return INVALID_OPERATION;
621 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700622 mThread.reset();
623 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700624}
625
Michael Wrightd02c5b62014-02-10 15:10:22 -0800626void InputDispatcher::dispatchOnce() {
627 nsecs_t nextWakeupTime = LONG_LONG_MAX;
628 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800629 std::scoped_lock _l(mLock);
630 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800631
632 // Run a dispatch loop if there are no pending commands.
633 // The dispatch loop might enqueue commands to run afterwards.
634 if (!haveCommandsLocked()) {
635 dispatchOnceInnerLocked(&nextWakeupTime);
636 }
637
638 // Run all pending commands if there are any.
639 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000640 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641 nextWakeupTime = LONG_LONG_MIN;
642 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800643
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700644 // If we are still waiting for ack on some events,
645 // we might have to wake up earlier to check if an app is anr'ing.
646 const nsecs_t nextAnrCheck = processAnrsLocked();
647 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
648
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800649 // We are about to enter an infinitely long sleep, because we have no commands or
650 // pending or queued events
651 if (nextWakeupTime == LONG_LONG_MAX) {
652 mDispatcherEnteredIdle.notify_all();
653 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800654 } // release lock
655
656 // Wait for callback or timeout or wake. (make sure we round up, not down)
657 nsecs_t currentTime = now();
658 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
659 mLooper->pollOnce(timeoutMillis);
660}
661
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700662/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500663 * Raise ANR if there is no focused window.
664 * Before the ANR is raised, do a final state check:
665 * 1. The currently focused application must be the same one we are waiting for.
666 * 2. Ensure we still don't have a focused window.
667 */
668void InputDispatcher::processNoFocusedWindowAnrLocked() {
669 // Check if the application that we are waiting for is still focused.
670 std::shared_ptr<InputApplicationHandle> focusedApplication =
671 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
672 if (focusedApplication == nullptr ||
673 focusedApplication->getApplicationToken() !=
674 mAwaitedFocusedApplication->getApplicationToken()) {
675 // Unexpected because we should have reset the ANR timer when focused application changed
676 ALOGE("Waited for a focused window, but focused application has already changed to %s",
677 focusedApplication->getName().c_str());
678 return; // The focused application has changed.
679 }
680
chaviw98318de2021-05-19 16:45:23 -0500681 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500682 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
683 if (focusedWindowHandle != nullptr) {
684 return; // We now have a focused window. No need for ANR.
685 }
686 onAnrLocked(mAwaitedFocusedApplication);
687}
688
689/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700690 * Check if any of the connections' wait queues have events that are too old.
691 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
692 * Return the time at which we should wake up next.
693 */
694nsecs_t InputDispatcher::processAnrsLocked() {
695 const nsecs_t currentTime = now();
696 nsecs_t nextAnrCheck = LONG_LONG_MAX;
697 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
698 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
699 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500700 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700701 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500702 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700703 return LONG_LONG_MIN;
704 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500705 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700706 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
707 }
708 }
709
710 // Check if any connection ANRs are due
711 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
712 if (currentTime < nextAnrCheck) { // most likely scenario
713 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
714 }
715
716 // If we reached here, we have an unresponsive connection.
717 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
718 if (connection == nullptr) {
719 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
720 return nextAnrCheck;
721 }
722 connection->responsive = false;
723 // Stop waking up for this unresponsive connection
724 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000725 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700726 return LONG_LONG_MIN;
727}
728
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500729std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500730 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700731 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500732 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700733 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500734 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700735}
736
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
738 nsecs_t currentTime = now();
739
Jeff Browndc5992e2014-04-11 01:27:26 -0700740 // Reset the key repeat timer whenever normal dispatch is suspended while the
741 // device is in a non-interactive state. This is to ensure that we abort a key
742 // repeat if the device is just coming out of sleep.
743 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800744 resetKeyRepeatLocked();
745 }
746
747 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
748 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100749 if (DEBUG_FOCUS) {
750 ALOGD("Dispatch frozen. Waiting some more.");
751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800752 return;
753 }
754
755 // Optimize latency of app switches.
756 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
757 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
758 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
759 if (mAppSwitchDueTime < *nextWakeupTime) {
760 *nextWakeupTime = mAppSwitchDueTime;
761 }
762
763 // Ready to start a new event.
764 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700765 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700766 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800767 if (isAppSwitchDue) {
768 // The inbound queue is empty so the app switch key we were waiting
769 // for will never arrive. Stop waiting for it.
770 resetPendingAppSwitchLocked(false);
771 isAppSwitchDue = false;
772 }
773
774 // Synthesize a key repeat if appropriate.
775 if (mKeyRepeatState.lastKeyEntry) {
776 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
777 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
778 } else {
779 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
780 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
781 }
782 }
783 }
784
785 // Nothing to do if there is no pending event.
786 if (!mPendingEvent) {
787 return;
788 }
789 } else {
790 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700791 mPendingEvent = mInboundQueue.front();
792 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800793 traceInboundQueueLengthLocked();
794 }
795
796 // Poke user activity for this event.
797 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700798 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800799 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800800 }
801
802 // Now we have an event to dispatch.
803 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700804 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700806 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700808 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800809 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700810 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811 }
812
813 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700814 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815 }
816
817 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700818 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700819 const ConfigurationChangedEntry& typedEntry =
820 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700821 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700822 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700823 break;
824 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800825
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700826 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700827 const DeviceResetEntry& typedEntry =
828 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700829 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700830 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700831 break;
832 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100834 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700835 std::shared_ptr<FocusEntry> typedEntry =
836 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100837 dispatchFocusLocked(currentTime, typedEntry);
838 done = true;
839 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
840 break;
841 }
842
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700843 case EventEntry::Type::TOUCH_MODE_CHANGED: {
844 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
845 dispatchTouchModeChangeLocked(currentTime, typedEntry);
846 done = true;
847 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
848 break;
849 }
850
Prabir Pradhan99987712020-11-10 18:43:05 -0800851 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
852 const auto typedEntry =
853 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
854 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
855 done = true;
856 break;
857 }
858
arthurhungb89ccb02020-12-30 16:19:01 +0800859 case EventEntry::Type::DRAG: {
860 std::shared_ptr<DragEntry> typedEntry =
861 std::static_pointer_cast<DragEntry>(mPendingEvent);
862 dispatchDragLocked(currentTime, typedEntry);
863 done = true;
864 break;
865 }
866
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700867 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700868 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700869 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700870 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700871 resetPendingAppSwitchLocked(true);
872 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700873 } else if (dropReason == DropReason::NOT_DROPPED) {
874 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 }
876 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700877 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700878 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700879 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700880 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
881 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700882 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700883 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700884 break;
885 }
886
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700887 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700888 std::shared_ptr<MotionEntry> motionEntry =
889 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700890 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
891 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700893 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700894 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700895 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700896 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
897 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700898 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700899 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700900 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800901 }
Chris Yef59a2f42020-10-16 12:55:26 -0700902
903 case EventEntry::Type::SENSOR: {
904 std::shared_ptr<SensorEntry> sensorEntry =
905 std::static_pointer_cast<SensorEntry>(mPendingEvent);
906 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
907 dropReason = DropReason::APP_SWITCH;
908 }
909 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
910 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
911 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
912 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
913 dropReason = DropReason::STALE;
914 }
915 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
916 done = true;
917 break;
918 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919 }
920
921 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700922 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700923 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800924 }
Michael Wright3a981722015-06-10 15:26:13 +0100925 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800926
927 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700928 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929 }
930}
931
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700932/**
933 * Return true if the events preceding this incoming motion event should be dropped
934 * Return false otherwise (the default behaviour)
935 */
936bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700937 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700938 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700939
940 // Optimize case where the current application is unresponsive and the user
941 // decides to touch a window in a different application.
942 // If the application takes too long to catch up then we drop all events preceding
943 // the touch into the other window.
944 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700945 int32_t displayId = motionEntry.displayId;
946 int32_t x = static_cast<int32_t>(
947 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
948 int32_t y = static_cast<int32_t>(
949 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Prabir Pradhand65552b2021-10-07 11:23:50 -0700950
951 const bool isStylus = isPointerFromStylus(motionEntry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -0500952 sp<WindowInfoHandle> touchedWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -0700953 findTouchedWindowAtLocked(displayId, x, y, nullptr, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700954 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700955 touchedWindowHandle->getApplicationToken() !=
956 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700957 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700958 ALOGI("Pruning input queue because user touched a different application while waiting "
959 "for %s",
960 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700961 return true;
962 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700963
964 // Alternatively, maybe there's a gesture monitor that could handle this event
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700965 for (const auto& monitor : getValueByKey(mGestureMonitorsByDisplay, displayId)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700966 sp<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700967 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000968 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700969 // This monitor could take more input. Drop all events preceding this
970 // event, so that gesture monitor could get a chance to receive the stream
971 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
972 "responsive gesture monitor that may handle the event",
973 mAwaitedFocusedApplication->getName().c_str());
974 return true;
975 }
976 }
977 }
978
979 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
980 // yet been processed by some connections, the dispatcher will wait for these motion
981 // events to be processed before dispatching the key event. This is because these motion events
982 // may cause a new window to be launched, which the user might expect to receive focus.
983 // To prevent waiting forever for such events, just send the key to the currently focused window
984 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
985 ALOGD("Received a new pointer down event, stop waiting for events to process and "
986 "just send the pending key event to the focused window.");
987 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700988 }
989 return false;
990}
991
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700992bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700993 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700994 mInboundQueue.push_back(std::move(newEntry));
995 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800996 traceInboundQueueLengthLocked();
997
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700998 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700999 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001000 // Optimize app switch latency.
1001 // If the application takes too long to catch up then we drop all events preceding
1002 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001003 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001005 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001006 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001007 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001008 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001009 if (DEBUG_APP_SWITCH) {
1010 ALOGD("App switch is pending!");
1011 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001012 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001013 mAppSwitchSawKeyDown = false;
1014 needWake = true;
1015 }
1016 }
1017 }
1018 break;
1019 }
1020
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001021 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001022 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1023 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001024 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001025 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001026 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001027 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001028 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001029 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1030 break;
1031 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001032 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001033 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001034 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001035 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001036 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1037 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001038 // nothing to do
1039 break;
1040 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001041 }
1042
1043 return needWake;
1044}
1045
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001046void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001047 // Do not store sensor event in recent queue to avoid flooding the queue.
1048 if (entry->type != EventEntry::Type::SENSOR) {
1049 mRecentQueue.push_back(entry);
1050 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001051 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001052 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001053 }
1054}
1055
chaviw98318de2021-05-19 16:45:23 -05001056sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1057 int32_t y, TouchState* touchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07001058 bool isStylus,
chaviw98318de2021-05-19 16:45:23 -05001059 bool addOutsideTargets,
1060 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001061 if (addOutsideTargets && touchState == nullptr) {
1062 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001063 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001064 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001065 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001066 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001067 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001068 continue;
1069 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001071 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhand65552b2021-10-07 11:23:50 -07001072 if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001073 return windowHandle;
1074 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001075
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001076 if (addOutsideTargets && info.flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
1077 touchState->addOrUpdateWindow(windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1078 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001079 }
1080 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001081 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082}
1083
Prabir Pradhand65552b2021-10-07 11:23:50 -07001084std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
1085 int32_t displayId, int32_t x, int32_t y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001086 // Traverse windows from front to back and gather the touched spy windows.
1087 std::vector<sp<WindowInfoHandle>> spyWindows;
1088 const auto& windowHandles = getWindowHandlesLocked(displayId);
1089 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1090 const WindowInfo& info = *windowHandle->getInfo();
1091
Prabir Pradhand65552b2021-10-07 11:23:50 -07001092 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001093 continue;
1094 }
1095 if (!info.isSpy()) {
1096 // The first touched non-spy window was found, so return the spy windows touched so far.
1097 return spyWindows;
1098 }
1099 spyWindows.push_back(windowHandle);
1100 }
1101 return spyWindows;
1102}
1103
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001104void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001105 const char* reason;
1106 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001107 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001108 if (DEBUG_INBOUND_EVENT_DETAILS) {
1109 ALOGD("Dropped event because policy consumed it.");
1110 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001111 reason = "inbound event was dropped because the policy consumed it";
1112 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001113 case DropReason::DISABLED:
1114 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001115 ALOGI("Dropped event because input dispatch is disabled.");
1116 }
1117 reason = "inbound event was dropped because input dispatch is disabled";
1118 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001119 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001120 ALOGI("Dropped event because of pending overdue app switch.");
1121 reason = "inbound event was dropped because of pending overdue app switch";
1122 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001123 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001124 ALOGI("Dropped event because the current application is not responding and the user "
1125 "has started interacting with a different application.");
1126 reason = "inbound event was dropped because the current application is not responding "
1127 "and the user has started interacting with a different application";
1128 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001129 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001130 ALOGI("Dropped event because it is stale.");
1131 reason = "inbound event was dropped because it is stale";
1132 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001133 case DropReason::NO_POINTER_CAPTURE:
1134 ALOGI("Dropped event because there is no window with Pointer Capture.");
1135 reason = "inbound event was dropped because there is no window with Pointer Capture";
1136 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001137 case DropReason::NOT_DROPPED: {
1138 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001139 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001140 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141 }
1142
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001143 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001144 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1146 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001147 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001148 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001149 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001150 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1151 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001152 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1153 synthesizeCancelationEventsForAllConnectionsLocked(options);
1154 } else {
1155 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1156 synthesizeCancelationEventsForAllConnectionsLocked(options);
1157 }
1158 break;
1159 }
Chris Yef59a2f42020-10-16 12:55:26 -07001160 case EventEntry::Type::SENSOR: {
1161 break;
1162 }
arthurhungb89ccb02020-12-30 16:19:01 +08001163 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1164 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001165 break;
1166 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001167 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001168 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001169 case EventEntry::Type::CONFIGURATION_CHANGED:
1170 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001171 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001172 break;
1173 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001174 }
1175}
1176
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001177static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001178 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1179 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180}
1181
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001182bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1183 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1184 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1185 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186}
1187
1188bool InputDispatcher::isAppSwitchPendingLocked() {
1189 return mAppSwitchDueTime != LONG_LONG_MAX;
1190}
1191
1192void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1193 mAppSwitchDueTime = LONG_LONG_MAX;
1194
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001195 if (DEBUG_APP_SWITCH) {
1196 if (handled) {
1197 ALOGD("App switch has arrived.");
1198 } else {
1199 ALOGD("App switch was abandoned.");
1200 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001202}
1203
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001205 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001206}
1207
Prabir Pradhancef936d2021-07-21 16:17:52 +00001208bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001209 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001210 return false;
1211 }
1212
1213 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001214 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001215 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001216 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1217 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001218 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001219 return true;
1220}
1221
Prabir Pradhancef936d2021-07-21 16:17:52 +00001222void InputDispatcher::postCommandLocked(Command&& command) {
1223 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001224}
1225
1226void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001227 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001228 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001229 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001230 releaseInboundEventLocked(entry);
1231 }
1232 traceInboundQueueLengthLocked();
1233}
1234
1235void InputDispatcher::releasePendingEventLocked() {
1236 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001237 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001238 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239 }
1240}
1241
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001242void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001243 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001244 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001245 if (DEBUG_DISPATCH_CYCLE) {
1246 ALOGD("Injected inbound event was dropped.");
1247 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001248 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001249 }
1250 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001251 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252 }
1253 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001254}
1255
1256void InputDispatcher::resetKeyRepeatLocked() {
1257 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001258 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259 }
1260}
1261
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1263 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264
Michael Wright2e732952014-09-24 13:26:59 -07001265 uint32_t policyFlags = entry->policyFlags &
1266 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001267
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001268 std::shared_ptr<KeyEntry> newEntry =
1269 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1270 entry->source, entry->displayId, policyFlags, entry->action,
1271 entry->flags, entry->keyCode, entry->scanCode,
1272 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001274 newEntry->syntheticRepeat = true;
1275 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001276 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001277 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001278}
1279
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001280bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001281 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001282 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1283 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1284 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001285
1286 // Reset key repeating in case a keyboard device was added or removed or something.
1287 resetKeyRepeatLocked();
1288
1289 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001290 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1291 scoped_unlock unlock(mLock);
1292 mPolicy->notifyConfigurationChanged(eventTime);
1293 };
1294 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001295 return true;
1296}
1297
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001298bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1299 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001300 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1301 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1302 entry.deviceId);
1303 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304
liushenxiang42232912021-05-21 20:24:09 +08001305 // Reset key repeating in case a keyboard device was disabled or enabled.
1306 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1307 resetKeyRepeatLocked();
1308 }
1309
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001310 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001311 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001312 synthesizeCancelationEventsForAllConnectionsLocked(options);
1313 return true;
1314}
1315
Vishnu Nairad321cd2020-08-20 16:40:21 -07001316void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001317 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001318 if (mPendingEvent != nullptr) {
1319 // Move the pending event to the front of the queue. This will give the chance
1320 // for the pending event to get dispatched to the newly focused window
1321 mInboundQueue.push_front(mPendingEvent);
1322 mPendingEvent = nullptr;
1323 }
1324
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001325 std::unique_ptr<FocusEntry> focusEntry =
1326 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1327 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001328
1329 // This event should go to the front of the queue, but behind all other focus events
1330 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001331 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001332 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001333 [](const std::shared_ptr<EventEntry>& event) {
1334 return event->type == EventEntry::Type::FOCUS;
1335 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001336
1337 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001338 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001339}
1340
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001341void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001342 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001343 if (channel == nullptr) {
1344 return; // Window has gone away
1345 }
1346 InputTarget target;
1347 target.inputChannel = channel;
1348 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1349 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001350 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1351 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001352 std::string reason = std::string("reason=").append(entry->reason);
1353 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001354 dispatchEventLocked(currentTime, entry, {target});
1355}
1356
Prabir Pradhan99987712020-11-10 18:43:05 -08001357void InputDispatcher::dispatchPointerCaptureChangedLocked(
1358 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1359 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001360 dropReason = DropReason::NOT_DROPPED;
1361
Prabir Pradhan99987712020-11-10 18:43:05 -08001362 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001363 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001364
1365 if (entry->pointerCaptureRequest.enable) {
1366 // Enable Pointer Capture.
1367 if (haveWindowWithPointerCapture &&
1368 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1369 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1370 "to the window.");
1371 }
1372 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001373 // This can happen if a window requests capture and immediately releases capture.
1374 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001375 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001376 return;
1377 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001378 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1379 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1380 return;
1381 }
1382
Vishnu Nairc519ff72021-01-21 08:23:08 -08001383 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001384 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1385 mWindowTokenWithPointerCapture = token;
1386 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001387 // Disable Pointer Capture.
1388 // We do not check if the sequence number matches for requests to disable Pointer Capture
1389 // for two reasons:
1390 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1391 // to disable capture with the same sequence number: one generated by
1392 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1393 // Capture being disabled in InputReader.
1394 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1395 // actual Pointer Capture state that affects events being generated by input devices is
1396 // in InputReader.
1397 if (!haveWindowWithPointerCapture) {
1398 // Pointer capture was already forcefully disabled because of focus change.
1399 dropReason = DropReason::NOT_DROPPED;
1400 return;
1401 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001402 token = mWindowTokenWithPointerCapture;
1403 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001404 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001405 setPointerCaptureLocked(false);
1406 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001407 }
1408
1409 auto channel = getInputChannelLocked(token);
1410 if (channel == nullptr) {
1411 // Window has gone away, clean up Pointer Capture state.
1412 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001413 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001414 setPointerCaptureLocked(false);
1415 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001416 return;
1417 }
1418 InputTarget target;
1419 target.inputChannel = channel;
1420 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1421 entry->dispatchInProgress = true;
1422 dispatchEventLocked(currentTime, entry, {target});
1423
1424 dropReason = DropReason::NOT_DROPPED;
1425}
1426
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001427void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1428 const std::shared_ptr<TouchModeEntry>& entry) {
1429 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1430 getWindowHandlesLocked(mFocusedDisplayId);
1431 if (windowHandles.empty()) {
1432 return;
1433 }
1434 const std::vector<InputTarget> inputTargets =
1435 getInputTargetsFromWindowHandlesLocked(windowHandles);
1436 if (inputTargets.empty()) {
1437 return;
1438 }
1439 entry->dispatchInProgress = true;
1440 dispatchEventLocked(currentTime, entry, inputTargets);
1441}
1442
1443std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1444 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1445 std::vector<InputTarget> inputTargets;
1446 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1447 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1448 const sp<IBinder>& token = handle->getToken();
1449 if (token == nullptr) {
1450 continue;
1451 }
1452 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1453 if (channel == nullptr) {
1454 continue; // Window has gone away
1455 }
1456 InputTarget target;
1457 target.inputChannel = channel;
1458 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1459 inputTargets.push_back(target);
1460 }
1461 return inputTargets;
1462}
1463
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001464bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001465 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001467 if (!entry->dispatchInProgress) {
1468 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1469 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1470 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1471 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001472 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001473 // We have seen two identical key downs in a row which indicates that the device
1474 // driver is automatically generating key repeats itself. We take note of the
1475 // repeat here, but we disable our own next key repeat timer since it is clear that
1476 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001477 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1478 // Make sure we don't get key down from a different device. If a different
1479 // device Id has same key pressed down, the new device Id will replace the
1480 // current one to hold the key repeat with repeat count reset.
1481 // In the future when got a KEY_UP on the device id, drop it and do not
1482 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1484 resetKeyRepeatLocked();
1485 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1486 } else {
1487 // Not a repeat. Save key down state in case we do see a repeat later.
1488 resetKeyRepeatLocked();
1489 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1490 }
1491 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001492 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1493 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001494 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001495 if (DEBUG_INBOUND_EVENT_DETAILS) {
1496 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1497 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001498 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 resetKeyRepeatLocked();
1500 }
1501
1502 if (entry->repeatCount == 1) {
1503 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1504 } else {
1505 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1506 }
1507
1508 entry->dispatchInProgress = true;
1509
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001510 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001511 }
1512
1513 // Handle case where the policy asked us to try again later last time.
1514 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1515 if (currentTime < entry->interceptKeyWakeupTime) {
1516 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1517 *nextWakeupTime = entry->interceptKeyWakeupTime;
1518 }
1519 return false; // wait until next wakeup
1520 }
1521 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1522 entry->interceptKeyWakeupTime = 0;
1523 }
1524
1525 // Give the policy a chance to intercept the key.
1526 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1527 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001528 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001529 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001530
1531 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1532 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1533 };
1534 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001535 return false; // wait for the command to run
1536 } else {
1537 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1538 }
1539 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001540 if (*dropReason == DropReason::NOT_DROPPED) {
1541 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001542 }
1543 }
1544
1545 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001546 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001547 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001548 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1549 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001550 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001551 return true;
1552 }
1553
1554 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001555 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001556 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001557 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001558 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001559 return false;
1560 }
1561
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001562 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001563 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564 return true;
1565 }
1566
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001567 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001568 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001569
1570 // Dispatch the key.
1571 dispatchEventLocked(currentTime, entry, inputTargets);
1572 return true;
1573}
1574
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001575void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001576 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1577 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1578 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1579 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1580 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1581 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1582 entry.metaState, entry.repeatCount, entry.downTime);
1583 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001584}
1585
Prabir Pradhancef936d2021-07-21 16:17:52 +00001586void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1587 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001588 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001589 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1590 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1591 "source=0x%x, sensorType=%s",
1592 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001593 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001594 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001595 auto command = [this, entry]() REQUIRES(mLock) {
1596 scoped_unlock unlock(mLock);
1597
1598 if (entry->accuracyChanged) {
1599 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1600 }
1601 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1602 entry->hwTimestamp, entry->values);
1603 };
1604 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001605}
1606
1607bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001608 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1609 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001610 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001611 }
Chris Yef59a2f42020-10-16 12:55:26 -07001612 { // acquire lock
1613 std::scoped_lock _l(mLock);
1614
1615 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1616 std::shared_ptr<EventEntry> entry = *it;
1617 if (entry->type == EventEntry::Type::SENSOR) {
1618 it = mInboundQueue.erase(it);
1619 releaseInboundEventLocked(entry);
1620 }
1621 }
1622 }
1623 return true;
1624}
1625
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001626bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001627 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001628 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001629 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001630 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001631 entry->dispatchInProgress = true;
1632
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001633 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001634 }
1635
1636 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001637 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001638 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001639 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1640 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001641 return true;
1642 }
1643
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001644 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001645
1646 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001647 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001648
1649 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001650 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001651 if (isPointerEvent) {
1652 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001653 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001654 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001655 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001656 } else {
1657 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001658 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001659 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001660 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001661 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001662 return false;
1663 }
1664
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001665 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001666 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001667 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1668 return true;
1669 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001670 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001671 CancelationOptions::Mode mode(isPointerEvent
1672 ? CancelationOptions::CANCEL_POINTER_EVENTS
1673 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1674 CancelationOptions options(mode, "input event injection failed");
1675 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001676 return true;
1677 }
1678
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001679 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001680 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001681
1682 // Dispatch the motion.
1683 if (conflictingPointerActions) {
1684 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001685 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 synthesizeCancelationEventsForAllConnectionsLocked(options);
1687 }
1688 dispatchEventLocked(currentTime, entry, inputTargets);
1689 return true;
1690}
1691
chaviw98318de2021-05-19 16:45:23 -05001692void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001693 bool isExiting, const MotionEntry& motionEntry) {
1694 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1695 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1696 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1697 PointerCoords pointerCoords;
1698 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1699 pointerCoords.transform(windowHandle->getInfo()->transform);
1700
1701 std::unique_ptr<DragEntry> dragEntry =
1702 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1703 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1704 pointerCoords.getY());
1705
1706 enqueueInboundEventLocked(std::move(dragEntry));
1707}
1708
1709void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1710 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1711 if (channel == nullptr) {
1712 return; // Window has gone away
1713 }
1714 InputTarget target;
1715 target.inputChannel = channel;
1716 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1717 entry->dispatchInProgress = true;
1718 dispatchEventLocked(currentTime, entry, {target});
1719}
1720
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001721void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001722 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1723 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1724 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001725 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001726 "metaState=0x%x, buttonState=0x%x,"
1727 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1728 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001729 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1730 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1731 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001732
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001733 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1734 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1735 "x=%f, y=%f, pressure=%f, size=%f, "
1736 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1737 "orientation=%f",
1738 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1739 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1740 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1741 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1742 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1743 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1744 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1745 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1746 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1747 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1748 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001750}
1751
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001752void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1753 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001754 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001755 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001756 if (DEBUG_DISPATCH_CYCLE) {
1757 ALOGD("dispatchEventToCurrentInputTargets");
1758 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001759
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001760 updateInteractionTokensLocked(*eventEntry, inputTargets);
1761
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1763
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001764 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001765
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001766 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001767 sp<Connection> connection =
1768 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001769 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001770 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001771 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001772 if (DEBUG_FOCUS) {
1773 ALOGD("Dropping event delivery to target with channel '%s' because it "
1774 "is no longer registered with the input dispatcher.",
1775 inputTarget.inputChannel->getName().c_str());
1776 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001777 }
1778 }
1779}
1780
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001781void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1782 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1783 // If the policy decides to close the app, we will get a channel removal event via
1784 // unregisterInputChannel, and will clean up the connection that way. We are already not
1785 // sending new pointers to the connection when it blocked, but focused events will continue to
1786 // pile up.
1787 ALOGW("Canceling events for %s because it is unresponsive",
1788 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08001789 if (connection->status == Connection::Status::NORMAL) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001790 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1791 "application not responding");
1792 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001793 }
1794}
1795
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001796void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001797 if (DEBUG_FOCUS) {
1798 ALOGD("Resetting ANR timeouts.");
1799 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001800
1801 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001802 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001803 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001804}
1805
Tiger Huang721e26f2018-07-24 22:26:19 +08001806/**
1807 * Get the display id that the given event should go to. If this event specifies a valid display id,
1808 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1809 * Focused display is the display that the user most recently interacted with.
1810 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001811int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001812 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001813 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001814 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001815 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1816 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001817 break;
1818 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001819 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001820 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1821 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001822 break;
1823 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001824 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001825 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001826 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001827 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001828 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001829 case EventEntry::Type::SENSOR:
1830 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001831 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001832 return ADISPLAY_ID_NONE;
1833 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001834 }
1835 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1836}
1837
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001838bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1839 const char* focusedWindowName) {
1840 if (mAnrTracker.empty()) {
1841 // already processed all events that we waited for
1842 mKeyIsWaitingForEventsTimeout = std::nullopt;
1843 return false;
1844 }
1845
1846 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1847 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001848 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001849 mKeyIsWaitingForEventsTimeout = currentTime +
1850 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1851 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001852 return true;
1853 }
1854
1855 // We still have pending events, and already started the timer
1856 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1857 return true; // Still waiting
1858 }
1859
1860 // Waited too long, and some connection still hasn't processed all motions
1861 // Just send the key to the focused window
1862 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1863 focusedWindowName);
1864 mKeyIsWaitingForEventsTimeout = std::nullopt;
1865 return false;
1866}
1867
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001868InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1869 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1870 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001871 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001872
Tiger Huang721e26f2018-07-24 22:26:19 +08001873 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001874 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001875 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001876 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1877
Michael Wrightd02c5b62014-02-10 15:10:22 -08001878 // If there is no currently focused window and no focused application
1879 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001880 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1881 ALOGI("Dropping %s event because there is no focused window or focused application in "
1882 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001883 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001884 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001885 }
1886
Vishnu Nair062a8672021-09-03 16:07:44 -07001887 // Drop key events if requested by input feature
1888 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1889 return InputEventInjectionResult::FAILED;
1890 }
1891
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001892 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1893 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1894 // start interacting with another application via touch (app switch). This code can be removed
1895 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1896 // an app is expected to have a focused window.
1897 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1898 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1899 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001900 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1901 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1902 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001903 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001904 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001905 ALOGW("Waiting because no window has focus but %s may eventually add a "
1906 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001907 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001908 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001909 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001910 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1911 // Already raised ANR. Drop the event
1912 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001913 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001914 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001915 } else {
1916 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001917 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001918 }
1919 }
1920
1921 // we have a valid, non-null focused window
1922 resetNoFocusedWindowTimeoutLocked();
1923
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001925 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001926 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001927 }
1928
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001929 if (focusedWindowHandle->getInfo()->paused) {
1930 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001931 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001932 }
1933
1934 // If the event is a key event, then we must wait for all previous events to
1935 // complete before delivering it because previous events may have the
1936 // side-effect of transferring focus to a different window and we want to
1937 // ensure that the following keys are sent to the new window.
1938 //
1939 // Suppose the user touches a button in a window then immediately presses "A".
1940 // If the button causes a pop-up window to appear then we want to ensure that
1941 // the "A" key is delivered to the new pop-up window. This is because users
1942 // often anticipate pending UI changes when typing on a keyboard.
1943 // To obtain this behavior, we must serialize key events with respect to all
1944 // prior input events.
1945 if (entry.type == EventEntry::Type::KEY) {
1946 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1947 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001948 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001949 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001950 }
1951
1952 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001953 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001954 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1955 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001956
1957 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001958 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001959}
1960
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001961/**
1962 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1963 * that are currently unresponsive.
1964 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001965std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
1966 const std::vector<Monitor>& monitors) const {
1967 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001968 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001969 [this](const Monitor& monitor) REQUIRES(mLock) {
1970 sp<Connection> connection =
1971 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001972 if (connection == nullptr) {
1973 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001974 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001975 return false;
1976 }
1977 if (!connection->responsive) {
1978 ALOGW("Unresponsive monitor %s will not get the new gesture",
1979 connection->inputChannel->getName().c_str());
1980 return false;
1981 }
1982 return true;
1983 });
1984 return responsiveMonitors;
1985}
1986
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001987InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1988 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1989 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001990 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001991 enum InjectionPermission {
1992 INJECTION_PERMISSION_UNKNOWN,
1993 INJECTION_PERMISSION_GRANTED,
1994 INJECTION_PERMISSION_DENIED
1995 };
1996
Michael Wrightd02c5b62014-02-10 15:10:22 -08001997 // For security reasons, we defer updating the touch state until we are sure that
1998 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001999 const int32_t displayId = entry.displayId;
2000 const int32_t action = entry.action;
2001 const int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002002
2003 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002004 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002005 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05002006 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
2007 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002009 // Copy current touch state into tempTouchState.
2010 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2011 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002012 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002013 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002014 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2015 oldState = &(it->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002016 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08002017 }
2018
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002019 bool isSplit = tempTouchState.split;
2020 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2021 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2022 tempTouchState.displayId != displayId);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002023
2024 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2025 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2026 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2027 const bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2028 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002029 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002030 bool wrongDevice = false;
2031 if (newGesture) {
2032 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002033 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002034 ALOGI("Dropping event because a pointer for a different device is already down "
2035 "in display %" PRId32,
2036 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002037 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002038 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002039 switchedDevice = false;
2040 wrongDevice = true;
2041 goto Failed;
2042 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002043 tempTouchState.reset();
2044 tempTouchState.down = down;
2045 tempTouchState.deviceId = entry.deviceId;
2046 tempTouchState.source = entry.source;
2047 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002048 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002049 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002050 ALOGI("Dropping move event because a pointer for a different device is already active "
2051 "in display %" PRId32,
2052 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002053 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002054 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002055 switchedDevice = false;
2056 wrongDevice = true;
2057 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058 }
2059
2060 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2061 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2062
Garfield Tan00f511d2019-06-12 16:55:40 -07002063 int32_t x;
2064 int32_t y;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002065 const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002066 // Always dispatch mouse events to cursor position.
2067 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002068 x = int32_t(entry.xCursorPosition);
2069 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002070 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002071 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2072 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002073 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002074 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Prabir Pradhand65552b2021-10-07 11:23:50 -07002075 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002076 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07002077 isStylus, isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002078
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002080 if (newTouchedWindowHandle == nullptr) {
Arthur Hungb3307ee2021-10-14 10:57:37 +00002081 ALOGD("No new touched window at (%" PRId32 ", %" PRId32 ") in display %" PRId32, x, y,
2082 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002083 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002084 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002085 }
2086
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002087 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002088 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002089 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2090 // New window supports splitting, but we should never split mouse events.
2091 isSplit = !isFromMouse;
2092 } else if (isSplit) {
2093 // New window does not support splitting but we have already split events.
2094 // Ignore the new window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002095 newTouchedWindowHandle = nullptr;
2096 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002097 } else {
2098 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002099 // be delivered to a new window which supports split touch. Pointers from a mouse device
2100 // should never be split.
2101 tempTouchState.split = isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002102 }
2103
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002104 // Update hover state.
Michael Wright3dd60e22019-03-27 22:06:44 +00002105 if (newTouchedWindowHandle != nullptr) {
Garfield Tandf26e862020-07-01 20:18:19 -07002106 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2107 newHoverWindowHandle = nullptr;
2108 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002109 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002110 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002111 }
2112
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002113 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002114 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002115 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002116 // Process the foreground window first so that it is the first to receive the event.
2117 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002118 }
2119
2120 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
2121 const WindowInfo& info = *windowHandle->getInfo();
2122
2123 if (info.paused) {
2124 ALOGI("Not sending touch event to %s because it is paused",
2125 windowHandle->getName().c_str());
2126 continue;
2127 }
2128
2129 // Ensure the window has a connection and the connection is responsive
2130 const bool isResponsive = hasResponsiveConnectionLocked(*windowHandle);
2131 if (!isResponsive) {
2132 ALOGW("Not sending touch gesture to %s because it is not responsive",
2133 windowHandle->getName().c_str());
2134 continue;
2135 }
2136
2137 // Drop events that can't be trusted due to occlusion
2138 if (mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2139 TouchOcclusionInfo occlusionInfo =
2140 computeTouchOcclusionInfoLocked(windowHandle, x, y);
2141 if (!isTouchTrustedLocked(occlusionInfo)) {
2142 if (DEBUG_TOUCH_OCCLUSION) {
2143 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2144 for (const auto& log : occlusionInfo.debugInfo) {
2145 ALOGD("%s", log.c_str());
2146 }
2147 }
2148 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
2149 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2150 ALOGW("Dropping untrusted touch event due to %s/%d",
2151 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2152 continue;
2153 }
2154 }
2155 }
2156
2157 // Drop touch events if requested by input feature
2158 if (shouldDropInput(entry, windowHandle)) {
2159 continue;
2160 }
2161
2162 // Set target flags.
2163 int32_t targetFlags = InputTarget::FLAG_DISPATCH_AS_IS;
2164
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002165 if (!info.isSpy()) {
2166 // There should only be one new foreground (non-spy) window at this location.
2167 targetFlags |= InputTarget::FLAG_FOREGROUND;
2168 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002169
2170 if (isSplit) {
2171 targetFlags |= InputTarget::FLAG_SPLIT;
2172 }
2173 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
2174 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2175 } else if (isWindowObscuredLocked(windowHandle)) {
2176 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2177 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002178
2179 // Update the temporary touch state.
2180 BitSet32 pointerIds;
2181 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002182 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002183 pointerIds.markBit(pointerId);
2184 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002185
2186 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002187 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002188
2189 const std::vector<Monitor> newGestureMonitors = isDown
2190 ? selectResponsiveMonitorsLocked(
2191 getValueByKey(mGestureMonitorsByDisplay, displayId))
2192 : std::vector<Monitor>{};
2193
2194 if (newTouchedWindows.empty() && newGestureMonitors.empty() &&
2195 tempTouchState.gestureMonitors.empty()) {
2196 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
2197 "(%d, %d) in display %" PRId32 ".",
2198 x, y, displayId);
2199 injectionResult = InputEventInjectionResult::FAILED;
2200 goto Failed;
Arthur Hung2ea44b92021-11-23 07:42:21 +00002201 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002202
2203 tempTouchState.addGestureMonitors(newGestureMonitors);
2204
Michael Wrightd02c5b62014-02-10 15:10:22 -08002205 } else {
2206 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2207
2208 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002209 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002210 if (DEBUG_FOCUS) {
2211 ALOGD("Dropping event because the pointer is not down or we previously "
2212 "dropped the pointer down event in display %" PRId32,
2213 displayId);
2214 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002215 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002216 goto Failed;
2217 }
2218
arthurhung6d4bed92021-03-17 11:59:33 +08002219 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002220
Michael Wrightd02c5b62014-02-10 15:10:22 -08002221 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002222 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002223 tempTouchState.isSlippery()) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002224 const int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2225 const int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226
Prabir Pradhand65552b2021-10-07 11:23:50 -07002227 const bool isStylus = isPointerFromStylus(entry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -05002228 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002229 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhand65552b2021-10-07 11:23:50 -07002230 newTouchedWindowHandle =
2231 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002232
2233 // Drop touch events if requested by input feature
2234 if (newTouchedWindowHandle != nullptr &&
2235 shouldDropInput(entry, newTouchedWindowHandle)) {
2236 newTouchedWindowHandle = nullptr;
2237 }
2238
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002239 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2240 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002241 if (DEBUG_FOCUS) {
2242 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2243 oldTouchedWindowHandle->getName().c_str(),
2244 newTouchedWindowHandle->getName().c_str(), displayId);
2245 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002246 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002247 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2248 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2249 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250
2251 // Make a slippery entrance into the new window.
2252 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002253 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002254 }
2255
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002256 int32_t targetFlags =
2257 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002258 if (isSplit) {
2259 targetFlags |= InputTarget::FLAG_SPLIT;
2260 }
2261 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2262 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002263 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2264 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002265 }
2266
2267 BitSet32 pointerIds;
2268 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002269 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002271 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272 }
2273 }
2274 }
2275
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002276 // Update dispatching for hover enter and exit.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002277 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002278 // Let the previous window know that the hover sequence is over, unless we already did
2279 // it when dispatching it as is to newTouchedWindowHandle.
Garfield Tandf26e862020-07-01 20:18:19 -07002280 if (mLastHoverWindowHandle != nullptr &&
2281 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2282 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002283 if (DEBUG_HOVER) {
2284 ALOGD("Sending hover exit event to window %s.",
2285 mLastHoverWindowHandle->getName().c_str());
2286 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002287 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2288 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002289 }
2290
Garfield Tandf26e862020-07-01 20:18:19 -07002291 // Let the new window know that the hover sequence is starting, unless we already did it
2292 // when dispatching it as is to newTouchedWindowHandle.
2293 if (newHoverWindowHandle != nullptr &&
2294 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2295 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002296 if (DEBUG_HOVER) {
2297 ALOGD("Sending hover enter event to window %s.",
2298 newHoverWindowHandle->getName().c_str());
2299 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002300 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2301 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2302 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303 }
2304 }
2305
2306 // Check permission to inject into all touched foreground windows and ensure there
2307 // is at least one touched foreground window.
2308 {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002309 bool haveForegroundOrSpyWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002310 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002311 const bool isForeground =
2312 (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0;
2313 if (touchedWindow.windowHandle->getInfo()->isSpy()) {
2314 haveForegroundOrSpyWindow = true;
2315 LOG_ALWAYS_FATAL_IF(isForeground,
2316 "Spy window cannot be dispatched as a foreground window.");
2317 }
2318 if (isForeground) {
2319 haveForegroundOrSpyWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002320 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002321 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002322 injectionPermission = INJECTION_PERMISSION_DENIED;
2323 goto Failed;
2324 }
2325 }
2326 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002327 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002328 if (!haveForegroundOrSpyWindow && !hasGestureMonitor) {
2329 ALOGI("Dropping event because there is no touched window in display "
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002330 "%" PRId32 " or gesture monitor to receive it.",
2331 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002332 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002333 goto Failed;
2334 }
2335
2336 // Permission granted to injection into all touched foreground windows.
2337 injectionPermission = INJECTION_PERMISSION_GRANTED;
2338 }
2339
2340 // Check whether windows listening for outside touches are owned by the same UID. If it is
2341 // set the policy flag that we will not reveal coordinate information to this window.
2342 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002343 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002344 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002345 if (foregroundWindowHandle) {
2346 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002347 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002348 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002349 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2350 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2351 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002352 InputTarget::FLAG_ZERO_COORDS,
2353 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002354 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002355 }
2356 }
2357 }
2358 }
2359
Michael Wrightd02c5b62014-02-10 15:10:22 -08002360 // If this is the first pointer going down and the touched window has a wallpaper
2361 // then also add the touched wallpaper windows so they are locked in for the duration
2362 // of the touch gesture.
2363 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2364 // engine only supports touch events. We would need to add a mechanism similar
2365 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2366 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002367 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002368 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002369 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002370 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002371 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002372 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2373 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002374 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002375 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002376 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002377 .addOrUpdateWindow(windowHandle,
2378 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2379 InputTarget::
2380 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2381 InputTarget::FLAG_DISPATCH_AS_IS,
2382 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002383 }
2384 }
2385 }
2386 }
2387
2388 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002389 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002390
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002391 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002392 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002393 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002394 }
2395
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002396 for (const auto& monitor : tempTouchState.gestureMonitors) {
2397 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002398 }
2399
Michael Wrightd02c5b62014-02-10 15:10:22 -08002400 // Drop the outside or hover touch windows since we will not care about them
2401 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002402 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002403
2404Failed:
2405 // Check injection permission once and for all.
2406 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002407 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002408 injectionPermission = INJECTION_PERMISSION_GRANTED;
2409 } else {
2410 injectionPermission = INJECTION_PERMISSION_DENIED;
2411 }
2412 }
2413
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002414 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2415 return injectionResult;
2416 }
2417
Michael Wrightd02c5b62014-02-10 15:10:22 -08002418 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002419 if (!wrongDevice) {
2420 if (switchedDevice) {
2421 if (DEBUG_FOCUS) {
2422 ALOGD("Conflicting pointer actions: Switched to a different device.");
2423 }
2424 *outConflictingPointerActions = true;
2425 }
2426
2427 if (isHoverAction) {
2428 // Started hovering, therefore no longer down.
2429 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002430 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002431 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2432 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002433 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002434 *outConflictingPointerActions = true;
2435 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002436 tempTouchState.reset();
2437 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2438 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2439 tempTouchState.deviceId = entry.deviceId;
2440 tempTouchState.source = entry.source;
2441 tempTouchState.displayId = displayId;
2442 }
2443 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2444 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2445 // All pointers up or canceled.
2446 tempTouchState.reset();
2447 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2448 // First pointer went down.
2449 if (oldState && oldState->down) {
2450 if (DEBUG_FOCUS) {
2451 ALOGD("Conflicting pointer actions: Down received while already down.");
2452 }
2453 *outConflictingPointerActions = true;
2454 }
2455 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2456 // One pointer went up.
2457 if (isSplit) {
2458 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2459 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002460
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002461 for (size_t i = 0; i < tempTouchState.windows.size();) {
2462 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2463 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2464 touchedWindow.pointerIds.clearBit(pointerId);
2465 if (touchedWindow.pointerIds.isEmpty()) {
2466 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2467 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002468 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002469 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002470 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002471 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002472 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002473 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002474
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002475 // Save changes unless the action was scroll in which case the temporary touch
2476 // state was only valid for this one action.
2477 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2478 if (tempTouchState.displayId >= 0) {
2479 mTouchStatesByDisplay[displayId] = tempTouchState;
2480 } else {
2481 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002482 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002483 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002484
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002485 // Update hover state.
2486 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002487 }
2488
Michael Wrightd02c5b62014-02-10 15:10:22 -08002489 return injectionResult;
2490}
2491
arthurhung6d4bed92021-03-17 11:59:33 +08002492void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002493 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2494 // have an explicit reason to support it.
2495 constexpr bool isStylus = false;
2496
chaviw98318de2021-05-19 16:45:23 -05002497 const sp<WindowInfoHandle> dropWindow =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002498 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002499 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002500 if (dropWindow) {
2501 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002502 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002503 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002504 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002505 }
2506 mDragState.reset();
2507}
2508
2509void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2510 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002511 return;
2512 }
2513
arthurhung6d4bed92021-03-17 11:59:33 +08002514 if (!mDragState->isStartDrag) {
2515 mDragState->isStartDrag = true;
2516 mDragState->isStylusButtonDownAtStart =
2517 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2518 }
2519
arthurhungb89ccb02020-12-30 16:19:01 +08002520 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2521 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2522 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2523 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002524 // Handle the special case : stylus button no longer pressed.
2525 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2526 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2527 finishDragAndDrop(entry.displayId, x, y);
2528 return;
2529 }
2530
Prabir Pradhand65552b2021-10-07 11:23:50 -07002531 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until
2532 // we have an explicit reason to support it.
2533 constexpr bool isStylus = false;
2534
chaviw98318de2021-05-19 16:45:23 -05002535 const sp<WindowInfoHandle> hoverWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002536 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002537 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002538 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002539 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2540 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2541 if (mDragState->dragHoverWindowHandle != nullptr) {
2542 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2543 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002544 }
arthurhung6d4bed92021-03-17 11:59:33 +08002545 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002546 }
2547 // enqueue drag location if needed.
2548 if (hoverWindowHandle != nullptr) {
2549 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2550 }
arthurhung6d4bed92021-03-17 11:59:33 +08002551 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2552 finishDragAndDrop(entry.displayId, x, y);
2553 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002554 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002555 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002556 }
2557}
2558
chaviw98318de2021-05-19 16:45:23 -05002559void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002560 int32_t targetFlags, BitSet32 pointerIds,
2561 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002562 std::vector<InputTarget>::iterator it =
2563 std::find_if(inputTargets.begin(), inputTargets.end(),
2564 [&windowHandle](const InputTarget& inputTarget) {
2565 return inputTarget.inputChannel->getConnectionToken() ==
2566 windowHandle->getToken();
2567 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002568
chaviw98318de2021-05-19 16:45:23 -05002569 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002570
2571 if (it == inputTargets.end()) {
2572 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002573 std::shared_ptr<InputChannel> inputChannel =
2574 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002575 if (inputChannel == nullptr) {
2576 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2577 return;
2578 }
2579 inputTarget.inputChannel = inputChannel;
2580 inputTarget.flags = targetFlags;
2581 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002582 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2583 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002584 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002585 } else {
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00002586 ALOGE("DisplayInfo not found for window on display: %d", windowInfo->displayId);
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002587 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002588 inputTargets.push_back(inputTarget);
2589 it = inputTargets.end() - 1;
2590 }
2591
2592 ALOG_ASSERT(it->flags == targetFlags);
2593 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2594
chaviw1ff3d1e2020-07-01 15:53:47 -07002595 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002596}
2597
Michael Wright3dd60e22019-03-27 22:06:44 +00002598void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002599 int32_t displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002600 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2601 mGlobalMonitorsByDisplay.find(displayId);
2602
2603 if (it != mGlobalMonitorsByDisplay.end()) {
2604 const std::vector<Monitor>& monitors = it->second;
2605 for (const Monitor& monitor : monitors) {
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002606 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002607 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002608 }
2609}
2610
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002611void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002612 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002613 InputTarget target;
2614 target.inputChannel = monitor.inputChannel;
2615 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002616 ui::Transform t;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002617 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
Prabir Pradhanb5402b22021-10-04 05:52:50 -07002618 const auto& displayTransform = it->second.transform;
2619 target.displayTransform = displayTransform;
2620 t = displayTransform;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002621 }
chaviw1ff3d1e2020-07-01 15:53:47 -07002622 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002623 inputTargets.push_back(target);
2624}
2625
chaviw98318de2021-05-19 16:45:23 -05002626bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002627 const InjectionState* injectionState) {
2628 if (injectionState &&
2629 (windowHandle == nullptr ||
2630 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2631 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002632 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002633 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002634 "owned by uid %d",
2635 injectionState->injectorPid, injectionState->injectorUid,
2636 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002637 } else {
2638 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002639 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002640 }
2641 return false;
2642 }
2643 return true;
2644}
2645
Robert Carrc9bf1d32020-04-13 17:21:08 -07002646/**
2647 * Indicate whether one window handle should be considered as obscuring
2648 * another window handle. We only check a few preconditions. Actually
2649 * checking the bounds is left to the caller.
2650 */
chaviw98318de2021-05-19 16:45:23 -05002651static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2652 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002653 // Compare by token so cloned layers aren't counted
2654 if (haveSameToken(windowHandle, otherHandle)) {
2655 return false;
2656 }
2657 auto info = windowHandle->getInfo();
2658 auto otherInfo = otherHandle->getInfo();
2659 if (!otherInfo->visible) {
2660 return false;
chaviw98318de2021-05-19 16:45:23 -05002661 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002662 // Those act as if they were invisible, so we don't need to flag them.
2663 // We do want to potentially flag touchable windows even if they have 0
2664 // opacity, since they can consume touches and alter the effects of the
2665 // user interaction (eg. apps that rely on
2666 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2667 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2668 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002669 } else if (info->ownerUid == otherInfo->ownerUid) {
2670 // If ownerUid is the same we don't generate occlusion events as there
2671 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002672 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002673 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002674 return false;
2675 } else if (otherInfo->displayId != info->displayId) {
2676 return false;
2677 }
2678 return true;
2679}
2680
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002681/**
2682 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2683 * untrusted, one should check:
2684 *
2685 * 1. If result.hasBlockingOcclusion is true.
2686 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2687 * BLOCK_UNTRUSTED.
2688 *
2689 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2690 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2691 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2692 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2693 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2694 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2695 *
2696 * If neither of those is true, then it means the touch can be allowed.
2697 */
2698InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002699 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2700 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002701 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002702 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002703 TouchOcclusionInfo info;
2704 info.hasBlockingOcclusion = false;
2705 info.obscuringOpacity = 0;
2706 info.obscuringUid = -1;
2707 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002708 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002709 if (windowHandle == otherHandle) {
2710 break; // All future windows are below us. Exit early.
2711 }
chaviw98318de2021-05-19 16:45:23 -05002712 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002713 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2714 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002715 if (DEBUG_TOUCH_OCCLUSION) {
2716 info.debugInfo.push_back(
2717 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2718 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002719 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2720 // we perform the checks below to see if the touch can be propagated or not based on the
2721 // window's touch occlusion mode
2722 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2723 info.hasBlockingOcclusion = true;
2724 info.obscuringUid = otherInfo->ownerUid;
2725 info.obscuringPackage = otherInfo->packageName;
2726 break;
2727 }
2728 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2729 uint32_t uid = otherInfo->ownerUid;
2730 float opacity =
2731 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2732 // Given windows A and B:
2733 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2734 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2735 opacityByUid[uid] = opacity;
2736 if (opacity > info.obscuringOpacity) {
2737 info.obscuringOpacity = opacity;
2738 info.obscuringUid = uid;
2739 info.obscuringPackage = otherInfo->packageName;
2740 }
2741 }
2742 }
2743 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002744 if (DEBUG_TOUCH_OCCLUSION) {
2745 info.debugInfo.push_back(
2746 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2747 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002748 return info;
2749}
2750
chaviw98318de2021-05-19 16:45:23 -05002751std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002752 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002753 return StringPrintf(INDENT2
2754 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2755 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2756 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2757 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002758 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002759 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002760 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2761 info->frameTop, info->frameRight, info->frameBottom,
2762 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002763 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2764 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2765 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002766}
2767
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002768bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2769 if (occlusionInfo.hasBlockingOcclusion) {
2770 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2771 occlusionInfo.obscuringUid);
2772 return false;
2773 }
2774 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2775 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2776 "%.2f, maximum allowed = %.2f)",
2777 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2778 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2779 return false;
2780 }
2781 return true;
2782}
2783
chaviw98318de2021-05-19 16:45:23 -05002784bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002785 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002786 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002787 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2788 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002789 if (windowHandle == otherHandle) {
2790 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002791 }
chaviw98318de2021-05-19 16:45:23 -05002792 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002793 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002794 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 return true;
2796 }
2797 }
2798 return false;
2799}
2800
chaviw98318de2021-05-19 16:45:23 -05002801bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002802 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002803 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2804 const WindowInfo* windowInfo = windowHandle->getInfo();
2805 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002806 if (windowHandle == otherHandle) {
2807 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002808 }
chaviw98318de2021-05-19 16:45:23 -05002809 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002810 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002811 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002812 return true;
2813 }
2814 }
2815 return false;
2816}
2817
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002818std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002819 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002820 if (applicationHandle != nullptr) {
2821 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002822 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002823 } else {
2824 return applicationHandle->getName();
2825 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002826 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002827 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002828 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002829 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830 }
2831}
2832
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002833void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002834 if (!isUserActivityEvent(eventEntry)) {
2835 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002836 return;
2837 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002838 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002839 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002840 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002841 const WindowInfo* info = focusedWindowHandle->getInfo();
2842 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002843 if (DEBUG_DISPATCH_CYCLE) {
2844 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2845 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002846 return;
2847 }
2848 }
2849
2850 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002851 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002852 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002853 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2854 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002855 return;
2856 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002857
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002858 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002859 eventType = USER_ACTIVITY_EVENT_TOUCH;
2860 }
2861 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002862 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002863 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002864 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2865 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002866 return;
2867 }
2868 eventType = USER_ACTIVITY_EVENT_BUTTON;
2869 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002870 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002871 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002872 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002873 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002874 break;
2875 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002876 }
2877
Prabir Pradhancef936d2021-07-21 16:17:52 +00002878 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2879 REQUIRES(mLock) {
2880 scoped_unlock unlock(mLock);
2881 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2882 };
2883 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002884}
2885
2886void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002887 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002888 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002889 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002890 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002891 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002892 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002893 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002894 ATRACE_NAME(message.c_str());
2895 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002896 if (DEBUG_DISPATCH_CYCLE) {
2897 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2898 "globalScaleFactor=%f, pointerIds=0x%x %s",
2899 connection->getInputChannelName().c_str(), inputTarget.flags,
2900 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2901 inputTarget.getPointerInfoString().c_str());
2902 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002903
2904 // Skip this event if the connection status is not normal.
2905 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002906 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002907 if (DEBUG_DISPATCH_CYCLE) {
2908 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002909 connection->getInputChannelName().c_str(),
2910 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002911 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002912 return;
2913 }
2914
2915 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002916 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2917 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2918 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002919 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002920
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002921 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002922 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002923 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002924 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002925 if (!splitMotionEntry) {
2926 return; // split event was dropped
2927 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00002928 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
2929 std::string reason = std::string("reason=pointer cancel on split window");
2930 android_log_event_list(LOGTAG_INPUT_CANCEL)
2931 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
2932 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002933 if (DEBUG_FOCUS) {
2934 ALOGD("channel '%s' ~ Split motion event.",
2935 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002936 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002937 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002938 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2939 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002940 return;
2941 }
2942 }
2943
2944 // Not splitting. Enqueue dispatch entries for the event as is.
2945 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2946}
2947
2948void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002949 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002950 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002951 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002952 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002953 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002954 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002955 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002956 ATRACE_NAME(message.c_str());
2957 }
2958
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002959 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002960
2961 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002962 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002963 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002964 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002965 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002966 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002967 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002968 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002969 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002970 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002971 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002972 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002973 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002974
2975 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002976 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977 startDispatchCycleLocked(currentTime, connection);
2978 }
2979}
2980
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002981void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002982 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002983 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002984 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002985 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002986 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2987 connection->getInputChannelName().c_str(),
2988 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002989 ATRACE_NAME(message.c_str());
2990 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002991 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002992 if (!(inputTargetFlags & dispatchMode)) {
2993 return;
2994 }
2995 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2996
2997 // This is a new event.
2998 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002999 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003000 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003001
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003002 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3003 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003004 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003006 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003007 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003008 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003009 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003010 dispatchEntry->resolvedAction = keyEntry.action;
3011 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003012
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003013 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
3014 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003015 if (DEBUG_DISPATCH_CYCLE) {
3016 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
3017 "event",
3018 connection->getInputChannelName().c_str());
3019 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003020 return; // skip the inconsistent event
3021 }
3022 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003024
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003025 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003026 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003027 // Assign a default value to dispatchEntry that will never be generated by InputReader,
3028 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
3029 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
3030 static_cast<int32_t>(IdGenerator::Source::OTHER);
3031 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003032 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3033 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
3034 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
3035 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3036 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
3037 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3038 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
3039 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3040 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
3041 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3042 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003043 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003044 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003045 }
3046 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003047 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3048 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003049 if (DEBUG_DISPATCH_CYCLE) {
3050 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
3051 "enter event",
3052 connection->getInputChannelName().c_str());
3053 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003054 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3055 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003056 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3057 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003058
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003059 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003060 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3061 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3062 }
3063 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3064 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3065 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003066
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003067 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3068 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003069 if (DEBUG_DISPATCH_CYCLE) {
3070 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3071 "event",
3072 connection->getInputChannelName().c_str());
3073 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003074 return; // skip the inconsistent event
3075 }
3076
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003077 dispatchEntry->resolvedEventId =
3078 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3079 ? mIdGenerator.nextId()
3080 : motionEntry.id;
3081 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3082 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3083 ") to MotionEvent(id=0x%" PRIx32 ").",
3084 motionEntry.id, dispatchEntry->resolvedEventId);
3085 ATRACE_NAME(message.c_str());
3086 }
3087
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003088 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3089 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3090 // Skip reporting pointer down outside focus to the policy.
3091 break;
3092 }
3093
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003094 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003095 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003096
3097 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003098 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003099 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003100 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003101 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3102 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003103 break;
3104 }
Chris Yef59a2f42020-10-16 12:55:26 -07003105 case EventEntry::Type::SENSOR: {
3106 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3107 break;
3108 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003109 case EventEntry::Type::CONFIGURATION_CHANGED:
3110 case EventEntry::Type::DEVICE_RESET: {
3111 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003112 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003113 break;
3114 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003115 }
3116
3117 // Remember that we are waiting for this dispatch to complete.
3118 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003119 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003120 }
3121
3122 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003123 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003124 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003125}
3126
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003127/**
3128 * This function is purely for debugging. It helps us understand where the user interaction
3129 * was taking place. For example, if user is touching launcher, we will see a log that user
3130 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3131 * We will see both launcher and wallpaper in that list.
3132 * Once the interaction with a particular set of connections starts, no new logs will be printed
3133 * until the set of interacted connections changes.
3134 *
3135 * The following items are skipped, to reduce the logspam:
3136 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3137 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3138 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3139 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3140 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003141 */
3142void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3143 const std::vector<InputTarget>& targets) {
3144 // Skip ACTION_UP events, and all events other than keys and motions
3145 if (entry.type == EventEntry::Type::KEY) {
3146 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3147 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3148 return;
3149 }
3150 } else if (entry.type == EventEntry::Type::MOTION) {
3151 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3152 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3153 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3154 return;
3155 }
3156 } else {
3157 return; // Not a key or a motion
3158 }
3159
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003160 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003161 std::vector<sp<Connection>> newConnections;
3162 for (const InputTarget& target : targets) {
3163 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3164 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3165 continue; // Skip windows that receive ACTION_OUTSIDE
3166 }
3167
3168 sp<IBinder> token = target.inputChannel->getConnectionToken();
3169 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003170 if (connection == nullptr) {
3171 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003172 }
3173 newConnectionTokens.insert(std::move(token));
3174 newConnections.emplace_back(connection);
3175 }
3176 if (newConnectionTokens == mInteractionConnectionTokens) {
3177 return; // no change
3178 }
3179 mInteractionConnectionTokens = newConnectionTokens;
3180
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003181 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003182 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003183 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003184 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003185 std::string message = "Interaction with: " + targetList;
3186 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003187 message += "<none>";
3188 }
3189 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3190}
3191
chaviwfd6d3512019-03-25 13:23:49 -07003192void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003193 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003194 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003195 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3196 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003197 return;
3198 }
3199
Vishnu Nairc519ff72021-01-21 08:23:08 -08003200 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003201 if (focusedToken == token) {
3202 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003203 return;
3204 }
3205
Prabir Pradhancef936d2021-07-21 16:17:52 +00003206 auto command = [this, token]() REQUIRES(mLock) {
3207 scoped_unlock unlock(mLock);
3208 mPolicy->onPointerDownOutsideFocus(token);
3209 };
3210 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003211}
3212
3213void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003214 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003215 if (ATRACE_ENABLED()) {
3216 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003217 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003218 ATRACE_NAME(message.c_str());
3219 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003220 if (DEBUG_DISPATCH_CYCLE) {
3221 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3222 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003223
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003224 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003225 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003226 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003227 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003228 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003229 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003230
3231 // Publish the event.
3232 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003233 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3234 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003235 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003236 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3237 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003239 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003240 status = connection->inputPublisher
3241 .publishKeyEvent(dispatchEntry->seq,
3242 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3243 keyEntry.source, keyEntry.displayId,
3244 std::move(hmac), dispatchEntry->resolvedAction,
3245 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3246 keyEntry.scanCode, keyEntry.metaState,
3247 keyEntry.repeatCount, keyEntry.downTime,
3248 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003249 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003250 }
3251
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003252 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003253 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003254
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003255 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003256 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003257
chaviw82357092020-01-28 13:13:06 -08003258 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003259 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003260 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3261 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003262 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003263 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3264 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003265 // Don't apply window scale here since we don't want scale to affect raw
3266 // coordinates. The scale will be sent back to the client and applied
3267 // later when requesting relative coordinates.
3268 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3269 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003270 }
3271 usingCoords = scaledCoords;
3272 }
3273 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003274 // We don't want the dispatch target to know.
3275 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003276 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003277 scaledCoords[i].clear();
3278 }
3279 usingCoords = scaledCoords;
3280 }
3281 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003282
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003283 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003284
3285 // Publish the motion event.
3286 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003287 .publishMotionEvent(dispatchEntry->seq,
3288 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003289 motionEntry.deviceId, motionEntry.source,
3290 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003291 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003292 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003293 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003294 motionEntry.edgeFlags, motionEntry.metaState,
3295 motionEntry.buttonState,
3296 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003297 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003298 motionEntry.xPrecision, motionEntry.yPrecision,
3299 motionEntry.xCursorPosition,
3300 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003301 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003302 motionEntry.downTime, motionEntry.eventTime,
3303 motionEntry.pointerCount,
3304 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003305 break;
3306 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003307
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003308 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003309 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003310 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003311 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003312 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003313 break;
3314 }
3315
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003316 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3317 const TouchModeEntry& touchModeEntry =
3318 static_cast<const TouchModeEntry&>(eventEntry);
3319 status = connection->inputPublisher
3320 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3321 touchModeEntry.inTouchMode);
3322
3323 break;
3324 }
3325
Prabir Pradhan99987712020-11-10 18:43:05 -08003326 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3327 const auto& captureEntry =
3328 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3329 status = connection->inputPublisher
3330 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003331 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003332 break;
3333 }
3334
arthurhungb89ccb02020-12-30 16:19:01 +08003335 case EventEntry::Type::DRAG: {
3336 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3337 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3338 dragEntry.id, dragEntry.x,
3339 dragEntry.y,
3340 dragEntry.isExiting);
3341 break;
3342 }
3343
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003344 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003345 case EventEntry::Type::DEVICE_RESET:
3346 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003347 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003348 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003349 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003350 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003351 }
3352
3353 // Check the result.
3354 if (status) {
3355 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003356 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003357 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003358 "This is unexpected because the wait queue is empty, so the pipe "
3359 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003360 "event to it, status=%s(%d)",
3361 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3362 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003363 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3364 } else {
3365 // Pipe is full and we are waiting for the app to finish process some events
3366 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003367 if (DEBUG_DISPATCH_CYCLE) {
3368 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3369 "waiting for the application to catch up",
3370 connection->getInputChannelName().c_str());
3371 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003372 }
3373 } else {
3374 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003375 "status=%s(%d)",
3376 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3377 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3379 }
3380 return;
3381 }
3382
3383 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003384 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3385 connection->outboundQueue.end(),
3386 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003387 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003388 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003389 if (connection->responsive) {
3390 mAnrTracker.insert(dispatchEntry->timeoutTime,
3391 connection->inputChannel->getConnectionToken());
3392 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003393 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003394 }
3395}
3396
chaviw09c8d2d2020-08-24 15:48:26 -07003397std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3398 size_t size;
3399 switch (event.type) {
3400 case VerifiedInputEvent::Type::KEY: {
3401 size = sizeof(VerifiedKeyEvent);
3402 break;
3403 }
3404 case VerifiedInputEvent::Type::MOTION: {
3405 size = sizeof(VerifiedMotionEvent);
3406 break;
3407 }
3408 }
3409 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3410 return mHmacKeyManager.sign(start, size);
3411}
3412
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003413const std::array<uint8_t, 32> InputDispatcher::getSignature(
3414 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003415 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3416 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003417 // Only sign events up and down events as the purely move events
3418 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003419 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003420 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003421
3422 VerifiedMotionEvent verifiedEvent =
3423 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3424 verifiedEvent.actionMasked = actionMasked;
3425 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3426 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003427}
3428
3429const std::array<uint8_t, 32> InputDispatcher::getSignature(
3430 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3431 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3432 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3433 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003434 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003435}
3436
Michael Wrightd02c5b62014-02-10 15:10:22 -08003437void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003438 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003439 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003440 if (DEBUG_DISPATCH_CYCLE) {
3441 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3442 connection->getInputChannelName().c_str(), seq, toString(handled));
3443 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003445 if (connection->status == Connection::Status::BROKEN ||
3446 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003447 return;
3448 }
3449
3450 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003451 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3452 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3453 };
3454 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003455}
3456
3457void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003458 const sp<Connection>& connection,
3459 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003460 if (DEBUG_DISPATCH_CYCLE) {
3461 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3462 connection->getInputChannelName().c_str(), toString(notify));
3463 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003464
3465 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003466 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003467 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003468 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003469 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003470
3471 // The connection appears to be unrecoverably broken.
3472 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003473 if (connection->status == Connection::Status::NORMAL) {
3474 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003475
3476 if (notify) {
3477 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003478 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3479 connection->getInputChannelName().c_str());
3480
3481 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003482 scoped_unlock unlock(mLock);
3483 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3484 };
3485 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003486 }
3487 }
3488}
3489
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003490void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3491 while (!queue.empty()) {
3492 DispatchEntry* dispatchEntry = queue.front();
3493 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003494 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003495 }
3496}
3497
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003498void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003499 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003500 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003501 }
3502 delete dispatchEntry;
3503}
3504
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003505int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3506 std::scoped_lock _l(mLock);
3507 sp<Connection> connection = getConnectionLocked(connectionToken);
3508 if (connection == nullptr) {
3509 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3510 connectionToken.get(), events);
3511 return 0; // remove the callback
3512 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003513
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003514 bool notify;
3515 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3516 if (!(events & ALOOPER_EVENT_INPUT)) {
3517 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3518 "events=0x%x",
3519 connection->getInputChannelName().c_str(), events);
3520 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003521 }
3522
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003523 nsecs_t currentTime = now();
3524 bool gotOne = false;
3525 status_t status = OK;
3526 for (;;) {
3527 Result<InputPublisher::ConsumerResponse> result =
3528 connection->inputPublisher.receiveConsumerResponse();
3529 if (!result.ok()) {
3530 status = result.error().code();
3531 break;
3532 }
3533
3534 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3535 const InputPublisher::Finished& finish =
3536 std::get<InputPublisher::Finished>(*result);
3537 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3538 finish.consumeTime);
3539 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003540 if (shouldReportMetricsForConnection(*connection)) {
3541 const InputPublisher::Timeline& timeline =
3542 std::get<InputPublisher::Timeline>(*result);
3543 mLatencyTracker
3544 .trackGraphicsLatency(timeline.inputEventId,
3545 connection->inputChannel->getConnectionToken(),
3546 std::move(timeline.graphicsTimeline));
3547 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003548 }
3549 gotOne = true;
3550 }
3551 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003552 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003553 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003554 return 1;
3555 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556 }
3557
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003558 notify = status != DEAD_OBJECT || !connection->monitor;
3559 if (notify) {
3560 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3561 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3562 status);
3563 }
3564 } else {
3565 // Monitor channels are never explicitly unregistered.
3566 // We do it automatically when the remote endpoint is closed so don't warn about them.
3567 const bool stillHaveWindowHandle =
3568 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3569 notify = !connection->monitor && stillHaveWindowHandle;
3570 if (notify) {
3571 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3572 connection->getInputChannelName().c_str(), events);
3573 }
3574 }
3575
3576 // Remove the channel.
3577 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3578 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579}
3580
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003581void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003582 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003583 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003584 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003585 }
3586}
3587
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003588void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003589 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003590 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3591 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3592}
3593
3594void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3595 const CancelationOptions& options,
3596 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3597 for (const auto& it : monitorsByDisplay) {
3598 const std::vector<Monitor>& monitors = it.second;
3599 for (const Monitor& monitor : monitors) {
3600 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003601 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003602 }
3603}
3604
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003606 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003607 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003608 if (connection == nullptr) {
3609 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003610 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003611
3612 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003613}
3614
3615void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3616 const sp<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003617 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003618 return;
3619 }
3620
3621 nsecs_t currentTime = now();
3622
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003623 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003624 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003625
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003626 if (cancelationEvents.empty()) {
3627 return;
3628 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003629 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3630 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3631 "with reality: %s, mode=%d.",
3632 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3633 options.mode);
3634 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003635
Arthur Hungb3307ee2021-10-14 10:57:37 +00003636 std::string reason = std::string("reason=").append(options.reason);
3637 android_log_event_list(LOGTAG_INPUT_CANCEL)
3638 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3639
Svet Ganov5d3bc372020-01-26 23:11:07 -08003640 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003641 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003642 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3643 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003644 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003645 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003646 target.globalScaleFactor = windowInfo->globalScaleFactor;
3647 }
3648 target.inputChannel = connection->inputChannel;
3649 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3650
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003651 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003652 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003653 switch (cancelationEventEntry->type) {
3654 case EventEntry::Type::KEY: {
3655 logOutboundKeyDetails("cancel - ",
3656 static_cast<const KeyEntry&>(*cancelationEventEntry));
3657 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003658 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003659 case EventEntry::Type::MOTION: {
3660 logOutboundMotionDetails("cancel - ",
3661 static_cast<const MotionEntry&>(*cancelationEventEntry));
3662 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003663 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003664 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003665 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003666 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3667 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003668 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003669 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003670 break;
3671 }
3672 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003673 case EventEntry::Type::DEVICE_RESET:
3674 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003675 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003676 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003677 break;
3678 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003679 }
3680
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003681 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3682 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003683 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003684
3685 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003686}
3687
Svet Ganov5d3bc372020-01-26 23:11:07 -08003688void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3689 const sp<Connection>& connection) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003690 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003691 return;
3692 }
3693
3694 nsecs_t currentTime = now();
3695
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003696 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003697 connection->inputState.synthesizePointerDownEvents(currentTime);
3698
3699 if (downEvents.empty()) {
3700 return;
3701 }
3702
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003703 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003704 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3705 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003706 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003707
3708 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003709 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003710 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3711 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003712 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003713 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003714 target.globalScaleFactor = windowInfo->globalScaleFactor;
3715 }
3716 target.inputChannel = connection->inputChannel;
3717 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3718
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003719 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003720 switch (downEventEntry->type) {
3721 case EventEntry::Type::MOTION: {
3722 logOutboundMotionDetails("down - ",
3723 static_cast<const MotionEntry&>(*downEventEntry));
3724 break;
3725 }
3726
3727 case EventEntry::Type::KEY:
3728 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003729 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003730 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003731 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003732 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003733 case EventEntry::Type::SENSOR:
3734 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003735 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003736 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003737 break;
3738 }
3739 }
3740
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003741 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3742 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003743 }
3744
3745 startDispatchCycleLocked(currentTime, connection);
3746}
3747
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003748std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3749 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003750 ALOG_ASSERT(pointerIds.value != 0);
3751
3752 uint32_t splitPointerIndexMap[MAX_POINTERS];
3753 PointerProperties splitPointerProperties[MAX_POINTERS];
3754 PointerCoords splitPointerCoords[MAX_POINTERS];
3755
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003756 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003757 uint32_t splitPointerCount = 0;
3758
3759 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003760 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003761 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003762 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003763 uint32_t pointerId = uint32_t(pointerProperties.id);
3764 if (pointerIds.hasBit(pointerId)) {
3765 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3766 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3767 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003768 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769 splitPointerCount += 1;
3770 }
3771 }
3772
3773 if (splitPointerCount != pointerIds.count()) {
3774 // This is bad. We are missing some of the pointers that we expected to deliver.
3775 // Most likely this indicates that we received an ACTION_MOVE events that has
3776 // different pointer ids than we expected based on the previous ACTION_DOWN
3777 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3778 // in this way.
3779 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003780 "we expected there to be %d pointers. This probably means we received "
3781 "a broken sequence of pointer ids from the input device.",
3782 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003783 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784 }
3785
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003786 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003787 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003788 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3789 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3791 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003792 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 uint32_t pointerId = uint32_t(pointerProperties.id);
3794 if (pointerIds.hasBit(pointerId)) {
3795 if (pointerIds.count() == 1) {
3796 // The first/last pointer went down/up.
3797 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003798 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003799 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3800 ? AMOTION_EVENT_ACTION_CANCEL
3801 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003802 } else {
3803 // A secondary pointer went down/up.
3804 uint32_t splitPointerIndex = 0;
3805 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3806 splitPointerIndex += 1;
3807 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003808 action = maskedAction |
3809 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003810 }
3811 } else {
3812 // An unrelated pointer changed.
3813 action = AMOTION_EVENT_ACTION_MOVE;
3814 }
3815 }
3816
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003817 int32_t newId = mIdGenerator.nextId();
3818 if (ATRACE_ENABLED()) {
3819 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3820 ") to MotionEvent(id=0x%" PRIx32 ").",
3821 originalMotionEntry.id, newId);
3822 ATRACE_NAME(message.c_str());
3823 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003824 std::unique_ptr<MotionEntry> splitMotionEntry =
3825 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3826 originalMotionEntry.deviceId, originalMotionEntry.source,
3827 originalMotionEntry.displayId,
3828 originalMotionEntry.policyFlags, action,
3829 originalMotionEntry.actionButton,
3830 originalMotionEntry.flags, originalMotionEntry.metaState,
3831 originalMotionEntry.buttonState,
3832 originalMotionEntry.classification,
3833 originalMotionEntry.edgeFlags,
3834 originalMotionEntry.xPrecision,
3835 originalMotionEntry.yPrecision,
3836 originalMotionEntry.xCursorPosition,
3837 originalMotionEntry.yCursorPosition,
3838 originalMotionEntry.downTime, splitPointerCount,
Alex Chauf7c99f32021-12-03 10:37:54 +00003839 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003840
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003841 if (originalMotionEntry.injectionState) {
3842 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003843 splitMotionEntry->injectionState->refCount += 1;
3844 }
3845
3846 return splitMotionEntry;
3847}
3848
3849void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003850 if (DEBUG_INBOUND_EVENT_DETAILS) {
3851 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3852 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853
Antonio Kantekf16f2832021-09-28 04:39:20 +00003854 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003855 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003856 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003857
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003858 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3859 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3860 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003861 } // release lock
3862
3863 if (needWake) {
3864 mLooper->wake();
3865 }
3866}
3867
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003868/**
3869 * If one of the meta shortcuts is detected, process them here:
3870 * Meta + Backspace -> generate BACK
3871 * Meta + Enter -> generate HOME
3872 * This will potentially overwrite keyCode and metaState.
3873 */
3874void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003875 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003876 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3877 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3878 if (keyCode == AKEYCODE_DEL) {
3879 newKeyCode = AKEYCODE_BACK;
3880 } else if (keyCode == AKEYCODE_ENTER) {
3881 newKeyCode = AKEYCODE_HOME;
3882 }
3883 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003884 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003885 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003886 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003887 keyCode = newKeyCode;
3888 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3889 }
3890 } else if (action == AKEY_EVENT_ACTION_UP) {
3891 // In order to maintain a consistent stream of up and down events, check to see if the key
3892 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3893 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003894 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003895 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003896 auto replacementIt = mReplacedKeys.find(replacement);
3897 if (replacementIt != mReplacedKeys.end()) {
3898 keyCode = replacementIt->second;
3899 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003900 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3901 }
3902 }
3903}
3904
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003906 if (DEBUG_INBOUND_EVENT_DETAILS) {
3907 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3908 "policyFlags=0x%x, action=0x%x, "
3909 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3910 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3911 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3912 args->downTime);
3913 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914 if (!validateKeyEvent(args->action)) {
3915 return;
3916 }
3917
3918 uint32_t policyFlags = args->policyFlags;
3919 int32_t flags = args->flags;
3920 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003921 // InputDispatcher tracks and generates key repeats on behalf of
3922 // whatever notifies it, so repeatCount should always be set to 0
3923 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003924 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3925 policyFlags |= POLICY_FLAG_VIRTUAL;
3926 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3927 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003928 if (policyFlags & POLICY_FLAG_FUNCTION) {
3929 metaState |= AMETA_FUNCTION_ON;
3930 }
3931
3932 policyFlags |= POLICY_FLAG_TRUSTED;
3933
Michael Wright78f24442014-08-06 15:55:28 -07003934 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003935 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003936
Michael Wrightd02c5b62014-02-10 15:10:22 -08003937 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003938 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003939 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3940 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003941
Michael Wright2b3c3302018-03-02 17:19:13 +00003942 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003943 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003944 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3945 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003946 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003947 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003948
Antonio Kantekf16f2832021-09-28 04:39:20 +00003949 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950 { // acquire lock
3951 mLock.lock();
3952
3953 if (shouldSendKeyToInputFilterLocked(args)) {
3954 mLock.unlock();
3955
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003956 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003957 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3958 return; // event was consumed by the filter
3959 }
3960
3961 mLock.lock();
3962 }
3963
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003964 std::unique_ptr<KeyEntry> newEntry =
3965 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3966 args->displayId, policyFlags, args->action, flags,
3967 keyCode, args->scanCode, metaState, repeatCount,
3968 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003969
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003970 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003971 mLock.unlock();
3972 } // release lock
3973
3974 if (needWake) {
3975 mLooper->wake();
3976 }
3977}
3978
3979bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3980 return mInputFilterEnabled;
3981}
3982
3983void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003984 if (DEBUG_INBOUND_EVENT_DETAILS) {
3985 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3986 "displayId=%" PRId32 ", policyFlags=0x%x, "
3987 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3988 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3989 "yCursorPosition=%f, downTime=%" PRId64,
3990 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3991 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3992 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3993 args->xCursorPosition, args->yCursorPosition, args->downTime);
3994 for (uint32_t i = 0; i < args->pointerCount; i++) {
3995 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3996 "x=%f, y=%f, pressure=%f, size=%f, "
3997 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3998 "orientation=%f",
3999 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
4000 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4001 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4002 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4003 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4004 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4005 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4006 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4007 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4008 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
4009 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004010 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004011 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
4012 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004013 return;
4014 }
4015
4016 uint32_t policyFlags = args->policyFlags;
4017 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004018
4019 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08004020 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004021 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4022 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004023 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004024 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004025
Antonio Kantekf16f2832021-09-28 04:39:20 +00004026 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004027 { // acquire lock
4028 mLock.lock();
4029
4030 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004031 ui::Transform displayTransform;
4032 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
4033 displayTransform = it->second.transform;
4034 }
4035
Michael Wrightd02c5b62014-02-10 15:10:22 -08004036 mLock.unlock();
4037
4038 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08004039 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
4040 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004041 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004042 displayTransform, args->xPrecision, args->yPrecision,
4043 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004044 args->downTime, args->eventTime, args->pointerCount,
4045 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004046
4047 policyFlags |= POLICY_FLAG_FILTERED;
4048 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
4049 return; // event was consumed by the filter
4050 }
4051
4052 mLock.lock();
4053 }
4054
4055 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004056 std::unique_ptr<MotionEntry> newEntry =
4057 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4058 args->source, args->displayId, policyFlags,
4059 args->action, args->actionButton, args->flags,
4060 args->metaState, args->buttonState,
4061 args->classification, args->edgeFlags,
4062 args->xPrecision, args->yPrecision,
4063 args->xCursorPosition, args->yCursorPosition,
4064 args->downTime, args->pointerCount,
Alex Chauf7c99f32021-12-03 10:37:54 +00004065 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004066
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004067 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4068 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4069 !mInputFilterEnabled) {
4070 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4071 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4072 }
4073
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004074 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004075 mLock.unlock();
4076 } // release lock
4077
4078 if (needWake) {
4079 mLooper->wake();
4080 }
4081}
4082
Chris Yef59a2f42020-10-16 12:55:26 -07004083void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004084 if (DEBUG_INBOUND_EVENT_DETAILS) {
4085 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4086 " sensorType=%s",
4087 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004088 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004089 }
Chris Yef59a2f42020-10-16 12:55:26 -07004090
Antonio Kantekf16f2832021-09-28 04:39:20 +00004091 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004092 { // acquire lock
4093 mLock.lock();
4094
4095 // Just enqueue a new sensor event.
4096 std::unique_ptr<SensorEntry> newEntry =
4097 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4098 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4099 args->sensorType, args->accuracy,
4100 args->accuracyChanged, args->values);
4101
4102 needWake = enqueueInboundEventLocked(std::move(newEntry));
4103 mLock.unlock();
4104 } // release lock
4105
4106 if (needWake) {
4107 mLooper->wake();
4108 }
4109}
4110
Chris Yefb552902021-02-03 17:18:37 -08004111void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004112 if (DEBUG_INBOUND_EVENT_DETAILS) {
4113 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4114 args->deviceId, args->isOn);
4115 }
Chris Yefb552902021-02-03 17:18:37 -08004116 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4117}
4118
Michael Wrightd02c5b62014-02-10 15:10:22 -08004119bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004120 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004121}
4122
4123void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004124 if (DEBUG_INBOUND_EVENT_DETAILS) {
4125 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4126 "switchMask=0x%08x",
4127 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4128 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004129
4130 uint32_t policyFlags = args->policyFlags;
4131 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004132 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004133}
4134
4135void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004136 if (DEBUG_INBOUND_EVENT_DETAILS) {
4137 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4138 args->deviceId);
4139 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004140
Antonio Kantekf16f2832021-09-28 04:39:20 +00004141 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004142 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004143 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004144
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004145 std::unique_ptr<DeviceResetEntry> newEntry =
4146 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4147 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004148 } // release lock
4149
4150 if (needWake) {
4151 mLooper->wake();
4152 }
4153}
4154
Prabir Pradhan7e186182020-11-10 13:56:45 -08004155void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004156 if (DEBUG_INBOUND_EVENT_DETAILS) {
4157 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004158 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004159 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004160
Antonio Kantekf16f2832021-09-28 04:39:20 +00004161 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004162 { // acquire lock
4163 std::scoped_lock _l(mLock);
4164 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004165 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004166 needWake = enqueueInboundEventLocked(std::move(entry));
4167 } // release lock
4168
4169 if (needWake) {
4170 mLooper->wake();
4171 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004172}
4173
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004174InputEventInjectionResult InputDispatcher::injectInputEvent(
4175 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4176 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004177 if (DEBUG_INBOUND_EVENT_DETAILS) {
4178 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4179 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4180 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4181 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004182 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004183
4184 policyFlags |= POLICY_FLAG_INJECTED;
4185 if (hasInjectionPermission(injectorPid, injectorUid)) {
4186 policyFlags |= POLICY_FLAG_TRUSTED;
4187 }
4188
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004189 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004190 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4191 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4192 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4193 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4194 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004195 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004196 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004197 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004198 }
4199
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004200 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004201 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004202 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004203 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4204 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004205 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004206 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004207 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004208
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004209 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004210 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4211 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4212 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004213 int32_t keyCode = incomingKey.getKeyCode();
4214 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004215 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004216 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004217 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004218 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004219 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4220 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4221 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004222
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004223 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4224 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004225 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004226
4227 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4228 android::base::Timer t;
4229 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4230 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4231 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4232 std::to_string(t.duration().count()).c_str());
4233 }
4234 }
4235
4236 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004237 std::unique_ptr<KeyEntry> injectedEntry =
4238 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004239 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004240 incomingKey.getDisplayId(), policyFlags, action,
4241 flags, keyCode, incomingKey.getScanCode(), metaState,
4242 incomingKey.getRepeatCount(),
4243 incomingKey.getDownTime());
4244 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004245 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004246 }
4247
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004248 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004249 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004250 const int32_t action = motionEvent.getAction();
4251 const bool isPointerEvent =
4252 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4253 // If a pointer event has no displayId specified, inject it to the default display.
4254 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4255 ? ADISPLAY_ID_DEFAULT
4256 : event->getDisplayId();
4257 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004258 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004259 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004260 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004261 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004262 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004263 }
4264
4265 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004266 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004267 android::base::Timer t;
4268 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4269 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4270 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4271 std::to_string(t.duration().count()).c_str());
4272 }
4273 }
4274
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004275 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4276 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4277 }
4278
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004279 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004280 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4281 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004282 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004283 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4284 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004285 displayId, policyFlags, action, actionButton,
4286 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004287 motionEvent.getButtonState(),
4288 motionEvent.getClassification(),
4289 motionEvent.getEdgeFlags(),
4290 motionEvent.getXPrecision(),
4291 motionEvent.getYPrecision(),
4292 motionEvent.getRawXCursorPosition(),
4293 motionEvent.getRawYCursorPosition(),
4294 motionEvent.getDownTime(), uint32_t(pointerCount),
Alex Chau663fc832021-12-03 10:37:54 +00004295 pointerProperties, samplePointerCoords,
4296 motionEvent.getXOffset(),
4297 motionEvent.getYOffset());
4298 transformMotionEntryForInjectionLocked(*injectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004299 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004300 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004301 sampleEventTimes += 1;
4302 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004303 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004304 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4305 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004306 displayId, policyFlags, action, actionButton,
4307 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004308 motionEvent.getButtonState(),
4309 motionEvent.getClassification(),
4310 motionEvent.getEdgeFlags(),
4311 motionEvent.getXPrecision(),
4312 motionEvent.getYPrecision(),
4313 motionEvent.getRawXCursorPosition(),
4314 motionEvent.getRawYCursorPosition(),
4315 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004316 uint32_t(pointerCount), pointerProperties,
Alex Chau663fc832021-12-03 10:37:54 +00004317 samplePointerCoords, motionEvent.getXOffset(),
4318 motionEvent.getYOffset());
4319 transformMotionEntryForInjectionLocked(*nextInjectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004320 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004321 }
4322 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004323 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004324
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004325 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004326 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004327 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328 }
4329
4330 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004331 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332 injectionState->injectionIsAsync = true;
4333 }
4334
4335 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004336 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337
4338 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004339 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004340 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004341 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342 }
4343
4344 mLock.unlock();
4345
4346 if (needWake) {
4347 mLooper->wake();
4348 }
4349
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004350 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004351 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004352 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004354 if (syncMode == InputEventInjectionSync::NONE) {
4355 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356 } else {
4357 for (;;) {
4358 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004359 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004360 break;
4361 }
4362
4363 nsecs_t remainingTimeout = endTime - now();
4364 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004365 if (DEBUG_INJECTION) {
4366 ALOGD("injectInputEvent - Timed out waiting for injection result "
4367 "to become available.");
4368 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004369 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004370 break;
4371 }
4372
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004373 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004374 }
4375
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004376 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4377 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004378 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004379 if (DEBUG_INJECTION) {
4380 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4381 injectionState->pendingForegroundDispatches);
4382 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004383 nsecs_t remainingTimeout = endTime - now();
4384 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004385 if (DEBUG_INJECTION) {
4386 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4387 "dispatches to finish.");
4388 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004389 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004390 break;
4391 }
4392
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004393 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004394 }
4395 }
4396 }
4397
4398 injectionState->release();
4399 } // release lock
4400
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004401 if (DEBUG_INJECTION) {
4402 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4403 injectionResult, injectorPid, injectorUid);
4404 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004405
4406 return injectionResult;
4407}
4408
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004409std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004410 std::array<uint8_t, 32> calculatedHmac;
4411 std::unique_ptr<VerifiedInputEvent> result;
4412 switch (event.getType()) {
4413 case AINPUT_EVENT_TYPE_KEY: {
4414 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4415 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4416 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004417 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004418 break;
4419 }
4420 case AINPUT_EVENT_TYPE_MOTION: {
4421 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4422 VerifiedMotionEvent verifiedMotionEvent =
4423 verifiedMotionEventFromMotionEvent(motionEvent);
4424 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004425 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004426 break;
4427 }
4428 default: {
4429 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4430 return nullptr;
4431 }
4432 }
4433 if (calculatedHmac == INVALID_HMAC) {
4434 return nullptr;
4435 }
4436 if (calculatedHmac != event.getHmac()) {
4437 return nullptr;
4438 }
4439 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004440}
4441
Michael Wrightd02c5b62014-02-10 15:10:22 -08004442bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004443 return injectorUid == 0 ||
4444 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004445}
4446
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004447void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004448 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004449 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004450 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004451 if (DEBUG_INJECTION) {
4452 ALOGD("Setting input event injection result to %d. "
4453 "injectorPid=%d, injectorUid=%d",
4454 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4455 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004456
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004457 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004458 // Log the outcome since the injector did not wait for the injection result.
4459 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004460 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004461 ALOGV("Asynchronous input event injection succeeded.");
4462 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004463 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004464 ALOGW("Asynchronous input event injection failed.");
4465 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004466 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004467 ALOGW("Asynchronous input event injection permission denied.");
4468 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004469 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004470 ALOGW("Asynchronous input event injection timed out.");
4471 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004472 case InputEventInjectionResult::PENDING:
4473 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4474 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004475 }
4476 }
4477
4478 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004479 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480 }
4481}
4482
Alex Chau663fc832021-12-03 10:37:54 +00004483void InputDispatcher::transformMotionEntryForInjectionLocked(MotionEntry& entry) const {
4484 const bool isRelativeMouseEvent = isFromSource(entry.source, AINPUT_SOURCE_MOUSE_RELATIVE);
4485 if (!isRelativeMouseEvent && !isFromSource(entry.source, AINPUT_SOURCE_CLASS_POINTER)) {
4486 return;
4487 }
4488
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004489 // Input injection works in the logical display coordinate space, but the input pipeline works
4490 // display space, so we need to transform the injected events accordingly.
4491 const auto it = mDisplayInfos.find(entry.displayId);
4492 if (it == mDisplayInfos.end()) return;
Alex Chau663fc832021-12-03 10:37:54 +00004493 const auto& transformToDisplay = it->second.transform.inverse();
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004494
4495 for (uint32_t i = 0; i < entry.pointerCount; i++) {
4496 PointerCoords& pc = entry.pointerCoords[i];
Alex Chau663fc832021-12-03 10:37:54 +00004497 const auto xy = isRelativeMouseEvent
4498 ? transformWithoutTranslation(transformToDisplay, pc.getX(), pc.getY())
4499 : transformToDisplay.transform(pc.getXYValue());
4500 pc.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
4501 pc.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004502
Alex Chau663fc832021-12-03 10:37:54 +00004503 // Axes with relative values never represent points on a screen, so they should never have
4504 // translation applied. If a device does not report relative values, these values are always
4505 // 0, and will remain unaffected by the following operation.
4506 const auto rel =
4507 transformWithoutTranslation(transformToDisplay,
4508 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
4509 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4510 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, rel.x);
4511 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, rel.y);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004512 }
4513}
4514
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004515void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4516 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004517 if (injectionState) {
4518 injectionState->pendingForegroundDispatches += 1;
4519 }
4520}
4521
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004522void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4523 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004524 if (injectionState) {
4525 injectionState->pendingForegroundDispatches -= 1;
4526
4527 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004528 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004529 }
4530 }
4531}
4532
chaviw98318de2021-05-19 16:45:23 -05004533const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004534 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004535 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004536 auto it = mWindowHandlesByDisplay.find(displayId);
4537 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004538}
4539
chaviw98318de2021-05-19 16:45:23 -05004540sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004541 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004542 if (windowHandleToken == nullptr) {
4543 return nullptr;
4544 }
4545
Arthur Hungb92218b2018-08-14 12:00:21 +08004546 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004547 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4548 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004549 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004550 return windowHandle;
4551 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004552 }
4553 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004554 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004555}
4556
chaviw98318de2021-05-19 16:45:23 -05004557sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4558 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004559 if (windowHandleToken == nullptr) {
4560 return nullptr;
4561 }
4562
chaviw98318de2021-05-19 16:45:23 -05004563 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004564 if (windowHandle->getToken() == windowHandleToken) {
4565 return windowHandle;
4566 }
4567 }
4568 return nullptr;
4569}
4570
chaviw98318de2021-05-19 16:45:23 -05004571sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4572 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004573 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004574 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4575 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004576 if (handle->getId() == windowHandle->getId() &&
4577 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004578 if (windowHandle->getInfo()->displayId != it.first) {
4579 ALOGE("Found window %s in display %" PRId32
4580 ", but it should belong to display %" PRId32,
4581 windowHandle->getName().c_str(), it.first,
4582 windowHandle->getInfo()->displayId);
4583 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004584 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004586 }
4587 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004588 return nullptr;
4589}
4590
chaviw98318de2021-05-19 16:45:23 -05004591sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004592 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4593 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004594}
4595
chaviw98318de2021-05-19 16:45:23 -05004596bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004597 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4598 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004599 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004600 if (connection != nullptr && noInputChannel) {
4601 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4602 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4603 return false;
4604 }
4605
4606 if (connection == nullptr) {
4607 if (!noInputChannel) {
4608 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4609 }
4610 return false;
4611 }
4612 if (!connection->responsive) {
4613 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4614 return false;
4615 }
4616 return true;
4617}
4618
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004619std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4620 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004621 auto connectionIt = mConnectionsByToken.find(token);
4622 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004623 return nullptr;
4624 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004625 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004626}
4627
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004628void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004629 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4630 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004631 // Remove all handles on a display if there are no windows left.
4632 mWindowHandlesByDisplay.erase(displayId);
4633 return;
4634 }
4635
4636 // Since we compare the pointer of input window handles across window updates, we need
4637 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004638 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4639 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4640 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004641 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004642 }
4643
chaviw98318de2021-05-19 16:45:23 -05004644 std::vector<sp<WindowInfoHandle>> newHandles;
4645 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004646 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004647 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004648 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004649 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4650 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4651 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004652 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004653 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004654 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004655 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004656 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004657 }
4658
4659 if (info->displayId != displayId) {
4660 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4661 handle->getName().c_str(), displayId, info->displayId);
4662 continue;
4663 }
4664
Robert Carredd13602020-04-13 17:24:34 -07004665 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4666 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004667 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004668 oldHandle->updateFrom(handle);
4669 newHandles.push_back(oldHandle);
4670 } else {
4671 newHandles.push_back(handle);
4672 }
4673 }
4674
4675 // Insert or replace
4676 mWindowHandlesByDisplay[displayId] = newHandles;
4677}
4678
Arthur Hung72d8dc32020-03-28 00:48:39 +00004679void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004680 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004681 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004682 { // acquire lock
4683 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004684 for (const auto& [displayId, handles] : handlesPerDisplay) {
4685 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004686 }
4687 }
4688 // Wake up poll loop since it may need to make new input dispatching choices.
4689 mLooper->wake();
4690}
4691
Arthur Hungb92218b2018-08-14 12:00:21 +08004692/**
4693 * Called from InputManagerService, update window handle list by displayId that can receive input.
4694 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4695 * If set an empty list, remove all handles from the specific display.
4696 * For focused handle, check if need to change and send a cancel event to previous one.
4697 * For removed handle, check if need to send a cancel event if already in touch.
4698 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004699void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004700 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004701 if (DEBUG_FOCUS) {
4702 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004703 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004704 windowList += iwh->getName() + " ";
4705 }
4706 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004708
Prabir Pradhand65552b2021-10-07 11:23:50 -07004709 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05004710 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07004711 const WindowInfo& info = *window->getInfo();
4712
4713 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4714 const bool noInputWindow = info.inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004715 if (noInputWindow && window->getToken() != nullptr) {
4716 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4717 window->getName().c_str());
4718 window->releaseChannel();
4719 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07004720
4721 // Ensure all stylus interceptors are trusted overlays
4722 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() && !info.trustedOverlay,
4723 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
4724 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004725 }
4726
Arthur Hung72d8dc32020-03-28 00:48:39 +00004727 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004728 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004729
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004730 // Save the old windows' orientation by ID before it gets updated.
4731 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004732 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004733 oldWindowOrientations.emplace(handle->getId(),
4734 handle->getInfo()->transform.getOrientation());
4735 }
4736
chaviw98318de2021-05-19 16:45:23 -05004737 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004738
chaviw98318de2021-05-19 16:45:23 -05004739 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004740 if (mLastHoverWindowHandle &&
4741 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4742 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004743 mLastHoverWindowHandle = nullptr;
4744 }
4745
Vishnu Nairc519ff72021-01-21 08:23:08 -08004746 std::optional<FocusResolver::FocusChanges> changes =
4747 mFocusResolver.setInputWindows(displayId, windowHandles);
4748 if (changes) {
4749 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004750 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004751
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004752 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4753 mTouchStatesByDisplay.find(displayId);
4754 if (stateIt != mTouchStatesByDisplay.end()) {
4755 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004756 for (size_t i = 0; i < state.windows.size();) {
4757 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004758 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004759 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004760 ALOGD("Touched window was removed: %s in display %" PRId32,
4761 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004762 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004763 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004764 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4765 if (touchedInputChannel != nullptr) {
4766 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4767 "touched window was removed");
4768 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004769 // Since we are about to drop the touch, cancel the events for the wallpaper as
4770 // well.
4771 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4772 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4773 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4774 if (wallpaper != nullptr) {
4775 sp<Connection> wallpaperConnection =
4776 getConnectionLocked(wallpaper->getToken());
Siarhei Vishniakou2b030972021-11-18 10:01:27 -08004777 if (wallpaperConnection != nullptr) {
4778 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4779 options);
4780 }
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004781 }
4782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004783 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004784 state.windows.erase(state.windows.begin() + i);
4785 } else {
4786 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004787 }
4788 }
arthurhungb89ccb02020-12-30 16:19:01 +08004789
arthurhung6d4bed92021-03-17 11:59:33 +08004790 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004791 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004792 if (mDragState &&
4793 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004794 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004795 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004796 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004797 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004798
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00004799 // Determine if the orientation of any of the input windows have changed, and cancel all
4800 // pointer events if necessary.
4801 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4802 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
4803 if (newWindowHandle != nullptr &&
4804 newWindowHandle->getInfo()->transform.getOrientation() !=
4805 oldWindowOrientations[oldWindowHandle->getId()]) {
4806 std::shared_ptr<InputChannel> inputChannel =
4807 getInputChannelLocked(newWindowHandle->getToken());
4808 if (inputChannel != nullptr) {
4809 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4810 "touched window's orientation changed");
4811 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004812 }
4813 }
4814 }
4815
Arthur Hung72d8dc32020-03-28 00:48:39 +00004816 // Release information for windows that are no longer present.
4817 // This ensures that unused input channels are released promptly.
4818 // Otherwise, they might stick around until the window handle is destroyed
4819 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004820 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004821 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004822 if (DEBUG_FOCUS) {
4823 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004824 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004825 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004826 // To avoid making too many calls into the compat framework, only
4827 // check for window flags when windows are going away.
4828 // TODO(b/157929241) : delete this. This is only needed temporarily
4829 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004830 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004831 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4832 oldWindowHandle->getName().c_str());
4833 if (mCompatService != nullptr) {
4834 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4835 oldWindowHandle->getInfo()->ownerUid);
4836 }
4837 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004838 }
chaviw291d88a2019-02-14 10:33:58 -08004839 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840}
4841
4842void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004843 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004844 if (DEBUG_FOCUS) {
4845 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4846 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4847 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004848 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004849 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004850 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004851 } // release lock
4852
4853 // Wake up poll loop since it may need to make new input dispatching choices.
4854 mLooper->wake();
4855}
4856
Vishnu Nair599f1412021-06-21 10:39:58 -07004857void InputDispatcher::setFocusedApplicationLocked(
4858 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4859 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4860 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4861
4862 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4863 return; // This application is already focused. No need to wake up or change anything.
4864 }
4865
4866 // Set the new application handle.
4867 if (inputApplicationHandle != nullptr) {
4868 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4869 } else {
4870 mFocusedApplicationHandlesByDisplay.erase(displayId);
4871 }
4872
4873 // No matter what the old focused application was, stop waiting on it because it is
4874 // no longer focused.
4875 resetNoFocusedWindowTimeoutLocked();
4876}
4877
Tiger Huang721e26f2018-07-24 22:26:19 +08004878/**
4879 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4880 * the display not specified.
4881 *
4882 * We track any unreleased events for each window. If a window loses the ability to receive the
4883 * released event, we will send a cancel event to it. So when the focused display is changed, we
4884 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4885 * display. The display-specified events won't be affected.
4886 */
4887void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004888 if (DEBUG_FOCUS) {
4889 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4890 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004891 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004892 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004893
4894 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004895 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004896 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004897 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004898 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004899 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004900 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004901 CancelationOptions
4902 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4903 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004904 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004905 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4906 }
4907 }
4908 mFocusedDisplayId = displayId;
4909
Chris Ye3c2d6f52020-08-09 10:39:48 -07004910 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004911 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004912 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004913
Vishnu Nairad321cd2020-08-20 16:40:21 -07004914 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004915 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004916 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004917 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004918 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004919 }
4920 }
4921 }
4922
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004923 if (DEBUG_FOCUS) {
4924 logDispatchStateLocked();
4925 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004926 } // release lock
4927
4928 // Wake up poll loop since it may need to make new input dispatching choices.
4929 mLooper->wake();
4930}
4931
Michael Wrightd02c5b62014-02-10 15:10:22 -08004932void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004933 if (DEBUG_FOCUS) {
4934 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4935 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004936
4937 bool changed;
4938 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004939 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004940
4941 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4942 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004943 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004944 }
4945
4946 if (mDispatchEnabled && !enabled) {
4947 resetAndDropEverythingLocked("dispatcher is being disabled");
4948 }
4949
4950 mDispatchEnabled = enabled;
4951 mDispatchFrozen = frozen;
4952 changed = true;
4953 } else {
4954 changed = false;
4955 }
4956
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004957 if (DEBUG_FOCUS) {
4958 logDispatchStateLocked();
4959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004960 } // release lock
4961
4962 if (changed) {
4963 // Wake up poll loop since it may need to make new input dispatching choices.
4964 mLooper->wake();
4965 }
4966}
4967
4968void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004969 if (DEBUG_FOCUS) {
4970 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004972
4973 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004974 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004975
4976 if (mInputFilterEnabled == enabled) {
4977 return;
4978 }
4979
4980 mInputFilterEnabled = enabled;
4981 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4982 } // release lock
4983
4984 // Wake up poll loop since there might be work to do to drop everything.
4985 mLooper->wake();
4986}
4987
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004988void InputDispatcher::setInTouchMode(bool inTouchMode) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00004989 bool needWake = false;
4990 {
4991 std::scoped_lock lock(mLock);
4992 if (mInTouchMode == inTouchMode) {
4993 return;
4994 }
4995 if (DEBUG_TOUCH_MODE) {
4996 ALOGD("Request to change touch mode from %s to %s", toString(mInTouchMode),
4997 toString(inTouchMode));
4998 // TODO(b/198487159): Also print the current last interacted apps.
4999 }
5000
5001 // TODO(b/198499018): Store touch mode per display.
5002 mInTouchMode = inTouchMode;
5003
5004 // TODO(b/198487159): Enforce that only last interacted apps can change touch mode.
5005 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode);
5006 needWake = enqueueInboundEventLocked(std::move(entry));
5007 } // release lock
5008
5009 if (needWake) {
5010 mLooper->wake();
5011 }
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005012}
5013
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005014void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5015 if (opacity < 0 || opacity > 1) {
5016 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5017 return;
5018 }
5019
5020 std::scoped_lock lock(mLock);
5021 mMaximumObscuringOpacityForTouch = opacity;
5022}
5023
5024void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
5025 std::scoped_lock lock(mLock);
5026 mBlockUntrustedTouchesMode = mode;
5027}
5028
Arthur Hungabbb9d82021-09-01 14:52:30 +00005029std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
5030 const sp<IBinder>& token) {
5031 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5032 for (TouchedWindow& w : state.windows) {
5033 if (w.windowHandle->getToken() == token) {
5034 return std::make_pair(&state, &w);
5035 }
5036 }
5037 }
5038 return std::make_pair(nullptr, nullptr);
5039}
5040
arthurhungb89ccb02020-12-30 16:19:01 +08005041bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5042 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005043 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005044 if (DEBUG_FOCUS) {
5045 ALOGD("Trivial transfer to same window.");
5046 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005047 return true;
5048 }
5049
Michael Wrightd02c5b62014-02-10 15:10:22 -08005050 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005051 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005052
Arthur Hungabbb9d82021-09-01 14:52:30 +00005053 // Find the target touch state and touched window by fromToken.
5054 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
5055 if (state == nullptr || touchedWindow == nullptr) {
5056 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005057 return false;
5058 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00005059
5060 const int32_t displayId = state->displayId;
5061 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5062 if (toWindowHandle == nullptr) {
5063 ALOGW("Cannot transfer focus because to window not found.");
5064 return false;
5065 }
5066
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005067 if (DEBUG_FOCUS) {
5068 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005069 touchedWindow->windowHandle->getName().c_str(),
5070 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005071 }
5072
Arthur Hungabbb9d82021-09-01 14:52:30 +00005073 // Erase old window.
5074 int32_t oldTargetFlags = touchedWindow->targetFlags;
5075 BitSet32 pointerIds = touchedWindow->pointerIds;
5076 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077
Arthur Hungabbb9d82021-09-01 14:52:30 +00005078 // Add new window.
5079 int32_t newTargetFlags = oldTargetFlags &
5080 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
5081 InputTarget::FLAG_DISPATCH_AS_IS);
5082 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005083
Arthur Hungabbb9d82021-09-01 14:52:30 +00005084 // Store the dragging window.
5085 if (isDragDrop) {
5086 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005087 }
5088
Arthur Hungabbb9d82021-09-01 14:52:30 +00005089 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005090 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5091 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005092 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005093 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005094 CancelationOptions
5095 options(CancelationOptions::CANCEL_POINTER_EVENTS,
5096 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005097 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005098 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005099 }
5100
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005101 if (DEBUG_FOCUS) {
5102 logDispatchStateLocked();
5103 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005104 } // release lock
5105
5106 // Wake up poll loop since it may need to make new input dispatching choices.
5107 mLooper->wake();
5108 return true;
5109}
5110
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005111// Binder call
5112bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5113 sp<IBinder> fromToken;
5114 { // acquire lock
5115 std::scoped_lock _l(mLock);
5116
Arthur Hungabbb9d82021-09-01 14:52:30 +00005117 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5118 [](const auto& pair) { return pair.second.windows.size() == 1; });
5119 if (it == mTouchStatesByDisplay.end()) {
5120 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5121 return false;
5122 }
5123 const int32_t displayId = it->first;
5124 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005125 if (toWindowHandle == nullptr) {
5126 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5127 return false;
5128 }
5129
Arthur Hungabbb9d82021-09-01 14:52:30 +00005130 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005131 const TouchedWindow& touchedWindow = state.windows[0];
5132 fromToken = touchedWindow.windowHandle->getToken();
5133 } // release lock
5134
5135 return transferTouchFocus(fromToken, destChannelToken);
5136}
5137
Michael Wrightd02c5b62014-02-10 15:10:22 -08005138void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005139 if (DEBUG_FOCUS) {
5140 ALOGD("Resetting and dropping all events (%s).", reason);
5141 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005142
5143 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5144 synthesizeCancelationEventsForAllConnectionsLocked(options);
5145
5146 resetKeyRepeatLocked();
5147 releasePendingEventLocked();
5148 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005149 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005150
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005151 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005152 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005153 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005154 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005155}
5156
5157void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005158 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005159 dumpDispatchStateLocked(dump);
5160
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005161 std::istringstream stream(dump);
5162 std::string line;
5163
5164 while (std::getline(stream, line, '\n')) {
5165 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005166 }
5167}
5168
Prabir Pradhan99987712020-11-10 18:43:05 -08005169std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5170 std::string dump;
5171
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005172 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5173 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005174
5175 std::string windowName = "None";
5176 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005177 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005178 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5179 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5180 : "token has capture without window";
5181 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005182 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005183
5184 return dump;
5185}
5186
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005187void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005188 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5189 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5190 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005191 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005192
Tiger Huang721e26f2018-07-24 22:26:19 +08005193 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5194 dump += StringPrintf(INDENT "FocusedApplications:\n");
5195 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5196 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005197 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005198 const std::chrono::duration timeout =
5199 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005200 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005201 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005202 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005203 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005204 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005205 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005206 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005207
Vishnu Nairc519ff72021-01-21 08:23:08 -08005208 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005209 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005210
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005211 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005212 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005213 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5214 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005215 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005216 state.displayId, toString(state.down), toString(state.split),
5217 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005218 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005219 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005220 for (size_t i = 0; i < state.windows.size(); i++) {
5221 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005222 dump += StringPrintf(INDENT4
5223 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5224 i, touchedWindow.windowHandle->getName().c_str(),
5225 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005226 }
5227 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005228 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005229 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005230 }
5231 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005232 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005233 }
5234
arthurhung6d4bed92021-03-17 11:59:33 +08005235 if (mDragState) {
5236 dump += StringPrintf(INDENT "DragState:\n");
5237 mDragState->dump(dump, INDENT2);
5238 }
5239
Arthur Hungb92218b2018-08-14 12:00:21 +08005240 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005241 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5242 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5243 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5244 const auto& displayInfo = it->second;
5245 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5246 displayInfo.logicalHeight);
5247 displayInfo.transform.dump(dump, "transform", INDENT4);
5248 } else {
5249 dump += INDENT2 "No DisplayInfo found!\n";
5250 }
5251
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005252 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005253 dump += INDENT2 "Windows:\n";
5254 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005255 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5256 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005257
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005258 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005259 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005260 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005261 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005262 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005263 "applicationInfo.name=%s, "
5264 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005265 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005266 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005267 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005268 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005269 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005270 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005271 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005272 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005273 windowInfo->frameLeft, windowInfo->frameTop,
5274 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005275 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005276 windowInfo->applicationInfo.name.c_str(),
5277 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005278 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005279 dump += StringPrintf(", inputFeatures=%s",
5280 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005281 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005282 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005283 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005284 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005285 millis(windowInfo->dispatchingTimeout),
5286 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005287 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005288 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005289 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005290 }
5291 } else {
5292 dump += INDENT2 "Windows: <none>\n";
5293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005294 }
5295 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005296 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005297 }
5298
Michael Wright3dd60e22019-03-27 22:06:44 +00005299 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005300 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005301 const std::vector<Monitor>& monitors = it.second;
5302 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5303 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005304 }
5305 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005306 const std::vector<Monitor>& monitors = it.second;
5307 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5308 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005309 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005310 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005311 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312 }
5313
5314 nsecs_t currentTime = now();
5315
5316 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005317 if (!mRecentQueue.empty()) {
5318 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005319 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005320 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005321 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005322 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005323 }
5324 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005325 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005326 }
5327
5328 // Dump event currently being dispatched.
5329 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005330 dump += INDENT "PendingEvent:\n";
5331 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005332 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005333 dump += StringPrintf(", age=%" PRId64 "ms\n",
5334 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005336 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005337 }
5338
5339 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005340 if (!mInboundQueue.empty()) {
5341 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005342 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005343 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005344 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005345 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005346 }
5347 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005348 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005349 }
5350
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005351 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005352 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005353 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5354 const KeyReplacement& replacement = pair.first;
5355 int32_t newKeyCode = pair.second;
5356 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005357 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005358 }
5359 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005360 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005361 }
5362
Prabir Pradhancef936d2021-07-21 16:17:52 +00005363 if (!mCommandQueue.empty()) {
5364 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5365 } else {
5366 dump += INDENT "CommandQueue: <empty>\n";
5367 }
5368
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005369 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005370 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005371 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005372 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005373 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005374 connection->inputChannel->getFd().get(),
5375 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005376 connection->getWindowName().c_str(),
5377 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005378 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005379
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005380 if (!connection->outboundQueue.empty()) {
5381 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5382 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005383 dump += dumpQueue(connection->outboundQueue, currentTime);
5384
Michael Wrightd02c5b62014-02-10 15:10:22 -08005385 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005386 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005387 }
5388
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005389 if (!connection->waitQueue.empty()) {
5390 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5391 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005392 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005393 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005394 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005395 }
5396 }
5397 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005398 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005399 }
5400
5401 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005402 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5403 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005404 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005405 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005406 }
5407
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005408 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005409 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5410 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5411 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005412 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005413 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005414}
5415
Michael Wright3dd60e22019-03-27 22:06:44 +00005416void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5417 const size_t numMonitors = monitors.size();
5418 for (size_t i = 0; i < numMonitors; i++) {
5419 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005420 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005421 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5422 dump += "\n";
5423 }
5424}
5425
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005426class LooperEventCallback : public LooperCallback {
5427public:
5428 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5429 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5430
5431private:
5432 std::function<int(int events)> mCallback;
5433};
5434
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005435Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005436 if (DEBUG_CHANNEL_CREATION) {
5437 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5438 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005439
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005440 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005441 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005442 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005443
5444 if (result) {
5445 return base::Error(result) << "Failed to open input channel pair with name " << name;
5446 }
5447
Michael Wrightd02c5b62014-02-10 15:10:22 -08005448 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005449 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005450 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005451 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005452 sp<Connection> connection =
5453 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005454
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005455 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5456 ALOGE("Created a new connection, but the token %p is already known", token.get());
5457 }
5458 mConnectionsByToken.emplace(token, connection);
5459
5460 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5461 this, std::placeholders::_1, token);
5462
5463 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005464 } // release lock
5465
5466 // Wake the looper because some connections have changed.
5467 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005468 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005469}
5470
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005471Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5472 bool isGestureMonitor,
5473 const std::string& name,
5474 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005475 std::shared_ptr<InputChannel> serverChannel;
5476 std::unique_ptr<InputChannel> clientChannel;
5477 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5478 if (result) {
5479 return base::Error(result) << "Failed to open input channel pair with name " << name;
5480 }
5481
Michael Wright3dd60e22019-03-27 22:06:44 +00005482 { // acquire lock
5483 std::scoped_lock _l(mLock);
5484
5485 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005486 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5487 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005488 }
5489
Garfield Tan15601662020-09-22 15:32:38 -07005490 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005491 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005492 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005493
5494 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5495 ALOGE("Created a new connection, but the token %p is already known", token.get());
5496 }
5497 mConnectionsByToken.emplace(token, connection);
5498 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5499 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005500
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005501 auto& monitorsByDisplay =
5502 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005503 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005504
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005505 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005506 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5507 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005508 }
Garfield Tan15601662020-09-22 15:32:38 -07005509
Michael Wright3dd60e22019-03-27 22:06:44 +00005510 // Wake the looper because some connections have changed.
5511 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005512 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005513}
5514
Garfield Tan15601662020-09-22 15:32:38 -07005515status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005516 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005517 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005518
Garfield Tan15601662020-09-22 15:32:38 -07005519 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005520 if (status) {
5521 return status;
5522 }
5523 } // release lock
5524
5525 // Wake the poll loop because removing the connection may have changed the current
5526 // synchronization state.
5527 mLooper->wake();
5528 return OK;
5529}
5530
Garfield Tan15601662020-09-22 15:32:38 -07005531status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5532 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005533 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005534 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005535 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005536 return BAD_VALUE;
5537 }
5538
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005539 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005540
Michael Wrightd02c5b62014-02-10 15:10:22 -08005541 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005542 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005543 }
5544
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005545 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005546
5547 nsecs_t currentTime = now();
5548 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5549
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005550 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005551 return OK;
5552}
5553
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005554void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5555 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5556 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005557}
5558
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005559void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005560 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005561 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005562 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005563 std::vector<Monitor>& monitors = it->second;
5564 const size_t numMonitors = monitors.size();
5565 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005566 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005567 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5568 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005569 monitors.erase(monitors.begin() + i);
5570 break;
5571 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005572 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005573 if (monitors.empty()) {
5574 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005575 } else {
5576 ++it;
5577 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005578 }
5579}
5580
Michael Wright3dd60e22019-03-27 22:06:44 +00005581status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5582 { // acquire lock
5583 std::scoped_lock _l(mLock);
Michael Wright3dd60e22019-03-27 22:06:44 +00005584
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005585 TouchState* statePtr = nullptr;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005586 std::shared_ptr<InputChannel> requestingChannel;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005587 int32_t displayId;
5588 int32_t deviceId;
5589 const std::optional<int32_t> foundGestureMonitorDisplayId =
5590 findGestureMonitorDisplayByTokenLocked(token);
5591
5592 // TODO: Optimize this function for pilfering from windows when removing gesture monitors.
5593 if (foundGestureMonitorDisplayId) {
5594 // A gesture monitor has requested to pilfer pointers.
5595 displayId = *foundGestureMonitorDisplayId;
5596 auto stateIt = mTouchStatesByDisplay.find(displayId);
5597 if (stateIt == mTouchStatesByDisplay.end()) {
5598 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5599 return BAD_VALUE;
5600 }
5601 statePtr = &stateIt->second;
5602
5603 for (const auto& monitor : statePtr->gestureMonitors) {
5604 if (monitor.inputChannel->getConnectionToken() == token) {
5605 requestingChannel = monitor.inputChannel;
5606 deviceId = statePtr->deviceId;
5607 }
5608 }
5609 } else {
5610 // Check if a window has requested to pilfer pointers.
5611 for (auto& [curDisplayId, state] : mTouchStatesByDisplay) {
5612 const sp<WindowInfoHandle>& windowHandle = state.getWindow(token);
5613 if (windowHandle != nullptr) {
5614 displayId = curDisplayId;
5615 requestingChannel = getInputChannelLocked(token);
5616 deviceId = state.deviceId;
5617 statePtr = &state;
5618 break;
5619 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005620 }
5621 }
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005622
5623 if (requestingChannel == nullptr) {
5624 ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
5625 return BAD_VALUE;
5626 }
5627 TouchState& state = *statePtr;
5628 if (!state.down) {
5629 ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005630 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005631 return BAD_VALUE;
5632 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005633
5634 // Send cancel events to all the input channels we're stealing from.
5635 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005636 "input channel stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005637 options.deviceId = deviceId;
5638 options.displayId = displayId;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005639 std::string canceledWindows;
Michael Wright3dd60e22019-03-27 22:06:44 +00005640 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005641 std::shared_ptr<InputChannel> channel =
5642 getInputChannelLocked(window.windowHandle->getToken());
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005643 if (channel != nullptr && channel->getConnectionToken() != token) {
Michael Wright3a240c42019-12-10 20:53:41 +00005644 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005645 canceledWindows += canceledWindows.empty() ? "[" : ", ";
5646 canceledWindows += channel->getName();
Michael Wright3a240c42019-12-10 20:53:41 +00005647 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005648 }
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005649 canceledWindows += canceledWindows.empty() ? "[]" : "]";
5650 ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(),
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005651 canceledWindows.c_str());
5652
Michael Wright3dd60e22019-03-27 22:06:44 +00005653 // Then clear the current touch state so we stop dispatching to them as well.
Arthur Hungfbfa5722021-11-16 02:45:54 +00005654 state.split = false;
Prabir Pradhan07e05b62021-11-19 03:57:24 -08005655 state.filterWindowsExcept(token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005656 }
5657 return OK;
5658}
5659
Prabir Pradhan99987712020-11-10 18:43:05 -08005660void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5661 { // acquire lock
5662 std::scoped_lock _l(mLock);
5663 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005664 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005665 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5666 windowHandle != nullptr ? windowHandle->getName().c_str()
5667 : "token without window");
5668 }
5669
Vishnu Nairc519ff72021-01-21 08:23:08 -08005670 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005671 if (focusedToken != windowToken) {
5672 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5673 enabled ? "enable" : "disable");
5674 return;
5675 }
5676
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005677 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005678 ALOGW("Ignoring request to %s Pointer Capture: "
5679 "window has %s requested pointer capture.",
5680 enabled ? "enable" : "disable", enabled ? "already" : "not");
5681 return;
5682 }
5683
Prabir Pradhan99987712020-11-10 18:43:05 -08005684 setPointerCaptureLocked(enabled);
5685 } // release lock
5686
5687 // Wake the thread to process command entries.
5688 mLooper->wake();
5689}
5690
Michael Wright3dd60e22019-03-27 22:06:44 +00005691std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5692 const sp<IBinder>& token) {
5693 for (const auto& it : mGestureMonitorsByDisplay) {
5694 const std::vector<Monitor>& monitors = it.second;
5695 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005696 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005697 return it.first;
5698 }
5699 }
5700 }
5701 return std::nullopt;
5702}
5703
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005704std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5705 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5706 if (gesturePid.has_value()) {
5707 return gesturePid;
5708 }
5709 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5710}
5711
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005712sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005713 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005714 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005715 }
5716
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005717 for (const auto& [token, connection] : mConnectionsByToken) {
5718 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005719 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005720 }
5721 }
Robert Carr4e670e52018-08-15 13:26:12 -07005722
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005723 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005724}
5725
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005726std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5727 sp<Connection> connection = getConnectionLocked(connectionToken);
5728 if (connection == nullptr) {
5729 return "<nullptr>";
5730 }
5731 return connection->getInputChannelName();
5732}
5733
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005734void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005735 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005736 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005737}
5738
Prabir Pradhancef936d2021-07-21 16:17:52 +00005739void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5740 const sp<Connection>& connection, uint32_t seq,
5741 bool handled, nsecs_t consumeTime) {
5742 // Handle post-event policy actions.
5743 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5744 if (dispatchEntryIt == connection->waitQueue.end()) {
5745 return;
5746 }
5747 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5748 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5749 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5750 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5751 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5752 }
5753 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5754 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5755 connection->inputChannel->getConnectionToken(),
5756 dispatchEntry->deliveryTime, consumeTime, finishTime);
5757 }
5758
5759 bool restartEvent;
5760 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5761 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5762 restartEvent =
5763 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5764 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5765 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5766 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5767 handled);
5768 } else {
5769 restartEvent = false;
5770 }
5771
5772 // Dequeue the event and start the next cycle.
5773 // Because the lock might have been released, it is possible that the
5774 // contents of the wait queue to have been drained, so we need to double-check
5775 // a few things.
5776 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5777 if (dispatchEntryIt != connection->waitQueue.end()) {
5778 dispatchEntry = *dispatchEntryIt;
5779 connection->waitQueue.erase(dispatchEntryIt);
5780 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5781 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5782 if (!connection->responsive) {
5783 connection->responsive = isConnectionResponsive(*connection);
5784 if (connection->responsive) {
5785 // The connection was unresponsive, and now it's responsive.
5786 processConnectionResponsiveLocked(*connection);
5787 }
5788 }
5789 traceWaitQueueLength(*connection);
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005790 if (restartEvent && connection->status == Connection::Status::NORMAL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005791 connection->outboundQueue.push_front(dispatchEntry);
5792 traceOutboundQueueLength(*connection);
5793 } else {
5794 releaseDispatchEntry(dispatchEntry);
5795 }
5796 }
5797
5798 // Start the next dispatch cycle for this connection.
5799 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005800}
5801
Prabir Pradhancef936d2021-07-21 16:17:52 +00005802void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5803 const sp<IBinder>& newToken) {
5804 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5805 scoped_unlock unlock(mLock);
5806 mPolicy->notifyFocusChanged(oldToken, newToken);
5807 };
5808 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005809}
5810
Prabir Pradhancef936d2021-07-21 16:17:52 +00005811void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5812 auto command = [this, token, x, y]() REQUIRES(mLock) {
5813 scoped_unlock unlock(mLock);
5814 mPolicy->notifyDropWindow(token, x, y);
5815 };
5816 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005817}
5818
Prabir Pradhancef936d2021-07-21 16:17:52 +00005819void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5820 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5821 scoped_unlock unlock(mLock);
5822 mPolicy->notifyUntrustedTouch(obscuringPackage);
5823 };
5824 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005825}
5826
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005827void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5828 if (connection == nullptr) {
5829 LOG_ALWAYS_FATAL("Caller must check for nullness");
5830 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005831 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5832 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005833 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005834 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005835 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005836 return;
5837 }
5838 /**
5839 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5840 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5841 * has changed. This could cause newer entries to time out before the already dispatched
5842 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5843 * processes the events linearly. So providing information about the oldest entry seems to be
5844 * most useful.
5845 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005846 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005847 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5848 std::string reason =
5849 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005850 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005851 ns2ms(currentWait),
5852 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005853 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005854 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005855
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005856 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5857
5858 // Stop waking up for events on this connection, it is already unresponsive
5859 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005860}
5861
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005862void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5863 std::string reason =
5864 StringPrintf("%s does not have a focused window", application->getName().c_str());
5865 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005866
Prabir Pradhancef936d2021-07-21 16:17:52 +00005867 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5868 scoped_unlock unlock(mLock);
5869 mPolicy->notifyNoFocusedWindowAnr(application);
5870 };
5871 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005872}
5873
chaviw98318de2021-05-19 16:45:23 -05005874void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005875 const std::string& reason) {
5876 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5877 updateLastAnrStateLocked(windowLabel, reason);
5878}
5879
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005880void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5881 const std::string& reason) {
5882 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005883 updateLastAnrStateLocked(windowLabel, reason);
5884}
5885
5886void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5887 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005888 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005889 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005890 struct tm tm;
5891 localtime_r(&t, &tm);
5892 char timestr[64];
5893 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005894 mLastAnrState.clear();
5895 mLastAnrState += INDENT "ANR:\n";
5896 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005897 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5898 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005899 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005900}
5901
Prabir Pradhancef936d2021-07-21 16:17:52 +00005902void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5903 KeyEntry& entry) {
5904 const KeyEvent event = createKeyEvent(entry);
5905 nsecs_t delay = 0;
5906 { // release lock
5907 scoped_unlock unlock(mLock);
5908 android::base::Timer t;
5909 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5910 entry.policyFlags);
5911 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5912 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5913 std::to_string(t.duration().count()).c_str());
5914 }
5915 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005916
5917 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005918 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005919 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005920 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005921 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005922 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5923 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005925}
5926
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005927void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005928 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5929 scoped_unlock unlock(mLock);
5930 mPolicy->notifyMonitorUnresponsive(pid, reason);
5931 };
5932 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005933}
5934
Prabir Pradhancef936d2021-07-21 16:17:52 +00005935void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005936 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005937 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5938 scoped_unlock unlock(mLock);
5939 mPolicy->notifyWindowUnresponsive(token, reason);
5940 };
5941 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005942}
5943
5944void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005945 auto command = [this, pid]() REQUIRES(mLock) {
5946 scoped_unlock unlock(mLock);
5947 mPolicy->notifyMonitorResponsive(pid);
5948 };
5949 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005950}
5951
Prabir Pradhancef936d2021-07-21 16:17:52 +00005952void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5953 auto command = [this, connectionToken]() REQUIRES(mLock) {
5954 scoped_unlock unlock(mLock);
5955 mPolicy->notifyWindowResponsive(connectionToken);
5956 };
5957 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005958}
5959
5960/**
5961 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5962 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5963 * command entry to the command queue.
5964 */
5965void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5966 std::string reason) {
5967 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5968 if (connection.monitor) {
5969 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5970 reason.c_str());
5971 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5972 if (!pid.has_value()) {
5973 ALOGE("Could not find unresponsive monitor for connection %s",
5974 connection.inputChannel->getName().c_str());
5975 return;
5976 }
5977 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5978 return;
5979 }
5980 // If not a monitor, must be a window
5981 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5982 reason.c_str());
5983 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5984}
5985
5986/**
5987 * Tell the policy that a connection has become responsive so that it can stop ANR.
5988 */
5989void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5990 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5991 if (connection.monitor) {
5992 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5993 if (!pid.has_value()) {
5994 ALOGE("Could not find responsive monitor for connection %s",
5995 connection.inputChannel->getName().c_str());
5996 return;
5997 }
5998 sendMonitorResponsiveCommandLocked(pid.value());
5999 return;
6000 }
6001 // If not a monitor, must be a window
6002 sendWindowResponsiveCommandLocked(connectionToken);
6003}
6004
Prabir Pradhancef936d2021-07-21 16:17:52 +00006005bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006006 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006007 KeyEntry& keyEntry, bool handled) {
6008 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006009 if (!handled) {
6010 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006011 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006012 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006013 return false;
6014 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006015
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006016 // Get the fallback key state.
6017 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006018 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006019 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006020 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006021 connection->inputState.removeFallbackKey(originalKeyCode);
6022 }
6023
6024 if (handled || !dispatchEntry->hasForegroundTarget()) {
6025 // If the application handles the original key for which we previously
6026 // generated a fallback or if the window is not a foreground window,
6027 // then cancel the associated fallback key, if any.
6028 if (fallbackKeyCode != -1) {
6029 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006030 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6031 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
6032 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6033 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6034 keyEntry.policyFlags);
6035 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006036 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006037 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006038
6039 mLock.unlock();
6040
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006041 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006042 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006043
6044 mLock.lock();
6045
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006046 // Cancel the fallback key.
6047 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006048 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006049 "application handled the original non-fallback key "
6050 "or is no longer a foreground target, "
6051 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08006052 options.keyCode = fallbackKeyCode;
6053 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006054 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006055 connection->inputState.removeFallbackKey(originalKeyCode);
6056 }
6057 } else {
6058 // If the application did not handle a non-fallback key, first check
6059 // that we are in a good state to perform unhandled key event processing
6060 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006061 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006062 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006063 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6064 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6065 "since this is not an initial down. "
6066 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6067 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6068 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006069 return false;
6070 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006071
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006072 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006073 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6074 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6075 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6076 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6077 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006078 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006079
6080 mLock.unlock();
6081
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006082 bool fallback =
6083 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006084 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006085
6086 mLock.lock();
6087
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006088 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006089 connection->inputState.removeFallbackKey(originalKeyCode);
6090 return false;
6091 }
6092
6093 // Latch the fallback keycode for this key on an initial down.
6094 // The fallback keycode cannot change at any other point in the lifecycle.
6095 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006096 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006097 fallbackKeyCode = event.getKeyCode();
6098 } else {
6099 fallbackKeyCode = AKEYCODE_UNKNOWN;
6100 }
6101 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
6102 }
6103
6104 ALOG_ASSERT(fallbackKeyCode != -1);
6105
6106 // Cancel the fallback key if the policy decides not to send it anymore.
6107 // We will continue to dispatch the key to the policy but we will no
6108 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006109 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
6110 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006111 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6112 if (fallback) {
6113 ALOGD("Unhandled key event: Policy requested to send key %d"
6114 "as a fallback for %d, but on the DOWN it had requested "
6115 "to send %d instead. Fallback canceled.",
6116 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
6117 } else {
6118 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6119 "but on the DOWN it had requested to send %d. "
6120 "Fallback canceled.",
6121 originalKeyCode, fallbackKeyCode);
6122 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006123 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006124
6125 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6126 "canceling fallback, policy no longer desires it");
6127 options.keyCode = fallbackKeyCode;
6128 synthesizeCancelationEventsForConnectionLocked(connection, options);
6129
6130 fallback = false;
6131 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006132 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006133 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006134 }
6135 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006136
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006137 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6138 {
6139 std::string msg;
6140 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6141 connection->inputState.getFallbackKeys();
6142 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6143 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6144 }
6145 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6146 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006147 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006148 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006149
6150 if (fallback) {
6151 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006152 keyEntry.eventTime = event.getEventTime();
6153 keyEntry.deviceId = event.getDeviceId();
6154 keyEntry.source = event.getSource();
6155 keyEntry.displayId = event.getDisplayId();
6156 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6157 keyEntry.keyCode = fallbackKeyCode;
6158 keyEntry.scanCode = event.getScanCode();
6159 keyEntry.metaState = event.getMetaState();
6160 keyEntry.repeatCount = event.getRepeatCount();
6161 keyEntry.downTime = event.getDownTime();
6162 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006163
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006164 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6165 ALOGD("Unhandled key event: Dispatching fallback key. "
6166 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6167 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6168 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006169 return true; // restart the event
6170 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006171 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6172 ALOGD("Unhandled key event: No fallback key.");
6173 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006174
6175 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006176 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006177 }
6178 }
6179 return false;
6180}
6181
Prabir Pradhancef936d2021-07-21 16:17:52 +00006182bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006183 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006184 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006185 return false;
6186}
6187
Michael Wrightd02c5b62014-02-10 15:10:22 -08006188void InputDispatcher::traceInboundQueueLengthLocked() {
6189 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006190 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006191 }
6192}
6193
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006194void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006195 if (ATRACE_ENABLED()) {
6196 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006197 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6198 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006199 }
6200}
6201
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006202void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006203 if (ATRACE_ENABLED()) {
6204 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006205 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6206 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006207 }
6208}
6209
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006210void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006211 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006212
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006213 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006214 dumpDispatchStateLocked(dump);
6215
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006216 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006217 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006218 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006219 }
6220}
6221
6222void InputDispatcher::monitor() {
6223 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006224 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006225 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006226 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006227}
6228
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006229/**
6230 * Wake up the dispatcher and wait until it processes all events and commands.
6231 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6232 * this method can be safely called from any thread, as long as you've ensured that
6233 * the work you are interested in completing has already been queued.
6234 */
6235bool InputDispatcher::waitForIdle() {
6236 /**
6237 * Timeout should represent the longest possible time that a device might spend processing
6238 * events and commands.
6239 */
6240 constexpr std::chrono::duration TIMEOUT = 100ms;
6241 std::unique_lock lock(mLock);
6242 mLooper->wake();
6243 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6244 return result == std::cv_status::no_timeout;
6245}
6246
Vishnu Naire798b472020-07-23 13:52:21 -07006247/**
6248 * Sets focus to the window identified by the token. This must be called
6249 * after updating any input window handles.
6250 *
6251 * Params:
6252 * request.token - input channel token used to identify the window that should gain focus.
6253 * request.focusedToken - the token that the caller expects currently to be focused. If the
6254 * specified token does not match the currently focused window, this request will be dropped.
6255 * If the specified focused token matches the currently focused window, the call will succeed.
6256 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6257 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6258 * when requesting the focus change. This determines which request gets
6259 * precedence if there is a focus change request from another source such as pointer down.
6260 */
Vishnu Nair958da932020-08-21 17:12:37 -07006261void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6262 { // acquire lock
6263 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006264 std::optional<FocusResolver::FocusChanges> changes =
6265 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6266 if (changes) {
6267 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006268 }
6269 } // release lock
6270 // Wake up poll loop since it may need to make new input dispatching choices.
6271 mLooper->wake();
6272}
6273
Vishnu Nairc519ff72021-01-21 08:23:08 -08006274void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6275 if (changes.oldFocus) {
6276 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006277 if (focusedInputChannel) {
6278 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6279 "focus left window");
6280 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006281 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006282 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006283 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006284 if (changes.newFocus) {
6285 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006286 }
6287
Prabir Pradhan99987712020-11-10 18:43:05 -08006288 // If a window has pointer capture, then it must have focus. We need to ensure that this
6289 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6290 // If the window loses focus before it loses pointer capture, then the window can be in a state
6291 // where it has pointer capture but not focus, violating the contract. Therefore we must
6292 // dispatch the pointer capture event before the focus event. Since focus events are added to
6293 // the front of the queue (above), we add the pointer capture event to the front of the queue
6294 // after the focus events are added. This ensures the pointer capture event ends up at the
6295 // front.
6296 disablePointerCaptureForcedLocked();
6297
Vishnu Nairc519ff72021-01-21 08:23:08 -08006298 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006299 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006300 }
6301}
Vishnu Nair958da932020-08-21 17:12:37 -07006302
Prabir Pradhan99987712020-11-10 18:43:05 -08006303void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006304 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006305 return;
6306 }
6307
6308 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6309
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006310 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006311 setPointerCaptureLocked(false);
6312 }
6313
6314 if (!mWindowTokenWithPointerCapture) {
6315 // No need to send capture changes because no window has capture.
6316 return;
6317 }
6318
6319 if (mPendingEvent != nullptr) {
6320 // Move the pending event to the front of the queue. This will give the chance
6321 // for the pending event to be dropped if it is a captured event.
6322 mInboundQueue.push_front(mPendingEvent);
6323 mPendingEvent = nullptr;
6324 }
6325
6326 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006327 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006328 mInboundQueue.push_front(std::move(entry));
6329}
6330
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006331void InputDispatcher::setPointerCaptureLocked(bool enable) {
6332 mCurrentPointerCaptureRequest.enable = enable;
6333 mCurrentPointerCaptureRequest.seq++;
6334 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006335 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006336 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006337 };
6338 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006339}
6340
Vishnu Nair599f1412021-06-21 10:39:58 -07006341void InputDispatcher::displayRemoved(int32_t displayId) {
6342 { // acquire lock
6343 std::scoped_lock _l(mLock);
6344 // Set an empty list to remove all handles from the specific display.
6345 setInputWindowsLocked(/* window handles */ {}, displayId);
6346 setFocusedApplicationLocked(displayId, nullptr);
6347 // Call focus resolver to clean up stale requests. This must be called after input windows
6348 // have been removed for the removed display.
6349 mFocusResolver.displayRemoved(displayId);
6350 } // release lock
6351
6352 // Wake up poll loop since it may need to make new input dispatching choices.
6353 mLooper->wake();
6354}
6355
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006356void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6357 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006358 // The listener sends the windows as a flattened array. Separate the windows by display for
6359 // more convenient parsing.
6360 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006361 for (const auto& info : windowInfos) {
6362 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6363 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6364 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006365
6366 { // acquire lock
6367 std::scoped_lock _l(mLock);
6368 mDisplayInfos.clear();
6369 for (const auto& displayInfo : displayInfos) {
6370 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6371 }
6372
6373 for (const auto& [displayId, handles] : handlesPerDisplay) {
6374 setInputWindowsLocked(handles, displayId);
6375 }
6376 }
6377 // Wake up poll loop since it may need to make new input dispatching choices.
6378 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006379}
6380
Vishnu Nair062a8672021-09-03 16:07:44 -07006381bool InputDispatcher::shouldDropInput(
6382 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6383 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6384 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6385 isWindowObscuredLocked(windowHandle))) {
6386 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6387 "%" PRId32 ".",
6388 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6389 windowHandle->getInfo()->inputFeatures.string().c_str(),
6390 windowHandle->getInfo()->displayId);
6391 return true;
6392 }
6393 return false;
6394}
6395
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006396void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6397 const std::vector<gui::WindowInfo>& windowInfos,
6398 const std::vector<DisplayInfo>& displayInfos) {
6399 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6400}
6401
Arthur Hungdfd528e2021-12-08 13:23:04 +00006402void InputDispatcher::cancelCurrentTouch() {
6403 {
6404 std::scoped_lock _l(mLock);
6405 ALOGD("Canceling all ongoing pointer gestures on all displays.");
6406 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
6407 "cancel current touch");
6408 synthesizeCancelationEventsForAllConnectionsLocked(options);
6409
6410 mTouchStatesByDisplay.clear();
6411 mLastHoverWindowHandle.clear();
6412 }
6413 // Wake up poll loop since there might be work to do.
6414 mLooper->wake();
6415}
6416
Garfield Tane84e6f92019-08-29 17:28:41 -07006417} // namespace android::inputdispatcher