blob: 3d860f961c4d0e4d1e2afcc17ab4fd4ff763c801 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
Michael Wright2b3c3302018-03-02 17:19:13 +000022#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080023#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080024#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050025#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070026#include <binder/Binder.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080027#include <ftl/enum.h>
chaviw15fab6f2021-06-07 14:15:52 -050028#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080029#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070030#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000031#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070032#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010033#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070034#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080035
Michael Wright44753b12020-07-08 13:48:11 +010036#include <cerrno>
37#include <cinttypes>
38#include <climits>
39#include <cstddef>
40#include <ctime>
41#include <queue>
42#include <sstream>
43
44#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070045#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010046
Michael Wrightd02c5b62014-02-10 15:10:22 -080047#define INDENT " "
48#define INDENT2 " "
49#define INDENT3 " "
50#define INDENT4 " "
51
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080052using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000053using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080054using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070055using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050056using android::gui::FocusRequest;
57using android::gui::TouchOcclusionMode;
58using android::gui::WindowInfo;
59using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080060using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100061using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080062using android::os::InputEventInjectionResult;
63using android::os::InputEventInjectionSync;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080064
Garfield Tane84e6f92019-08-29 17:28:41 -070065namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080066
Prabir Pradhancef936d2021-07-21 16:17:52 +000067namespace {
68
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080069/**
70 * Log detailed debug messages about each inbound event notification to the dispatcher.
71 * Enable this via "adb shell setprop log.tag.InputDispatcherInboundEvent DEBUG" (requires restart)
72 */
73const bool DEBUG_INBOUND_EVENT_DETAILS =
74 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "InboundEvent", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000075
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080076/**
77 * Log detailed debug messages about each outbound event processed by the dispatcher.
78 * Enable this via "adb shell setprop log.tag.InputDispatcherOutboundEvent DEBUG" (requires restart)
79 */
80const bool DEBUG_OUTBOUND_EVENT_DETAILS =
81 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "OutboundEvent", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000082
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080083/**
84 * Log debug messages about the dispatch cycle.
85 * Enable this via "adb shell setprop log.tag.InputDispatcherDispatchCycle DEBUG" (requires restart)
86 */
87const bool DEBUG_DISPATCH_CYCLE =
88 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "DispatchCycle", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000089
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080090/**
91 * Log debug messages about channel creation
92 * Enable this via "adb shell setprop log.tag.InputDispatcherChannelCreation DEBUG" (requires
93 * restart)
94 */
95const bool DEBUG_CHANNEL_CREATION =
96 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "ChannelCreation", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +000097
Siarhei Vishniakou63138b62022-03-03 11:33:19 -080098/**
99 * Log debug messages about input event injection.
100 * Enable this via "adb shell setprop log.tag.InputDispatcherInjection DEBUG" (requires restart)
101 */
102const bool DEBUG_INJECTION =
103 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Injection", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000104
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800105/**
106 * Log debug messages about input focus tracking.
107 * Enable this via "adb shell setprop log.tag.InputDispatcherFocus DEBUG" (requires restart)
108 */
109const bool DEBUG_FOCUS =
110 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Focus", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000111
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800112/**
113 * Log debug messages about touch mode event
114 * Enable this via "adb shell setprop log.tag.InputDispatcherTouchMode DEBUG" (requires restart)
115 */
116const bool DEBUG_TOUCH_MODE =
117 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "TouchMode", ANDROID_LOG_INFO);
Antonio Kantekf16f2832021-09-28 04:39:20 +0000118
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800119/**
120 * Log debug messages about touch occlusion
121 * Enable this via "adb shell setprop log.tag.InputDispatcherTouchOcclusion DEBUG" (requires
122 * restart)
123 */
124const bool DEBUG_TOUCH_OCCLUSION =
125 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "TouchOcclusion", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000126
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800127/**
128 * Log debug messages about the app switch latency optimization.
129 * Enable this via "adb shell setprop log.tag.InputDispatcherAppSwitch DEBUG" (requires restart)
130 */
131const bool DEBUG_APP_SWITCH =
132 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "AppSwitch", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000133
Siarhei Vishniakou63138b62022-03-03 11:33:19 -0800134/**
135 * Log debug messages about hover events.
136 * Enable this via "adb shell setprop log.tag.InputDispatcherHover DEBUG" (requires restart)
137 */
138const bool DEBUG_HOVER =
139 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Hover", ANDROID_LOG_INFO);
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000140
Prabir Pradhancef936d2021-07-21 16:17:52 +0000141// Temporarily releases a held mutex for the lifetime of the instance.
142// Named to match std::scoped_lock
143class scoped_unlock {
144public:
145 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
146 ~scoped_unlock() { mMutex.lock(); }
147
148private:
149 std::mutex& mMutex;
150};
151
Michael Wrightd02c5b62014-02-10 15:10:22 -0800152// Default input dispatching timeout if there is no focused application or paused window
153// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800154const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
155 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
156 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800157
158// Amount of time to allow for all pending events to be processed when an app switch
159// key is on the way. This is used to preempt input dispatch and drop input events
160// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000161constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800162
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800163const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800164
Michael Wrightd02c5b62014-02-10 15:10:22 -0800165// 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 +0000166constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
167
168// Log a warning when an interception call takes longer than this to process.
169constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800170
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700171// Additional key latency in case a connection is still processing some motion events.
172// This will help with the case when a user touched a button that opens a new window,
173// and gives us the chance to dispatch the key to this new window.
174constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
175
Michael Wrightd02c5b62014-02-10 15:10:22 -0800176// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000177constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
178
Antonio Kantekea47acb2021-12-23 12:41:25 -0800179// Event log tags. See EventLogTags.logtags for reference.
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000180constexpr int LOGTAG_INPUT_INTERACTION = 62000;
181constexpr int LOGTAG_INPUT_FOCUS = 62001;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000182constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000183
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000184inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 return systemTime(SYSTEM_TIME_MONOTONIC);
186}
187
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000188inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 return value ? "true" : "false";
190}
191
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000192inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000193 if (binder == nullptr) {
194 return "<null>";
195 }
196 return StringPrintf("%p", binder.get());
197}
198
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000199inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700200 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
201 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800202}
203
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000204bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800205 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700206 case AKEY_EVENT_ACTION_DOWN:
207 case AKEY_EVENT_ACTION_UP:
208 return true;
209 default:
210 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 }
212}
213
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000214bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700215 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216 ALOGE("Key event has invalid action code 0x%x", action);
217 return false;
218 }
219 return true;
220}
221
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000222bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700224 case AMOTION_EVENT_ACTION_DOWN:
225 case AMOTION_EVENT_ACTION_UP:
226 case AMOTION_EVENT_ACTION_CANCEL:
227 case AMOTION_EVENT_ACTION_MOVE:
228 case AMOTION_EVENT_ACTION_OUTSIDE:
229 case AMOTION_EVENT_ACTION_HOVER_ENTER:
230 case AMOTION_EVENT_ACTION_HOVER_MOVE:
231 case AMOTION_EVENT_ACTION_HOVER_EXIT:
232 case AMOTION_EVENT_ACTION_SCROLL:
233 return true;
234 case AMOTION_EVENT_ACTION_POINTER_DOWN:
235 case AMOTION_EVENT_ACTION_POINTER_UP: {
236 int32_t index = getMotionEventActionPointerIndex(action);
237 return index >= 0 && index < pointerCount;
238 }
239 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
240 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
241 return actionButton != 0;
242 default:
243 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800244 }
245}
246
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000247int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500248 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
249}
250
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000251bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
252 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700253 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 ALOGE("Motion event has invalid action code 0x%x", action);
255 return false;
256 }
257 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Siarhei Vishniakou01747382022-01-20 13:23:27 -0800258 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %zu.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700259 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800260 return false;
261 }
262 BitSet32 pointerIdBits;
263 for (size_t i = 0; i < pointerCount; i++) {
264 int32_t id = pointerProperties[i].id;
265 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700266 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
267 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800268 return false;
269 }
270 if (pointerIdBits.hasBit(id)) {
271 ALOGE("Motion event has duplicate pointer id %d", id);
272 return false;
273 }
274 pointerIdBits.markBit(id);
275 }
276 return true;
277}
278
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000279std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800280 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000281 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800282 }
283
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000284 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800285 bool first = true;
286 Region::const_iterator cur = region.begin();
287 Region::const_iterator const tail = region.end();
288 while (cur != tail) {
289 if (first) {
290 first = false;
291 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800292 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800293 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800294 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295 cur++;
296 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000297 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800298}
299
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000300std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500301 constexpr size_t maxEntries = 50; // max events to print
302 constexpr size_t skipBegin = maxEntries / 2;
303 const size_t skipEnd = queue.size() - maxEntries / 2;
304 // skip from maxEntries / 2 ... size() - maxEntries/2
305 // only print from 0 .. skipBegin and then from skipEnd .. size()
306
307 std::string dump;
308 for (size_t i = 0; i < queue.size(); i++) {
309 const DispatchEntry& entry = *queue[i];
310 if (i >= skipBegin && i < skipEnd) {
311 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
312 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
313 continue;
314 }
315 dump.append(INDENT4);
316 dump += entry.eventEntry->getDescription();
317 dump += StringPrintf(", seq=%" PRIu32
318 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
319 entry.seq, entry.targetFlags, entry.resolvedAction,
320 ns2ms(currentTime - entry.eventEntry->eventTime));
321 if (entry.deliveryTime != 0) {
322 // This entry was delivered, so add information on how long we've been waiting
323 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
324 }
325 dump.append("\n");
326 }
327 return dump;
328}
329
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700330/**
331 * Find the entry in std::unordered_map by key, and return it.
332 * If the entry is not found, return a default constructed entry.
333 *
334 * Useful when the entries are vectors, since an empty vector will be returned
335 * if the entry is not found.
336 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
337 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700338template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000339V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700340 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700341 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800342}
343
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000344bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700345 if (first == second) {
346 return true;
347 }
348
349 if (first == nullptr || second == nullptr) {
350 return false;
351 }
352
353 return first->getToken() == second->getToken();
354}
355
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000356bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000357 if (first == nullptr || second == nullptr) {
358 return false;
359 }
360 return first->applicationInfo.token != nullptr &&
361 first->applicationInfo.token == second->applicationInfo.token;
362}
363
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000364std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
365 std::shared_ptr<EventEntry> eventEntry,
366 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700367 if (inputTarget.useDefaultPointerTransform()) {
368 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700369 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700370 inputTarget.displayTransform,
371 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000372 }
373
374 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
375 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
376
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700377 std::vector<PointerCoords> pointerCoords;
378 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000379
380 // Use the first pointer information to normalize all other pointers. This could be any pointer
381 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700382 // uses the transform for the normalized pointer.
383 const ui::Transform& firstPointerTransform =
384 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
385 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000386
387 // Iterate through all pointers in the event to normalize against the first.
388 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
389 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
390 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700391 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000392
393 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700394 // First, apply the current pointer's transform to update the coordinates into
395 // window space.
396 pointerCoords[pointerIndex].transform(currTransform);
397 // Next, apply the inverse transform of the normalized coordinates so the
398 // current coordinates are transformed into the normalized coordinate space.
399 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000400 }
401
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700402 std::unique_ptr<MotionEntry> combinedMotionEntry =
403 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
404 motionEntry.deviceId, motionEntry.source,
405 motionEntry.displayId, motionEntry.policyFlags,
406 motionEntry.action, motionEntry.actionButton,
407 motionEntry.flags, motionEntry.metaState,
408 motionEntry.buttonState, motionEntry.classification,
409 motionEntry.edgeFlags, motionEntry.xPrecision,
410 motionEntry.yPrecision, motionEntry.xCursorPosition,
411 motionEntry.yCursorPosition, motionEntry.downTime,
412 motionEntry.pointerCount, motionEntry.pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +0000413 pointerCoords.data());
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000414
415 if (motionEntry.injectionState) {
416 combinedMotionEntry->injectionState = motionEntry.injectionState;
417 combinedMotionEntry->injectionState->refCount += 1;
418 }
419
420 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700421 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700422 firstPointerTransform, inputTarget.displayTransform,
423 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000424 return dispatchEntry;
425}
426
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000427status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
428 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700429 std::unique_ptr<InputChannel> uniqueServerChannel;
430 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
431
432 serverChannel = std::move(uniqueServerChannel);
433 return result;
434}
435
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500436template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000437bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500438 if (lhs == nullptr && rhs == nullptr) {
439 return true;
440 }
441 if (lhs == nullptr || rhs == nullptr) {
442 return false;
443 }
444 return *lhs == *rhs;
445}
446
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000447KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000448 KeyEvent event;
449 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
450 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
451 entry.repeatCount, entry.downTime, entry.eventTime);
452 return event;
453}
454
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000455bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000456 // Do not keep track of gesture monitors. They receive every event and would disproportionately
457 // affect the statistics.
458 if (connection.monitor) {
459 return false;
460 }
461 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
462 if (!connection.responsive) {
463 return false;
464 }
465 return true;
466}
467
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000468bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000469 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
470 const int32_t& inputEventId = eventEntry.id;
471 if (inputEventId != dispatchEntry.resolvedEventId) {
472 // Event was transmuted
473 return false;
474 }
475 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
476 return false;
477 }
478 // Only track latency for events that originated from hardware
479 if (eventEntry.isSynthesized()) {
480 return false;
481 }
482 const EventEntry::Type& inputEventEntryType = eventEntry.type;
483 if (inputEventEntryType == EventEntry::Type::KEY) {
484 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
485 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
486 return false;
487 }
488 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
489 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
490 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
491 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
492 return false;
493 }
494 } else {
495 // Not a key or a motion
496 return false;
497 }
498 if (!shouldReportMetricsForConnection(connection)) {
499 return false;
500 }
501 return true;
502}
503
Prabir Pradhancef936d2021-07-21 16:17:52 +0000504/**
505 * Connection is responsive if it has no events in the waitQueue that are older than the
506 * current time.
507 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000508bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000509 const nsecs_t currentTime = now();
510 for (const DispatchEntry* entry : connection.waitQueue) {
511 if (entry->timeoutTime < currentTime) {
512 return false;
513 }
514 }
515 return true;
516}
517
Antonio Kantekf16f2832021-09-28 04:39:20 +0000518// Returns true if the event type passed as argument represents a user activity.
519bool isUserActivityEvent(const EventEntry& eventEntry) {
520 switch (eventEntry.type) {
521 case EventEntry::Type::FOCUS:
522 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
523 case EventEntry::Type::DRAG:
524 case EventEntry::Type::TOUCH_MODE_CHANGED:
525 case EventEntry::Type::SENSOR:
526 case EventEntry::Type::CONFIGURATION_CHANGED:
527 return false;
528 case EventEntry::Type::DEVICE_RESET:
529 case EventEntry::Type::KEY:
530 case EventEntry::Type::MOTION:
531 return true;
532 }
533}
534
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800535// Returns true if the given window can accept pointer events at the given display location.
Prabir Pradhand65552b2021-10-07 11:23:50 -0700536bool windowAcceptsTouchAt(const WindowInfo& windowInfo, int32_t displayId, int32_t x, int32_t y,
537 bool isStylus) {
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800538 const auto inputConfig = windowInfo.inputConfig;
539 if (windowInfo.displayId != displayId ||
540 inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800541 return false;
542 }
Prabir Pradhand65552b2021-10-07 11:23:50 -0700543 const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800544 if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800545 return false;
546 }
Prabir Pradhan06349042022-02-04 09:19:17 -0800547 if (!windowInfo.touchableRegionContainsPoint(x, y)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -0800548 return false;
549 }
550 return true;
551}
552
Prabir Pradhand65552b2021-10-07 11:23:50 -0700553bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
554 return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
555 (entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS ||
556 entry.pointerProperties[pointerIndex].toolType == AMOTION_EVENT_TOOL_TYPE_ERASER);
557}
558
Prabir Pradhan6dfbf262022-03-14 15:24:30 +0000559// Determines if the given window can be targeted as InputTarget::FLAG_FOREGROUND.
560// Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
561// such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
562// be sent to such a window, but it is not a foreground event and doesn't use
563// InputTarget::FLAG_FOREGROUND.
564bool canReceiveForegroundTouches(const WindowInfo& info) {
565 // A non-touchable window can still receive touch events (e.g. in the case of
566 // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
567 return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
568}
569
Antonio Kantek48710e42022-03-24 14:19:30 -0700570bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, int32_t pid, int32_t uid) {
571 if (windowHandle == nullptr) {
572 return false;
573 }
574 const WindowInfo* windowInfo = windowHandle->getInfo();
575 if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
576 return true;
577 }
578 return false;
579}
580
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000581} // namespace
582
Michael Wrightd02c5b62014-02-10 15:10:22 -0800583// --- InputDispatcher ---
584
Garfield Tan00f511d2019-06-12 16:55:40 -0700585InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800586 : InputDispatcher(policy, STALE_EVENT_TIMEOUT) {}
587
588InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy,
589 std::chrono::nanoseconds staleEventTimeout)
Garfield Tan00f511d2019-06-12 16:55:40 -0700590 : mPolicy(policy),
591 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700592 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800593 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700594 mAppSwitchSawKeyDown(false),
595 mAppSwitchDueTime(LONG_LONG_MAX),
596 mNextUnblockedEvent(nullptr),
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800597 mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
Garfield Tan00f511d2019-06-12 16:55:40 -0700598 mDispatchEnabled(false),
599 mDispatchFrozen(false),
600 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800601 // mInTouchMode will be initialized by the WindowManager to the default device config.
602 // To avoid leaking stack in case that call never comes, and for tests,
603 // initialize it here anyways.
Antonio Kantekf16f2832021-09-28 04:39:20 +0000604 mInTouchMode(kDefaultInTouchMode),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100605 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000606 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800607 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800608 mStaleEventTimeout(staleEventTimeout),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000609 mLatencyAggregator(),
Siarhei Vishniakoubd252722022-01-06 03:49:35 -0800610 mLatencyTracker(&mLatencyAggregator) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800611 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800612 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800613
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700614 mWindowInfoListener = new DispatcherWindowListener(*this);
615 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
616
Yi Kong9b14ac62018-07-17 13:48:38 -0700617 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618
619 policy->getDispatcherConfiguration(&mConfig);
620}
621
622InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000623 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800624
Prabir Pradhancef936d2021-07-21 16:17:52 +0000625 resetKeyRepeatLocked();
626 releasePendingEventLocked();
627 drainInboundQueueLocked();
628 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800629
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000630 while (!mConnectionsByToken.empty()) {
631 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000632 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
633 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800634 }
635}
636
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700637status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700638 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700639 return ALREADY_EXISTS;
640 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700641 mThread = std::make_unique<InputThread>(
642 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
643 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700644}
645
646status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700647 if (mThread && mThread->isCallingThread()) {
648 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700649 return INVALID_OPERATION;
650 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700651 mThread.reset();
652 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700653}
654
Michael Wrightd02c5b62014-02-10 15:10:22 -0800655void InputDispatcher::dispatchOnce() {
656 nsecs_t nextWakeupTime = LONG_LONG_MAX;
657 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800658 std::scoped_lock _l(mLock);
659 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800660
661 // Run a dispatch loop if there are no pending commands.
662 // The dispatch loop might enqueue commands to run afterwards.
663 if (!haveCommandsLocked()) {
664 dispatchOnceInnerLocked(&nextWakeupTime);
665 }
666
667 // Run all pending commands if there are any.
668 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000669 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800670 nextWakeupTime = LONG_LONG_MIN;
671 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800672
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700673 // If we are still waiting for ack on some events,
674 // we might have to wake up earlier to check if an app is anr'ing.
675 const nsecs_t nextAnrCheck = processAnrsLocked();
676 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
677
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800678 // We are about to enter an infinitely long sleep, because we have no commands or
679 // pending or queued events
680 if (nextWakeupTime == LONG_LONG_MAX) {
681 mDispatcherEnteredIdle.notify_all();
682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800683 } // release lock
684
685 // Wait for callback or timeout or wake. (make sure we round up, not down)
686 nsecs_t currentTime = now();
687 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
688 mLooper->pollOnce(timeoutMillis);
689}
690
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700691/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500692 * Raise ANR if there is no focused window.
693 * Before the ANR is raised, do a final state check:
694 * 1. The currently focused application must be the same one we are waiting for.
695 * 2. Ensure we still don't have a focused window.
696 */
697void InputDispatcher::processNoFocusedWindowAnrLocked() {
698 // Check if the application that we are waiting for is still focused.
699 std::shared_ptr<InputApplicationHandle> focusedApplication =
700 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
701 if (focusedApplication == nullptr ||
702 focusedApplication->getApplicationToken() !=
703 mAwaitedFocusedApplication->getApplicationToken()) {
704 // Unexpected because we should have reset the ANR timer when focused application changed
705 ALOGE("Waited for a focused window, but focused application has already changed to %s",
706 focusedApplication->getName().c_str());
707 return; // The focused application has changed.
708 }
709
chaviw98318de2021-05-19 16:45:23 -0500710 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500711 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
712 if (focusedWindowHandle != nullptr) {
713 return; // We now have a focused window. No need for ANR.
714 }
715 onAnrLocked(mAwaitedFocusedApplication);
716}
717
718/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700719 * Check if any of the connections' wait queues have events that are too old.
720 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
721 * Return the time at which we should wake up next.
722 */
723nsecs_t InputDispatcher::processAnrsLocked() {
724 const nsecs_t currentTime = now();
725 nsecs_t nextAnrCheck = LONG_LONG_MAX;
726 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
727 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
728 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500729 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700730 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500731 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700732 return LONG_LONG_MIN;
733 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500734 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700735 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
736 }
737 }
738
739 // Check if any connection ANRs are due
740 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
741 if (currentTime < nextAnrCheck) { // most likely scenario
742 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
743 }
744
745 // If we reached here, we have an unresponsive connection.
746 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
747 if (connection == nullptr) {
748 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
749 return nextAnrCheck;
750 }
751 connection->responsive = false;
752 // Stop waking up for this unresponsive connection
753 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000754 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700755 return LONG_LONG_MIN;
756}
757
Prabir Pradhan1376fcd2022-01-21 09:56:35 -0800758std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
759 const sp<Connection>& connection) {
760 if (connection->monitor) {
761 return mMonitorDispatchingTimeout;
762 }
763 const sp<WindowInfoHandle> window =
764 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700765 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500766 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700767 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500768 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700769}
770
Michael Wrightd02c5b62014-02-10 15:10:22 -0800771void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
772 nsecs_t currentTime = now();
773
Jeff Browndc5992e2014-04-11 01:27:26 -0700774 // Reset the key repeat timer whenever normal dispatch is suspended while the
775 // device is in a non-interactive state. This is to ensure that we abort a key
776 // repeat if the device is just coming out of sleep.
777 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800778 resetKeyRepeatLocked();
779 }
780
781 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
782 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100783 if (DEBUG_FOCUS) {
784 ALOGD("Dispatch frozen. Waiting some more.");
785 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800786 return;
787 }
788
789 // Optimize latency of app switches.
790 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
791 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
792 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
793 if (mAppSwitchDueTime < *nextWakeupTime) {
794 *nextWakeupTime = mAppSwitchDueTime;
795 }
796
797 // Ready to start a new event.
798 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700799 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700800 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800801 if (isAppSwitchDue) {
802 // The inbound queue is empty so the app switch key we were waiting
803 // for will never arrive. Stop waiting for it.
804 resetPendingAppSwitchLocked(false);
805 isAppSwitchDue = false;
806 }
807
808 // Synthesize a key repeat if appropriate.
809 if (mKeyRepeatState.lastKeyEntry) {
810 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
811 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
812 } else {
813 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
814 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
815 }
816 }
817 }
818
819 // Nothing to do if there is no pending event.
820 if (!mPendingEvent) {
821 return;
822 }
823 } else {
824 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700825 mPendingEvent = mInboundQueue.front();
826 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800827 traceInboundQueueLengthLocked();
828 }
829
830 // Poke user activity for this event.
831 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700832 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800834 }
835
836 // Now we have an event to dispatch.
837 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700838 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800839 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700840 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800841 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700842 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800843 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700844 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800845 }
846
847 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700848 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800849 }
850
851 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700852 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700853 const ConfigurationChangedEntry& typedEntry =
854 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700855 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700856 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700857 break;
858 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800859
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700860 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700861 const DeviceResetEntry& typedEntry =
862 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700863 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700864 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700865 break;
866 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800867
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100868 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700869 std::shared_ptr<FocusEntry> typedEntry =
870 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100871 dispatchFocusLocked(currentTime, typedEntry);
872 done = true;
873 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
874 break;
875 }
876
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700877 case EventEntry::Type::TOUCH_MODE_CHANGED: {
878 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
879 dispatchTouchModeChangeLocked(currentTime, typedEntry);
880 done = true;
881 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
882 break;
883 }
884
Prabir Pradhan99987712020-11-10 18:43:05 -0800885 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
886 const auto typedEntry =
887 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
888 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
889 done = true;
890 break;
891 }
892
arthurhungb89ccb02020-12-30 16:19:01 +0800893 case EventEntry::Type::DRAG: {
894 std::shared_ptr<DragEntry> typedEntry =
895 std::static_pointer_cast<DragEntry>(mPendingEvent);
896 dispatchDragLocked(currentTime, typedEntry);
897 done = true;
898 break;
899 }
900
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700901 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700902 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700903 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700904 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700905 resetPendingAppSwitchLocked(true);
906 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700907 } else if (dropReason == DropReason::NOT_DROPPED) {
908 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700909 }
910 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700911 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700912 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700913 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700914 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
915 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700916 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700917 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700918 break;
919 }
920
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700921 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700922 std::shared_ptr<MotionEntry> motionEntry =
923 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700924 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
925 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800926 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700927 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700928 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700929 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700930 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
931 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700932 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700933 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700934 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800935 }
Chris Yef59a2f42020-10-16 12:55:26 -0700936
937 case EventEntry::Type::SENSOR: {
938 std::shared_ptr<SensorEntry> sensorEntry =
939 std::static_pointer_cast<SensorEntry>(mPendingEvent);
940 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
941 dropReason = DropReason::APP_SWITCH;
942 }
943 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
944 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
945 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
946 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
947 dropReason = DropReason::STALE;
948 }
949 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
950 done = true;
951 break;
952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 }
954
955 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700956 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700957 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800958 }
Michael Wright3a981722015-06-10 15:26:13 +0100959 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800960
961 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700962 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800963 }
964}
965
Siarhei Vishniakou289e9242022-02-15 14:50:16 -0800966bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
967 return std::chrono::nanoseconds(currentTime - entry.eventTime) >= mStaleEventTimeout;
968}
969
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700970/**
971 * Return true if the events preceding this incoming motion event should be dropped
972 * Return false otherwise (the default behaviour)
973 */
974bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700975 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700976 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700977
978 // Optimize case where the current application is unresponsive and the user
979 // decides to touch a window in a different application.
980 // If the application takes too long to catch up then we drop all events preceding
981 // the touch into the other window.
982 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700983 int32_t displayId = motionEntry.displayId;
984 int32_t x = static_cast<int32_t>(
985 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
986 int32_t y = static_cast<int32_t>(
987 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Prabir Pradhand65552b2021-10-07 11:23:50 -0700988
989 const bool isStylus = isPointerFromStylus(motionEntry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -0500990 sp<WindowInfoHandle> touchedWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -0700991 findTouchedWindowAtLocked(displayId, x, y, nullptr, isStylus);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700992 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700993 touchedWindowHandle->getApplicationToken() !=
994 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700995 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700996 ALOGI("Pruning input queue because user touched a different application while waiting "
997 "for %s",
998 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700999 return true;
1000 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001001
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001002 // Alternatively, maybe there's a spy window that could handle this event.
1003 const std::vector<sp<WindowInfoHandle>> touchedSpies =
1004 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
1005 for (const auto& windowHandle : touchedSpies) {
1006 const sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +00001007 if (connection != nullptr && connection->responsive) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001008 // This spy window could take more input. Drop all events preceding this
1009 // event, so that the spy window can get a chance to receive the stream.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001010 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08001011 "responsive spy window that may handle the event.",
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001012 mAwaitedFocusedApplication->getName().c_str());
1013 return true;
1014 }
1015 }
1016 }
1017
1018 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
1019 // yet been processed by some connections, the dispatcher will wait for these motion
1020 // events to be processed before dispatching the key event. This is because these motion events
1021 // may cause a new window to be launched, which the user might expect to receive focus.
1022 // To prevent waiting forever for such events, just send the key to the currently focused window
1023 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1024 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1025 "just send the pending key event to the focused window.");
1026 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001027 }
1028 return false;
1029}
1030
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001031bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001032 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001033 mInboundQueue.push_back(std::move(newEntry));
1034 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001035 traceInboundQueueLengthLocked();
1036
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001037 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001038 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001039 // Optimize app switch latency.
1040 // If the application takes too long to catch up then we drop all events preceding
1041 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001042 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001043 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001044 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001045 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001046 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001047 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001048 if (DEBUG_APP_SWITCH) {
1049 ALOGD("App switch is pending!");
1050 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001051 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001052 mAppSwitchSawKeyDown = false;
1053 needWake = true;
1054 }
1055 }
1056 }
Arthur Hung2ee6d0b2022-03-03 20:19:38 +08001057
1058 // If a new up event comes in, and the pending event with same key code has been asked
1059 // to try again later because of the policy. We have to reset the intercept key wake up
1060 // time for it may have been handled in the policy and could be dropped.
1061 if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1062 mPendingEvent->type == EventEntry::Type::KEY) {
1063 KeyEntry& pendingKey = static_cast<KeyEntry&>(*mPendingEvent);
1064 if (pendingKey.keyCode == keyEntry.keyCode &&
1065 pendingKey.interceptKeyResult ==
1066 KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1067 pendingKey.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1068 pendingKey.interceptKeyWakeupTime = 0;
1069 needWake = true;
1070 }
1071 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001072 break;
1073 }
1074
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001075 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001076 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1077 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001078 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001079 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001080 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001081 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001082 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001083 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1084 break;
1085 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001086 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001087 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001088 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001089 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001090 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1091 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001092 // nothing to do
1093 break;
1094 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001095 }
1096
1097 return needWake;
1098}
1099
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001100void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001101 // Do not store sensor event in recent queue to avoid flooding the queue.
1102 if (entry->type != EventEntry::Type::SENSOR) {
1103 mRecentQueue.push_back(entry);
1104 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001105 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001106 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001107 }
1108}
1109
chaviw98318de2021-05-19 16:45:23 -05001110sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1111 int32_t y, TouchState* touchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07001112 bool isStylus,
chaviw98318de2021-05-19 16:45:23 -05001113 bool addOutsideTargets,
1114 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001115 if (addOutsideTargets && touchState == nullptr) {
1116 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001117 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118 // Traverse windows from front to back to find touched window.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001119 const auto& windowHandles = getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05001120 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001121 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001122 continue;
1123 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001125 const WindowInfo& info = *windowHandle->getInfo();
Prabir Pradhand65552b2021-10-07 11:23:50 -07001126 if (!info.isSpy() && windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001127 return windowHandle;
1128 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001129
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08001130 if (addOutsideTargets &&
1131 info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08001132 touchState->addOrUpdateWindow(windowHandle, InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1133 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134 }
1135 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001136 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001137}
1138
Prabir Pradhand65552b2021-10-07 11:23:50 -07001139std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
1140 int32_t displayId, int32_t x, int32_t y, bool isStylus) const {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001141 // Traverse windows from front to back and gather the touched spy windows.
1142 std::vector<sp<WindowInfoHandle>> spyWindows;
1143 const auto& windowHandles = getWindowHandlesLocked(displayId);
1144 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1145 const WindowInfo& info = *windowHandle->getInfo();
1146
Prabir Pradhand65552b2021-10-07 11:23:50 -07001147 if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus)) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08001148 continue;
1149 }
1150 if (!info.isSpy()) {
1151 // The first touched non-spy window was found, so return the spy windows touched so far.
1152 return spyWindows;
1153 }
1154 spyWindows.push_back(windowHandle);
1155 }
1156 return spyWindows;
1157}
1158
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001159void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001160 const char* reason;
1161 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001162 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001163 if (DEBUG_INBOUND_EVENT_DETAILS) {
1164 ALOGD("Dropped event because policy consumed it.");
1165 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001166 reason = "inbound event was dropped because the policy consumed it";
1167 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001168 case DropReason::DISABLED:
1169 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001170 ALOGI("Dropped event because input dispatch is disabled.");
1171 }
1172 reason = "inbound event was dropped because input dispatch is disabled";
1173 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001174 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001175 ALOGI("Dropped event because of pending overdue app switch.");
1176 reason = "inbound event was dropped because of pending overdue app switch";
1177 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001178 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001179 ALOGI("Dropped event because the current application is not responding and the user "
1180 "has started interacting with a different application.");
1181 reason = "inbound event was dropped because the current application is not responding "
1182 "and the user has started interacting with a different application";
1183 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001184 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001185 ALOGI("Dropped event because it is stale.");
1186 reason = "inbound event was dropped because it is stale";
1187 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001188 case DropReason::NO_POINTER_CAPTURE:
1189 ALOGI("Dropped event because there is no window with Pointer Capture.");
1190 reason = "inbound event was dropped because there is no window with Pointer Capture";
1191 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001192 case DropReason::NOT_DROPPED: {
1193 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001194 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001195 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001196 }
1197
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001198 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001199 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001200 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1201 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001202 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001203 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001204 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001205 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1206 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001207 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1208 synthesizeCancelationEventsForAllConnectionsLocked(options);
1209 } else {
1210 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1211 synthesizeCancelationEventsForAllConnectionsLocked(options);
1212 }
1213 break;
1214 }
Chris Yef59a2f42020-10-16 12:55:26 -07001215 case EventEntry::Type::SENSOR: {
1216 break;
1217 }
arthurhungb89ccb02020-12-30 16:19:01 +08001218 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1219 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001220 break;
1221 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001222 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001223 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001224 case EventEntry::Type::CONFIGURATION_CHANGED:
1225 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001226 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001227 break;
1228 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001229 }
1230}
1231
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001232static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001233 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1234 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001235}
1236
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001237bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1238 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1239 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1240 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241}
1242
1243bool InputDispatcher::isAppSwitchPendingLocked() {
1244 return mAppSwitchDueTime != LONG_LONG_MAX;
1245}
1246
1247void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1248 mAppSwitchDueTime = LONG_LONG_MAX;
1249
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001250 if (DEBUG_APP_SWITCH) {
1251 if (handled) {
1252 ALOGD("App switch has arrived.");
1253 } else {
1254 ALOGD("App switch was abandoned.");
1255 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001256 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001257}
1258
Michael Wrightd02c5b62014-02-10 15:10:22 -08001259bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001260 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261}
1262
Prabir Pradhancef936d2021-07-21 16:17:52 +00001263bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001264 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001265 return false;
1266 }
1267
1268 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001269 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001270 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001271 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1272 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001273 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001274 return true;
1275}
1276
Prabir Pradhancef936d2021-07-21 16:17:52 +00001277void InputDispatcher::postCommandLocked(Command&& command) {
1278 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001279}
1280
1281void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001282 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001283 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001284 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001285 releaseInboundEventLocked(entry);
1286 }
1287 traceInboundQueueLengthLocked();
1288}
1289
1290void InputDispatcher::releasePendingEventLocked() {
1291 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001292 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001293 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001294 }
1295}
1296
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001297void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001298 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001299 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001300 if (DEBUG_DISPATCH_CYCLE) {
1301 ALOGD("Injected inbound event was dropped.");
1302 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001303 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304 }
1305 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001306 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001307 }
1308 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001309}
1310
1311void InputDispatcher::resetKeyRepeatLocked() {
1312 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001313 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001314 }
1315}
1316
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001317std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1318 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001319
Michael Wright2e732952014-09-24 13:26:59 -07001320 uint32_t policyFlags = entry->policyFlags &
1321 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001322
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001323 std::shared_ptr<KeyEntry> newEntry =
1324 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1325 entry->source, entry->displayId, policyFlags, entry->action,
1326 entry->flags, entry->keyCode, entry->scanCode,
1327 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001328
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001329 newEntry->syntheticRepeat = true;
1330 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001331 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001332 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001333}
1334
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001335bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001336 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001337 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1338 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1339 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001340
1341 // Reset key repeating in case a keyboard device was added or removed or something.
1342 resetKeyRepeatLocked();
1343
1344 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001345 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1346 scoped_unlock unlock(mLock);
1347 mPolicy->notifyConfigurationChanged(eventTime);
1348 };
1349 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001350 return true;
1351}
1352
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001353bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1354 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001355 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1356 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1357 entry.deviceId);
1358 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001359
liushenxiang42232912021-05-21 20:24:09 +08001360 // Reset key repeating in case a keyboard device was disabled or enabled.
1361 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1362 resetKeyRepeatLocked();
1363 }
1364
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001365 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001366 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001367 synthesizeCancelationEventsForAllConnectionsLocked(options);
1368 return true;
1369}
1370
Vishnu Nairad321cd2020-08-20 16:40:21 -07001371void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001372 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001373 if (mPendingEvent != nullptr) {
1374 // Move the pending event to the front of the queue. This will give the chance
1375 // for the pending event to get dispatched to the newly focused window
1376 mInboundQueue.push_front(mPendingEvent);
1377 mPendingEvent = nullptr;
1378 }
1379
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001380 std::unique_ptr<FocusEntry> focusEntry =
1381 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1382 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001383
1384 // This event should go to the front of the queue, but behind all other focus events
1385 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001386 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001387 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001388 [](const std::shared_ptr<EventEntry>& event) {
1389 return event->type == EventEntry::Type::FOCUS;
1390 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001391
1392 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001393 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001394}
1395
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001396void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001397 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001398 if (channel == nullptr) {
1399 return; // Window has gone away
1400 }
1401 InputTarget target;
1402 target.inputChannel = channel;
1403 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1404 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001405 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1406 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001407 std::string reason = std::string("reason=").append(entry->reason);
1408 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001409 dispatchEventLocked(currentTime, entry, {target});
1410}
1411
Prabir Pradhan99987712020-11-10 18:43:05 -08001412void InputDispatcher::dispatchPointerCaptureChangedLocked(
1413 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1414 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001415 dropReason = DropReason::NOT_DROPPED;
1416
Prabir Pradhan99987712020-11-10 18:43:05 -08001417 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001418 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001419
1420 if (entry->pointerCaptureRequest.enable) {
1421 // Enable Pointer Capture.
1422 if (haveWindowWithPointerCapture &&
1423 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1424 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1425 "to the window.");
1426 }
1427 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001428 // This can happen if a window requests capture and immediately releases capture.
1429 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001430 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001431 return;
1432 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001433 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1434 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1435 return;
1436 }
1437
Vishnu Nairc519ff72021-01-21 08:23:08 -08001438 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001439 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1440 mWindowTokenWithPointerCapture = token;
1441 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001442 // Disable Pointer Capture.
1443 // We do not check if the sequence number matches for requests to disable Pointer Capture
1444 // for two reasons:
1445 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1446 // to disable capture with the same sequence number: one generated by
1447 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1448 // Capture being disabled in InputReader.
1449 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1450 // actual Pointer Capture state that affects events being generated by input devices is
1451 // in InputReader.
1452 if (!haveWindowWithPointerCapture) {
1453 // Pointer capture was already forcefully disabled because of focus change.
1454 dropReason = DropReason::NOT_DROPPED;
1455 return;
1456 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001457 token = mWindowTokenWithPointerCapture;
1458 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001459 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001460 setPointerCaptureLocked(false);
1461 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001462 }
1463
1464 auto channel = getInputChannelLocked(token);
1465 if (channel == nullptr) {
1466 // Window has gone away, clean up Pointer Capture state.
1467 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001468 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001469 setPointerCaptureLocked(false);
1470 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001471 return;
1472 }
1473 InputTarget target;
1474 target.inputChannel = channel;
1475 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1476 entry->dispatchInProgress = true;
1477 dispatchEventLocked(currentTime, entry, {target});
1478
1479 dropReason = DropReason::NOT_DROPPED;
1480}
1481
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001482void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1483 const std::shared_ptr<TouchModeEntry>& entry) {
1484 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1485 getWindowHandlesLocked(mFocusedDisplayId);
1486 if (windowHandles.empty()) {
1487 return;
1488 }
1489 const std::vector<InputTarget> inputTargets =
1490 getInputTargetsFromWindowHandlesLocked(windowHandles);
1491 if (inputTargets.empty()) {
1492 return;
1493 }
1494 entry->dispatchInProgress = true;
1495 dispatchEventLocked(currentTime, entry, inputTargets);
1496}
1497
1498std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1499 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1500 std::vector<InputTarget> inputTargets;
1501 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1502 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1503 const sp<IBinder>& token = handle->getToken();
1504 if (token == nullptr) {
1505 continue;
1506 }
1507 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1508 if (channel == nullptr) {
1509 continue; // Window has gone away
1510 }
1511 InputTarget target;
1512 target.inputChannel = channel;
1513 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1514 inputTargets.push_back(target);
1515 }
1516 return inputTargets;
1517}
1518
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001519bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001520 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001521 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001522 if (!entry->dispatchInProgress) {
1523 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1524 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1525 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1526 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001527 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001528 // We have seen two identical key downs in a row which indicates that the device
1529 // driver is automatically generating key repeats itself. We take note of the
1530 // repeat here, but we disable our own next key repeat timer since it is clear that
1531 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001532 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1533 // Make sure we don't get key down from a different device. If a different
1534 // device Id has same key pressed down, the new device Id will replace the
1535 // current one to hold the key repeat with repeat count reset.
1536 // In the future when got a KEY_UP on the device id, drop it and do not
1537 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001538 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1539 resetKeyRepeatLocked();
1540 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1541 } else {
1542 // Not a repeat. Save key down state in case we do see a repeat later.
1543 resetKeyRepeatLocked();
1544 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1545 }
1546 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001547 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1548 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001549 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001550 if (DEBUG_INBOUND_EVENT_DETAILS) {
1551 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1552 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001553 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001554 resetKeyRepeatLocked();
1555 }
1556
1557 if (entry->repeatCount == 1) {
1558 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1559 } else {
1560 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1561 }
1562
1563 entry->dispatchInProgress = true;
1564
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001565 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001566 }
1567
1568 // Handle case where the policy asked us to try again later last time.
1569 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1570 if (currentTime < entry->interceptKeyWakeupTime) {
1571 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1572 *nextWakeupTime = entry->interceptKeyWakeupTime;
1573 }
1574 return false; // wait until next wakeup
1575 }
1576 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1577 entry->interceptKeyWakeupTime = 0;
1578 }
1579
1580 // Give the policy a chance to intercept the key.
1581 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1582 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001583 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001584 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001585
1586 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1587 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1588 };
1589 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001590 return false; // wait for the command to run
1591 } else {
1592 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1593 }
1594 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001595 if (*dropReason == DropReason::NOT_DROPPED) {
1596 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001597 }
1598 }
1599
1600 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001601 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001602 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001603 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1604 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001605 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 return true;
1607 }
1608
1609 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001610 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001611 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001612 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001613 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001614 return false;
1615 }
1616
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001617 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001618 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001619 return true;
1620 }
1621
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001622 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001623 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001624
1625 // Dispatch the key.
1626 dispatchEventLocked(currentTime, entry, inputTargets);
1627 return true;
1628}
1629
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001630void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001631 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1632 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1633 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1634 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1635 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1636 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1637 entry.metaState, entry.repeatCount, entry.downTime);
1638 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639}
1640
Prabir Pradhancef936d2021-07-21 16:17:52 +00001641void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1642 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001643 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001644 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1645 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1646 "source=0x%x, sensorType=%s",
1647 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001648 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001649 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001650 auto command = [this, entry]() REQUIRES(mLock) {
1651 scoped_unlock unlock(mLock);
1652
1653 if (entry->accuracyChanged) {
1654 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1655 }
1656 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1657 entry->hwTimestamp, entry->values);
1658 };
1659 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001660}
1661
1662bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001663 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1664 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001665 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001666 }
Chris Yef59a2f42020-10-16 12:55:26 -07001667 { // acquire lock
1668 std::scoped_lock _l(mLock);
1669
1670 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1671 std::shared_ptr<EventEntry> entry = *it;
1672 if (entry->type == EventEntry::Type::SENSOR) {
1673 it = mInboundQueue.erase(it);
1674 releaseInboundEventLocked(entry);
1675 }
1676 }
1677 }
1678 return true;
1679}
1680
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001681bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001682 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001683 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001684 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001685 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 entry->dispatchInProgress = true;
1687
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001688 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689 }
1690
1691 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001692 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001693 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001694 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1695 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001696 return true;
1697 }
1698
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001699 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001700
1701 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001702 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001703
1704 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001705 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001706 if (isPointerEvent) {
1707 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001708 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001709 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001710 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001711 } else {
1712 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001713 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001714 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001715 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001716 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001717 return false;
1718 }
1719
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001720 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001721 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001722 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1723 return true;
1724 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001725 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001726 CancelationOptions::Mode mode(isPointerEvent
1727 ? CancelationOptions::CANCEL_POINTER_EVENTS
1728 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1729 CancelationOptions options(mode, "input event injection failed");
1730 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001731 return true;
1732 }
1733
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001734 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001735 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736
1737 // Dispatch the motion.
1738 if (conflictingPointerActions) {
1739 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001740 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001741 synthesizeCancelationEventsForAllConnectionsLocked(options);
1742 }
1743 dispatchEventLocked(currentTime, entry, inputTargets);
1744 return true;
1745}
1746
chaviw98318de2021-05-19 16:45:23 -05001747void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001748 bool isExiting, const MotionEntry& motionEntry) {
1749 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1750 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1751 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1752 PointerCoords pointerCoords;
1753 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1754 pointerCoords.transform(windowHandle->getInfo()->transform);
1755
1756 std::unique_ptr<DragEntry> dragEntry =
1757 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1758 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1759 pointerCoords.getY());
1760
1761 enqueueInboundEventLocked(std::move(dragEntry));
1762}
1763
1764void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1765 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1766 if (channel == nullptr) {
1767 return; // Window has gone away
1768 }
1769 InputTarget target;
1770 target.inputChannel = channel;
1771 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1772 entry->dispatchInProgress = true;
1773 dispatchEventLocked(currentTime, entry, {target});
1774}
1775
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001776void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001777 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1778 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1779 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001780 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001781 "metaState=0x%x, buttonState=0x%x,"
1782 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1783 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001784 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1785 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1786 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001787
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001788 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1789 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1790 "x=%f, y=%f, pressure=%f, size=%f, "
1791 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1792 "orientation=%f",
1793 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1794 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1795 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1796 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1797 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1798 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1799 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1800 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1801 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1802 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1803 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001804 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001805}
1806
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001807void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1808 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001809 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001810 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001811 if (DEBUG_DISPATCH_CYCLE) {
1812 ALOGD("dispatchEventToCurrentInputTargets");
1813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001814
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001815 updateInteractionTokensLocked(*eventEntry, inputTargets);
1816
Michael Wrightd02c5b62014-02-10 15:10:22 -08001817 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1818
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001819 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001820
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001821 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001822 sp<Connection> connection =
1823 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001824 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001825 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001826 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001827 if (DEBUG_FOCUS) {
1828 ALOGD("Dropping event delivery to target with channel '%s' because it "
1829 "is no longer registered with the input dispatcher.",
1830 inputTarget.inputChannel->getName().c_str());
1831 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001832 }
1833 }
1834}
1835
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001836void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1837 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1838 // If the policy decides to close the app, we will get a channel removal event via
1839 // unregisterInputChannel, and will clean up the connection that way. We are already not
1840 // sending new pointers to the connection when it blocked, but focused events will continue to
1841 // pile up.
1842 ALOGW("Canceling events for %s because it is unresponsive",
1843 connection->inputChannel->getName().c_str());
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08001844 if (connection->status == Connection::Status::NORMAL) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001845 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1846 "application not responding");
1847 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001848 }
1849}
1850
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001851void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001852 if (DEBUG_FOCUS) {
1853 ALOGD("Resetting ANR timeouts.");
1854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001855
1856 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001857 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001858 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001859}
1860
Tiger Huang721e26f2018-07-24 22:26:19 +08001861/**
1862 * Get the display id that the given event should go to. If this event specifies a valid display id,
1863 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1864 * Focused display is the display that the user most recently interacted with.
1865 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001866int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001867 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001868 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001869 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001870 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1871 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001872 break;
1873 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001874 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001875 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1876 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001877 break;
1878 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001879 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001880 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001881 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001882 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001883 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001884 case EventEntry::Type::SENSOR:
1885 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001886 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001887 return ADISPLAY_ID_NONE;
1888 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001889 }
1890 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1891}
1892
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001893bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1894 const char* focusedWindowName) {
1895 if (mAnrTracker.empty()) {
1896 // already processed all events that we waited for
1897 mKeyIsWaitingForEventsTimeout = std::nullopt;
1898 return false;
1899 }
1900
1901 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1902 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001903 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001904 mKeyIsWaitingForEventsTimeout = currentTime +
1905 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1906 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001907 return true;
1908 }
1909
1910 // We still have pending events, and already started the timer
1911 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1912 return true; // Still waiting
1913 }
1914
1915 // Waited too long, and some connection still hasn't processed all motions
1916 // Just send the key to the focused window
1917 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1918 focusedWindowName);
1919 mKeyIsWaitingForEventsTimeout = std::nullopt;
1920 return false;
1921}
1922
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001923InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1924 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1925 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001926 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001927
Tiger Huang721e26f2018-07-24 22:26:19 +08001928 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001929 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001930 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001931 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1932
Michael Wrightd02c5b62014-02-10 15:10:22 -08001933 // If there is no currently focused window and no focused application
1934 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001935 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1936 ALOGI("Dropping %s event because there is no focused window or focused application in "
1937 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001938 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001939 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001940 }
1941
Vishnu Nair062a8672021-09-03 16:07:44 -07001942 // Drop key events if requested by input feature
1943 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1944 return InputEventInjectionResult::FAILED;
1945 }
1946
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001947 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1948 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1949 // start interacting with another application via touch (app switch). This code can be removed
1950 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1951 // an app is expected to have a focused window.
1952 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1953 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1954 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001955 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1956 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1957 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001958 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001959 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001960 ALOGW("Waiting because no window has focus but %s may eventually add a "
1961 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001962 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001963 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001964 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001965 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1966 // Already raised ANR. Drop the event
1967 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001968 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001969 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001970 } else {
1971 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001972 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001973 }
1974 }
1975
1976 // we have a valid, non-null focused window
1977 resetNoFocusedWindowTimeoutLocked();
1978
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001980 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001981 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 }
1983
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08001984 if (focusedWindowHandle->getInfo()->inputConfig.test(
1985 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001986 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001987 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001988 }
1989
1990 // If the event is a key event, then we must wait for all previous events to
1991 // complete before delivering it because previous events may have the
1992 // side-effect of transferring focus to a different window and we want to
1993 // ensure that the following keys are sent to the new window.
1994 //
1995 // Suppose the user touches a button in a window then immediately presses "A".
1996 // If the button causes a pop-up window to appear then we want to ensure that
1997 // the "A" key is delivered to the new pop-up window. This is because users
1998 // often anticipate pending UI changes when typing on a keyboard.
1999 // To obtain this behavior, we must serialize key events with respect to all
2000 // prior input events.
2001 if (entry.type == EventEntry::Type::KEY) {
2002 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2003 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002004 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002005 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002006 }
2007
2008 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08002009 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002010 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
2011 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002012
2013 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002014 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002015}
2016
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002017/**
2018 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2019 * that are currently unresponsive.
2020 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002021std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2022 const std::vector<Monitor>& monitors) const {
2023 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002024 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002025 [this](const Monitor& monitor) REQUIRES(mLock) {
2026 sp<Connection> connection =
2027 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002028 if (connection == nullptr) {
2029 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002030 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002031 return false;
2032 }
2033 if (!connection->responsive) {
2034 ALOGW("Unresponsive monitor %s will not get the new gesture",
2035 connection->inputChannel->getName().c_str());
2036 return false;
2037 }
2038 return true;
2039 });
2040 return responsiveMonitors;
2041}
2042
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002043InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
2044 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
2045 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002046 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047 enum InjectionPermission {
2048 INJECTION_PERMISSION_UNKNOWN,
2049 INJECTION_PERMISSION_GRANTED,
2050 INJECTION_PERMISSION_DENIED
2051 };
2052
Michael Wrightd02c5b62014-02-10 15:10:22 -08002053 // For security reasons, we defer updating the touch state until we are sure that
2054 // event injection will be allowed.
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002055 const int32_t displayId = entry.displayId;
2056 const int32_t action = entry.action;
2057 const int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058
2059 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002060 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05002062 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
2063 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002064
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002065 // Copy current touch state into tempTouchState.
2066 // This state will be used to update mTouchStatesByDisplay at the end of this function.
2067 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002068 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002069 TouchState tempTouchState;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002070 if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2071 oldState = &(it->second);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08002072 tempTouchState = *oldState;
Jeff Brownf086ddb2014-02-11 14:28:48 -08002073 }
2074
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002075 bool isSplit = tempTouchState.split;
2076 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2077 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2078 tempTouchState.displayId != displayId);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002079
2080 const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2081 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2082 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2083 const bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2084 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002085 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002086 bool wrongDevice = false;
2087 if (newGesture) {
2088 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002089 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002090 ALOGI("Dropping event because a pointer for a different device is already down "
2091 "in display %" PRId32,
2092 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002093 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002094 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002095 switchedDevice = false;
2096 wrongDevice = true;
2097 goto Failed;
2098 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002099 tempTouchState.reset();
2100 tempTouchState.down = down;
2101 tempTouchState.deviceId = entry.deviceId;
2102 tempTouchState.source = entry.source;
2103 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002104 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002105 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002106 ALOGI("Dropping move event because a pointer for a different device is already active "
2107 "in display %" PRId32,
2108 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002109 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002110 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002111 switchedDevice = false;
2112 wrongDevice = true;
2113 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002114 }
2115
2116 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2117 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2118
Garfield Tan00f511d2019-06-12 16:55:40 -07002119 int32_t x;
2120 int32_t y;
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002121 const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002122 // Always dispatch mouse events to cursor position.
2123 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002124 x = int32_t(entry.xCursorPosition);
2125 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002126 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002127 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2128 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002129 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002130 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Prabir Pradhand65552b2021-10-07 11:23:50 -07002131 const bool isStylus = isPointerFromStylus(entry, pointerIndex);
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002132 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
Prabir Pradhand65552b2021-10-07 11:23:50 -07002133 isStylus, isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002134
Michael Wrightd02c5b62014-02-10 15:10:22 -08002135 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002136 if (newTouchedWindowHandle == nullptr) {
Arthur Hungb3307ee2021-10-14 10:57:37 +00002137 ALOGD("No new touched window at (%" PRId32 ", %" PRId32 ") in display %" PRId32, x, y,
2138 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002140 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002141 }
2142
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002143 // Figure out whether splitting will be allowed for this window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002144 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002145 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2146 // New window supports splitting, but we should never split mouse events.
2147 isSplit = !isFromMouse;
2148 } else if (isSplit) {
2149 // New window does not support splitting but we have already split events.
2150 // Ignore the new window.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002151 newTouchedWindowHandle = nullptr;
2152 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002153 } else {
2154 // No window is touched, so set split to true. This will allow the next pointer down to
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002155 // be delivered to a new window which supports split touch. Pointers from a mouse device
2156 // should never be split.
2157 tempTouchState.split = isSplit = !isFromMouse;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002158 }
2159
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002160 // Update hover state.
Michael Wright3dd60e22019-03-27 22:06:44 +00002161 if (newTouchedWindowHandle != nullptr) {
Garfield Tandf26e862020-07-01 20:18:19 -07002162 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2163 newHoverWindowHandle = nullptr;
2164 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002165 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002166 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002167 }
2168
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002169 std::vector<sp<WindowInfoHandle>> newTouchedWindows =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002170 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002171 if (newTouchedWindowHandle != nullptr) {
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002172 // Process the foreground window first so that it is the first to receive the event.
2173 newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002174 }
2175
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002176 if (newTouchedWindows.empty()) {
2177 ALOGI("Dropping event because there is no touchable window at (%d, %d) on display %d.",
2178 x, y, displayId);
2179 injectionResult = InputEventInjectionResult::FAILED;
2180 goto Failed;
2181 }
2182
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002183 for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
2184 const WindowInfo& info = *windowHandle->getInfo();
2185
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002186 if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002187 ALOGI("Not sending touch event to %s because it is paused",
2188 windowHandle->getName().c_str());
2189 continue;
2190 }
2191
2192 // Ensure the window has a connection and the connection is responsive
2193 const bool isResponsive = hasResponsiveConnectionLocked(*windowHandle);
2194 if (!isResponsive) {
2195 ALOGW("Not sending touch gesture to %s because it is not responsive",
2196 windowHandle->getName().c_str());
2197 continue;
2198 }
2199
2200 // Drop events that can't be trusted due to occlusion
2201 if (mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2202 TouchOcclusionInfo occlusionInfo =
2203 computeTouchOcclusionInfoLocked(windowHandle, x, y);
2204 if (!isTouchTrustedLocked(occlusionInfo)) {
2205 if (DEBUG_TOUCH_OCCLUSION) {
2206 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2207 for (const auto& log : occlusionInfo.debugInfo) {
2208 ALOGD("%s", log.c_str());
2209 }
2210 }
2211 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
2212 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2213 ALOGW("Dropping untrusted touch event due to %s/%d",
2214 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2215 continue;
2216 }
2217 }
2218 }
2219
2220 // Drop touch events if requested by input feature
2221 if (shouldDropInput(entry, windowHandle)) {
2222 continue;
2223 }
2224
2225 // Set target flags.
2226 int32_t targetFlags = InputTarget::FLAG_DISPATCH_AS_IS;
2227
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002228 if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2229 // There should only be one touched window that can be "foreground" for the pointer.
Prabir Pradhan07e05b62021-11-19 03:57:24 -08002230 targetFlags |= InputTarget::FLAG_FOREGROUND;
2231 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002232
2233 if (isSplit) {
2234 targetFlags |= InputTarget::FLAG_SPLIT;
2235 }
2236 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
2237 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2238 } else if (isWindowObscuredLocked(windowHandle)) {
2239 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2240 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002241
2242 // Update the temporary touch state.
2243 BitSet32 pointerIds;
2244 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002245 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002246 pointerIds.markBit(pointerId);
2247 }
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002248
2249 tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 } else {
2252 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2253
2254 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002255 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002256 if (DEBUG_FOCUS) {
2257 ALOGD("Dropping event because the pointer is not down or we previously "
2258 "dropped the pointer down event in display %" PRId32,
2259 displayId);
2260 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002261 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002262 goto Failed;
2263 }
2264
arthurhung6d4bed92021-03-17 11:59:33 +08002265 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002266
Michael Wrightd02c5b62014-02-10 15:10:22 -08002267 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002268 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002269 tempTouchState.isSlippery()) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002270 const int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2271 const int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002272
Prabir Pradhand65552b2021-10-07 11:23:50 -07002273 const bool isStylus = isPointerFromStylus(entry, 0 /*pointerIndex*/);
chaviw98318de2021-05-19 16:45:23 -05002274 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002275 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhand65552b2021-10-07 11:23:50 -07002276 newTouchedWindowHandle =
2277 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState, isStylus);
Vishnu Nair062a8672021-09-03 16:07:44 -07002278
2279 // Drop touch events if requested by input feature
2280 if (newTouchedWindowHandle != nullptr &&
2281 shouldDropInput(entry, newTouchedWindowHandle)) {
2282 newTouchedWindowHandle = nullptr;
2283 }
2284
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002285 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2286 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002287 if (DEBUG_FOCUS) {
2288 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2289 oldTouchedWindowHandle->getName().c_str(),
2290 newTouchedWindowHandle->getName().c_str(), displayId);
2291 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002292 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002293 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2294 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2295 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002296
2297 // Make a slippery entrance into the new window.
2298 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Prabir Pradhan713bb3e2021-12-20 02:07:40 -08002299 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002300 }
2301
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002302 int32_t targetFlags = InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
2303 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
2304 targetFlags |= InputTarget::FLAG_FOREGROUND;
2305 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002306 if (isSplit) {
2307 targetFlags |= InputTarget::FLAG_SPLIT;
2308 }
2309 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2310 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002311 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2312 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002313 }
2314
2315 BitSet32 pointerIds;
2316 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002317 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002318 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002319 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002320 }
2321 }
2322 }
2323
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002324 // Update dispatching for hover enter and exit.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002325 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Prabir Pradhan3f90d312021-11-19 03:57:24 -08002326 // Let the previous window know that the hover sequence is over, unless we already did
2327 // it when dispatching it as is to newTouchedWindowHandle.
Garfield Tandf26e862020-07-01 20:18:19 -07002328 if (mLastHoverWindowHandle != nullptr &&
2329 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2330 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002331 if (DEBUG_HOVER) {
2332 ALOGD("Sending hover exit event to window %s.",
2333 mLastHoverWindowHandle->getName().c_str());
2334 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002335 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2336 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337 }
2338
Garfield Tandf26e862020-07-01 20:18:19 -07002339 // Let the new window know that the hover sequence is starting, unless we already did it
2340 // when dispatching it as is to newTouchedWindowHandle.
2341 if (newHoverWindowHandle != nullptr &&
2342 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2343 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002344 if (DEBUG_HOVER) {
2345 ALOGD("Sending hover enter event to window %s.",
2346 newHoverWindowHandle->getName().c_str());
2347 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002348 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2349 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2350 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002351 }
2352 }
2353
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002354 // Ensure that we have at least one foreground window or at least one window that cannot be a
2355 // foreground target. If we only have windows that are not receiving foreground touches (e.g. we
2356 // only have windows getting ACTION_OUTSIDE), then drop the event, because there is no window
2357 // that is actually receiving the entire gesture.
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002358 if (std::none_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2359 [](const TouchedWindow& touchedWindow) {
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00002360 return !canReceiveForegroundTouches(
2361 *touchedWindow.windowHandle->getInfo()) ||
2362 (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0;
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002363 })) {
2364 ALOGI("Dropping event because there is no touched window on display %d to receive it.",
2365 displayId);
2366 injectionResult = InputEventInjectionResult::FAILED;
2367 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002368 }
2369
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002370 // Check permission to inject into all touched foreground windows.
2371 if (std::any_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
2372 [this, &entry](const TouchedWindow& touchedWindow) {
2373 return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 &&
2374 !checkInjectionPermission(touchedWindow.windowHandle,
2375 entry.injectionState);
2376 })) {
2377 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
2378 injectionPermission = INJECTION_PERMISSION_DENIED;
2379 goto Failed;
2380 }
2381 // Permission granted to inject into all touched foreground windows.
2382 injectionPermission = INJECTION_PERMISSION_GRANTED;
2383
Michael Wrightd02c5b62014-02-10 15:10:22 -08002384 // Check whether windows listening for outside touches are owned by the same UID. If it is
2385 // set the policy flag that we will not reveal coordinate information to this window.
2386 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002387 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002388 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002389 if (foregroundWindowHandle) {
2390 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002391 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002392 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002393 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2394 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2395 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002396 InputTarget::FLAG_ZERO_COORDS,
2397 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002398 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002399 }
2400 }
2401 }
2402 }
2403
Michael Wrightd02c5b62014-02-10 15:10:22 -08002404 // If this is the first pointer going down and the touched window has a wallpaper
2405 // then also add the touched wallpaper windows so they are locked in for the duration
2406 // of the touch gesture.
2407 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2408 // engine only supports touch events. We would need to add a mechanism similar
2409 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2410 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002411 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002412 tempTouchState.getFirstForegroundWindowHandle();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002413 if (foregroundWindowHandle &&
2414 foregroundWindowHandle->getInfo()->inputConfig.test(
2415 WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
chaviw98318de2021-05-19 16:45:23 -05002416 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002417 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002418 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2419 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002420 if (info->displayId == displayId &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002421 windowHandle->getInfo()->inputConfig.test(
2422 WindowInfo::InputConfig::IS_WALLPAPER)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002423 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002424 .addOrUpdateWindow(windowHandle,
2425 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2426 InputTarget::
2427 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2428 InputTarget::FLAG_DISPATCH_AS_IS,
2429 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002430 }
2431 }
2432 }
2433 }
2434
2435 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002436 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002437
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002438 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002439 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002440 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002441 }
2442
2443 // Drop the outside or hover touch windows since we will not care about them
2444 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002445 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002446
2447Failed:
2448 // Check injection permission once and for all.
2449 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002450 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002451 injectionPermission = INJECTION_PERMISSION_GRANTED;
2452 } else {
2453 injectionPermission = INJECTION_PERMISSION_DENIED;
2454 }
2455 }
2456
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002457 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2458 return injectionResult;
2459 }
2460
Michael Wrightd02c5b62014-02-10 15:10:22 -08002461 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002462 if (!wrongDevice) {
2463 if (switchedDevice) {
2464 if (DEBUG_FOCUS) {
2465 ALOGD("Conflicting pointer actions: Switched to a different device.");
2466 }
2467 *outConflictingPointerActions = true;
2468 }
2469
2470 if (isHoverAction) {
2471 // Started hovering, therefore no longer down.
2472 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002473 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002474 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2475 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002476 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002477 *outConflictingPointerActions = true;
2478 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002479 tempTouchState.reset();
2480 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2481 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2482 tempTouchState.deviceId = entry.deviceId;
2483 tempTouchState.source = entry.source;
2484 tempTouchState.displayId = displayId;
2485 }
2486 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2487 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2488 // All pointers up or canceled.
2489 tempTouchState.reset();
2490 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2491 // First pointer went down.
2492 if (oldState && oldState->down) {
2493 if (DEBUG_FOCUS) {
2494 ALOGD("Conflicting pointer actions: Down received while already down.");
2495 }
2496 *outConflictingPointerActions = true;
2497 }
2498 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2499 // One pointer went up.
2500 if (isSplit) {
2501 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2502 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002503
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002504 for (size_t i = 0; i < tempTouchState.windows.size();) {
2505 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2506 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2507 touchedWindow.pointerIds.clearBit(pointerId);
2508 if (touchedWindow.pointerIds.isEmpty()) {
2509 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2510 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002511 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002512 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002513 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002514 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002515 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002516 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002517
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002518 // Save changes unless the action was scroll in which case the temporary touch
2519 // state was only valid for this one action.
2520 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2521 if (tempTouchState.displayId >= 0) {
2522 mTouchStatesByDisplay[displayId] = tempTouchState;
2523 } else {
2524 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002525 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002526 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002527
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002528 // Update hover state.
2529 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530 }
2531
Michael Wrightd02c5b62014-02-10 15:10:22 -08002532 return injectionResult;
2533}
2534
arthurhung6d4bed92021-03-17 11:59:33 +08002535void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07002536 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2537 // have an explicit reason to support it.
2538 constexpr bool isStylus = false;
2539
chaviw98318de2021-05-19 16:45:23 -05002540 const sp<WindowInfoHandle> dropWindow =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002541 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002542 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002543 if (dropWindow) {
2544 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002545 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002546 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002547 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002548 }
2549 mDragState.reset();
2550}
2551
2552void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2553 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002554 return;
2555 }
2556
arthurhung6d4bed92021-03-17 11:59:33 +08002557 if (!mDragState->isStartDrag) {
2558 mDragState->isStartDrag = true;
2559 mDragState->isStylusButtonDownAtStart =
2560 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2561 }
2562
arthurhungb89ccb02020-12-30 16:19:01 +08002563 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2564 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2565 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2566 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002567 // Handle the special case : stylus button no longer pressed.
2568 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2569 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2570 finishDragAndDrop(entry.displayId, x, y);
2571 return;
2572 }
2573
Prabir Pradhand65552b2021-10-07 11:23:50 -07002574 // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until
2575 // we have an explicit reason to support it.
2576 constexpr bool isStylus = false;
2577
chaviw98318de2021-05-19 16:45:23 -05002578 const sp<WindowInfoHandle> hoverWindowHandle =
Prabir Pradhand65552b2021-10-07 11:23:50 -07002579 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/, isStylus,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002580 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002581 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002582 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2583 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2584 if (mDragState->dragHoverWindowHandle != nullptr) {
2585 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2586 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002587 }
arthurhung6d4bed92021-03-17 11:59:33 +08002588 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002589 }
2590 // enqueue drag location if needed.
2591 if (hoverWindowHandle != nullptr) {
2592 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2593 }
arthurhung6d4bed92021-03-17 11:59:33 +08002594 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2595 finishDragAndDrop(entry.displayId, x, y);
2596 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002597 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002598 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002599 }
2600}
2601
chaviw98318de2021-05-19 16:45:23 -05002602void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002603 int32_t targetFlags, BitSet32 pointerIds,
2604 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002605 std::vector<InputTarget>::iterator it =
2606 std::find_if(inputTargets.begin(), inputTargets.end(),
2607 [&windowHandle](const InputTarget& inputTarget) {
2608 return inputTarget.inputChannel->getConnectionToken() ==
2609 windowHandle->getToken();
2610 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002611
chaviw98318de2021-05-19 16:45:23 -05002612 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002613
2614 if (it == inputTargets.end()) {
2615 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002616 std::shared_ptr<InputChannel> inputChannel =
2617 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002618 if (inputChannel == nullptr) {
2619 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2620 return;
2621 }
2622 inputTarget.inputChannel = inputChannel;
2623 inputTarget.flags = targetFlags;
2624 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002625 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2626 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002627 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002628 } else {
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00002629 ALOGE("DisplayInfo not found for window on display: %d", windowInfo->displayId);
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002630 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002631 inputTargets.push_back(inputTarget);
2632 it = inputTargets.end() - 1;
2633 }
2634
2635 ALOG_ASSERT(it->flags == targetFlags);
2636 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2637
chaviw1ff3d1e2020-07-01 15:53:47 -07002638 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002639}
2640
Michael Wright3dd60e22019-03-27 22:06:44 +00002641void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002642 int32_t displayId) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002643 auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
2644 if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
Michael Wright3dd60e22019-03-27 22:06:44 +00002645
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002646 for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
2647 InputTarget target;
2648 target.inputChannel = monitor.inputChannel;
2649 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2650 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
2651 target.displayTransform = it->second.transform;
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002652 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08002653 target.setDefaultPointerTransform(target.displayTransform);
2654 inputTargets.push_back(target);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002655 }
2656}
2657
chaviw98318de2021-05-19 16:45:23 -05002658bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002659 const InjectionState* injectionState) {
2660 if (injectionState &&
2661 (windowHandle == nullptr ||
2662 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2663 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002664 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002665 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002666 "owned by uid %d",
2667 injectionState->injectorPid, injectionState->injectorUid,
2668 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002669 } else {
2670 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002671 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002672 }
2673 return false;
2674 }
2675 return true;
2676}
2677
Robert Carrc9bf1d32020-04-13 17:21:08 -07002678/**
2679 * Indicate whether one window handle should be considered as obscuring
2680 * another window handle. We only check a few preconditions. Actually
2681 * checking the bounds is left to the caller.
2682 */
chaviw98318de2021-05-19 16:45:23 -05002683static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2684 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002685 // Compare by token so cloned layers aren't counted
2686 if (haveSameToken(windowHandle, otherHandle)) {
2687 return false;
2688 }
2689 auto info = windowHandle->getInfo();
2690 auto otherInfo = otherHandle->getInfo();
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002691 if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002692 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002693 } else if (otherInfo->alpha == 0 &&
2694 otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002695 // Those act as if they were invisible, so we don't need to flag them.
2696 // We do want to potentially flag touchable windows even if they have 0
2697 // opacity, since they can consume touches and alter the effects of the
2698 // user interaction (eg. apps that rely on
2699 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2700 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2701 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002702 } else if (info->ownerUid == otherInfo->ownerUid) {
2703 // If ownerUid is the same we don't generate occlusion events as there
2704 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002705 return false;
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002706 } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002707 return false;
2708 } else if (otherInfo->displayId != info->displayId) {
2709 return false;
2710 }
2711 return true;
2712}
2713
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002714/**
2715 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2716 * untrusted, one should check:
2717 *
2718 * 1. If result.hasBlockingOcclusion is true.
2719 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2720 * BLOCK_UNTRUSTED.
2721 *
2722 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2723 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2724 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2725 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2726 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2727 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2728 *
2729 * If neither of those is true, then it means the touch can be allowed.
2730 */
2731InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002732 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2733 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002734 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002735 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002736 TouchOcclusionInfo info;
2737 info.hasBlockingOcclusion = false;
2738 info.obscuringOpacity = 0;
2739 info.obscuringUid = -1;
2740 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002741 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002742 if (windowHandle == otherHandle) {
2743 break; // All future windows are below us. Exit early.
2744 }
chaviw98318de2021-05-19 16:45:23 -05002745 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002746 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2747 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002748 if (DEBUG_TOUCH_OCCLUSION) {
2749 info.debugInfo.push_back(
2750 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2751 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002752 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2753 // we perform the checks below to see if the touch can be propagated or not based on the
2754 // window's touch occlusion mode
2755 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2756 info.hasBlockingOcclusion = true;
2757 info.obscuringUid = otherInfo->ownerUid;
2758 info.obscuringPackage = otherInfo->packageName;
2759 break;
2760 }
2761 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2762 uint32_t uid = otherInfo->ownerUid;
2763 float opacity =
2764 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2765 // Given windows A and B:
2766 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2767 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2768 opacityByUid[uid] = opacity;
2769 if (opacity > info.obscuringOpacity) {
2770 info.obscuringOpacity = opacity;
2771 info.obscuringUid = uid;
2772 info.obscuringPackage = otherInfo->packageName;
2773 }
2774 }
2775 }
2776 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002777 if (DEBUG_TOUCH_OCCLUSION) {
2778 info.debugInfo.push_back(
2779 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2780 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002781 return info;
2782}
2783
chaviw98318de2021-05-19 16:45:23 -05002784std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002785 bool isTouchedWindow) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002786 return StringPrintf(INDENT2 "* %spackage=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2787 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2788 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
2789 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08002790 isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
2791 info->ownerUid, info->id, toString(info->touchOcclusionMode).c_str(),
2792 info->alpha, info->frameLeft, info->frameTop, info->frameRight,
2793 info->frameBottom, dumpRegion(info->touchableRegion).c_str(),
2794 info->name.c_str(), info->inputConfig.string().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002795 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002796 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002797}
2798
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002799bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2800 if (occlusionInfo.hasBlockingOcclusion) {
2801 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2802 occlusionInfo.obscuringUid);
2803 return false;
2804 }
2805 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2806 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2807 "%.2f, maximum allowed = %.2f)",
2808 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2809 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2810 return false;
2811 }
2812 return true;
2813}
2814
chaviw98318de2021-05-19 16:45:23 -05002815bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002816 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002817 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002818 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2819 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002820 if (windowHandle == otherHandle) {
2821 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002822 }
chaviw98318de2021-05-19 16:45:23 -05002823 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002824 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002825 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002826 return true;
2827 }
2828 }
2829 return false;
2830}
2831
chaviw98318de2021-05-19 16:45:23 -05002832bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002833 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002834 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2835 const WindowInfo* windowInfo = windowHandle->getInfo();
2836 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002837 if (windowHandle == otherHandle) {
2838 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002839 }
chaviw98318de2021-05-19 16:45:23 -05002840 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002841 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002842 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002843 return true;
2844 }
2845 }
2846 return false;
2847}
2848
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002849std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002850 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002851 if (applicationHandle != nullptr) {
2852 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002853 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002854 } else {
2855 return applicationHandle->getName();
2856 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002857 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002858 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002860 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861 }
2862}
2863
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002864void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002865 if (!isUserActivityEvent(eventEntry)) {
2866 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002867 return;
2868 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002869 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002870 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002871 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002872 const WindowInfo* info = focusedWindowHandle->getInfo();
Prabir Pradhan51e7db02022-02-07 06:02:57 -08002873 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002874 if (DEBUG_DISPATCH_CYCLE) {
2875 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2876 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002877 return;
2878 }
2879 }
2880
2881 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002882 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002883 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002884 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2885 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002886 return;
2887 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002888
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002889 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002890 eventType = USER_ACTIVITY_EVENT_TOUCH;
2891 }
2892 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002893 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002894 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002895 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2896 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002897 return;
2898 }
2899 eventType = USER_ACTIVITY_EVENT_BUTTON;
2900 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002901 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002902 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002903 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002904 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002905 break;
2906 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002907 }
2908
Prabir Pradhancef936d2021-07-21 16:17:52 +00002909 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2910 REQUIRES(mLock) {
2911 scoped_unlock unlock(mLock);
2912 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2913 };
2914 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002915}
2916
2917void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002919 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002920 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002921 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002922 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002923 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002924 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002925 ATRACE_NAME(message.c_str());
2926 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002927 if (DEBUG_DISPATCH_CYCLE) {
2928 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2929 "globalScaleFactor=%f, pointerIds=0x%x %s",
2930 connection->getInputChannelName().c_str(), inputTarget.flags,
2931 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2932 inputTarget.getPointerInfoString().c_str());
2933 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934
2935 // Skip this event if the connection status is not normal.
2936 // We don't want to enqueue additional outbound events if the connection is broken.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002937 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002938 if (DEBUG_DISPATCH_CYCLE) {
2939 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08002940 connection->getInputChannelName().c_str(),
2941 ftl::enum_string(connection->status).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002942 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002943 return;
2944 }
2945
2946 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002947 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2948 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2949 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002950 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002951
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002952 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002953 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002954 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002955 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956 if (!splitMotionEntry) {
2957 return; // split event was dropped
2958 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00002959 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
2960 std::string reason = std::string("reason=pointer cancel on split window");
2961 android_log_event_list(LOGTAG_INPUT_CANCEL)
2962 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
2963 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002964 if (DEBUG_FOCUS) {
2965 ALOGD("channel '%s' ~ Split motion event.",
2966 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002967 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002968 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002969 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2970 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002971 return;
2972 }
2973 }
2974
2975 // Not splitting. Enqueue dispatch entries for the event as is.
2976 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2977}
2978
2979void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002980 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002981 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002982 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002983 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002984 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002985 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002986 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002987 ATRACE_NAME(message.c_str());
2988 }
2989
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002990 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002991
2992 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002993 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002994 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002995 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002996 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002997 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002998 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002999 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003000 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07003001 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003002 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07003003 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003004 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003005
3006 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003007 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003008 startDispatchCycleLocked(currentTime, connection);
3009 }
3010}
3011
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003012void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003013 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003014 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003015 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003016 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003017 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
3018 connection->getInputChannelName().c_str(),
3019 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003020 ATRACE_NAME(message.c_str());
3021 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003022 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003023 if (!(inputTargetFlags & dispatchMode)) {
3024 return;
3025 }
3026 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
3027
3028 // This is a new event.
3029 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003030 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003031 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003032
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003033 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3034 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003035 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003036 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003037 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003038 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003039 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003040 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003041 dispatchEntry->resolvedAction = keyEntry.action;
3042 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003043
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003044 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
3045 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003046 if (DEBUG_DISPATCH_CYCLE) {
3047 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
3048 "event",
3049 connection->getInputChannelName().c_str());
3050 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003051 return; // skip the inconsistent event
3052 }
3053 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003054 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003055
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003056 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003057 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003058 // Assign a default value to dispatchEntry that will never be generated by InputReader,
3059 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
3060 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
3061 static_cast<int32_t>(IdGenerator::Source::OTHER);
3062 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003063 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3064 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
3065 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
3066 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3067 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
3068 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3069 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
3070 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3071 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
3072 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3073 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003074 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003075 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003076 }
3077 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003078 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3079 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003080 if (DEBUG_DISPATCH_CYCLE) {
3081 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
3082 "enter event",
3083 connection->getInputChannelName().c_str());
3084 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003085 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
3086 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003087 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3088 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003089
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003090 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003091 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3092 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3093 }
3094 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3095 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3096 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003097
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003098 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3099 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003100 if (DEBUG_DISPATCH_CYCLE) {
3101 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3102 "event",
3103 connection->getInputChannelName().c_str());
3104 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003105 return; // skip the inconsistent event
3106 }
3107
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003108 dispatchEntry->resolvedEventId =
3109 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3110 ? mIdGenerator.nextId()
3111 : motionEntry.id;
3112 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3113 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3114 ") to MotionEvent(id=0x%" PRIx32 ").",
3115 motionEntry.id, dispatchEntry->resolvedEventId);
3116 ATRACE_NAME(message.c_str());
3117 }
3118
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003119 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3120 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3121 // Skip reporting pointer down outside focus to the policy.
3122 break;
3123 }
3124
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003125 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003126 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003127
3128 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003129 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003130 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003131 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003132 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3133 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003134 break;
3135 }
Chris Yef59a2f42020-10-16 12:55:26 -07003136 case EventEntry::Type::SENSOR: {
3137 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3138 break;
3139 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003140 case EventEntry::Type::CONFIGURATION_CHANGED:
3141 case EventEntry::Type::DEVICE_RESET: {
3142 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003143 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003144 break;
3145 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003146 }
3147
3148 // Remember that we are waiting for this dispatch to complete.
3149 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003150 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003151 }
3152
3153 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003154 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003155 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003156}
3157
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003158/**
3159 * This function is purely for debugging. It helps us understand where the user interaction
3160 * was taking place. For example, if user is touching launcher, we will see a log that user
3161 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3162 * We will see both launcher and wallpaper in that list.
3163 * Once the interaction with a particular set of connections starts, no new logs will be printed
3164 * until the set of interacted connections changes.
3165 *
3166 * The following items are skipped, to reduce the logspam:
3167 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3168 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3169 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3170 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3171 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003172 */
3173void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3174 const std::vector<InputTarget>& targets) {
3175 // Skip ACTION_UP events, and all events other than keys and motions
3176 if (entry.type == EventEntry::Type::KEY) {
3177 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3178 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3179 return;
3180 }
3181 } else if (entry.type == EventEntry::Type::MOTION) {
3182 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3183 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3184 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3185 return;
3186 }
3187 } else {
3188 return; // Not a key or a motion
3189 }
3190
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003191 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003192 std::vector<sp<Connection>> newConnections;
3193 for (const InputTarget& target : targets) {
3194 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3195 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3196 continue; // Skip windows that receive ACTION_OUTSIDE
3197 }
3198
3199 sp<IBinder> token = target.inputChannel->getConnectionToken();
3200 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003201 if (connection == nullptr) {
3202 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003203 }
3204 newConnectionTokens.insert(std::move(token));
3205 newConnections.emplace_back(connection);
3206 }
3207 if (newConnectionTokens == mInteractionConnectionTokens) {
3208 return; // no change
3209 }
3210 mInteractionConnectionTokens = newConnectionTokens;
3211
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003212 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003213 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003214 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003215 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003216 std::string message = "Interaction with: " + targetList;
3217 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003218 message += "<none>";
3219 }
3220 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3221}
3222
chaviwfd6d3512019-03-25 13:23:49 -07003223void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003224 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003225 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003226 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3227 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003228 return;
3229 }
3230
Vishnu Nairc519ff72021-01-21 08:23:08 -08003231 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003232 if (focusedToken == token) {
3233 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003234 return;
3235 }
3236
Prabir Pradhancef936d2021-07-21 16:17:52 +00003237 auto command = [this, token]() REQUIRES(mLock) {
3238 scoped_unlock unlock(mLock);
3239 mPolicy->onPointerDownOutsideFocus(token);
3240 };
3241 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003242}
3243
3244void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003245 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003246 if (ATRACE_ENABLED()) {
3247 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003248 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003249 ATRACE_NAME(message.c_str());
3250 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003251 if (DEBUG_DISPATCH_CYCLE) {
3252 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3253 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003254
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003255 while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003256 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003257 dispatchEntry->deliveryTime = currentTime;
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08003258 const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003259 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003260
3261 // Publish the event.
3262 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003263 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3264 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003265 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003266 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3267 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003268
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003269 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003270 status = connection->inputPublisher
3271 .publishKeyEvent(dispatchEntry->seq,
3272 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3273 keyEntry.source, keyEntry.displayId,
3274 std::move(hmac), dispatchEntry->resolvedAction,
3275 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3276 keyEntry.scanCode, keyEntry.metaState,
3277 keyEntry.repeatCount, keyEntry.downTime,
3278 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003279 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003280 }
3281
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003282 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003283 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003284
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003285 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003286 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003287
chaviw82357092020-01-28 13:13:06 -08003288 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003289 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003290 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3291 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003292 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003293 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3294 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003295 // Don't apply window scale here since we don't want scale to affect raw
3296 // coordinates. The scale will be sent back to the client and applied
3297 // later when requesting relative coordinates.
3298 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3299 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003300 }
3301 usingCoords = scaledCoords;
3302 }
3303 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003304 // We don't want the dispatch target to know.
3305 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003306 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003307 scaledCoords[i].clear();
3308 }
3309 usingCoords = scaledCoords;
3310 }
3311 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003312
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003313 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003314
3315 // Publish the motion event.
3316 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003317 .publishMotionEvent(dispatchEntry->seq,
3318 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003319 motionEntry.deviceId, motionEntry.source,
3320 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003321 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003322 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003323 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003324 motionEntry.edgeFlags, motionEntry.metaState,
3325 motionEntry.buttonState,
3326 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003327 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003328 motionEntry.xPrecision, motionEntry.yPrecision,
3329 motionEntry.xCursorPosition,
3330 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003331 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003332 motionEntry.downTime, motionEntry.eventTime,
3333 motionEntry.pointerCount,
3334 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003335 break;
3336 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003337
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003338 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003339 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003340 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003341 focusEntry.id,
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07003342 focusEntry.hasFocus);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003343 break;
3344 }
3345
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003346 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3347 const TouchModeEntry& touchModeEntry =
3348 static_cast<const TouchModeEntry&>(eventEntry);
3349 status = connection->inputPublisher
3350 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3351 touchModeEntry.inTouchMode);
3352
3353 break;
3354 }
3355
Prabir Pradhan99987712020-11-10 18:43:05 -08003356 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3357 const auto& captureEntry =
3358 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3359 status = connection->inputPublisher
3360 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003361 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003362 break;
3363 }
3364
arthurhungb89ccb02020-12-30 16:19:01 +08003365 case EventEntry::Type::DRAG: {
3366 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3367 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3368 dragEntry.id, dragEntry.x,
3369 dragEntry.y,
3370 dragEntry.isExiting);
3371 break;
3372 }
3373
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003374 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003375 case EventEntry::Type::DEVICE_RESET:
3376 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003377 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003378 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003379 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003380 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381 }
3382
3383 // Check the result.
3384 if (status) {
3385 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003386 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003387 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003388 "This is unexpected because the wait queue is empty, so the pipe "
3389 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003390 "event to it, status=%s(%d)",
3391 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3392 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003393 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3394 } else {
3395 // Pipe is full and we are waiting for the app to finish process some events
3396 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003397 if (DEBUG_DISPATCH_CYCLE) {
3398 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3399 "waiting for the application to catch up",
3400 connection->getInputChannelName().c_str());
3401 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003402 }
3403 } else {
3404 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003405 "status=%s(%d)",
3406 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3407 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003408 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3409 }
3410 return;
3411 }
3412
3413 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003414 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3415 connection->outboundQueue.end(),
3416 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003417 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003418 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003419 if (connection->responsive) {
3420 mAnrTracker.insert(dispatchEntry->timeoutTime,
3421 connection->inputChannel->getConnectionToken());
3422 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003423 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003424 }
3425}
3426
chaviw09c8d2d2020-08-24 15:48:26 -07003427std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3428 size_t size;
3429 switch (event.type) {
3430 case VerifiedInputEvent::Type::KEY: {
3431 size = sizeof(VerifiedKeyEvent);
3432 break;
3433 }
3434 case VerifiedInputEvent::Type::MOTION: {
3435 size = sizeof(VerifiedMotionEvent);
3436 break;
3437 }
3438 }
3439 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3440 return mHmacKeyManager.sign(start, size);
3441}
3442
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003443const std::array<uint8_t, 32> InputDispatcher::getSignature(
3444 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003445 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3446 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003447 // Only sign events up and down events as the purely move events
3448 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003449 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003450 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003451
3452 VerifiedMotionEvent verifiedEvent =
3453 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3454 verifiedEvent.actionMasked = actionMasked;
3455 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3456 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003457}
3458
3459const std::array<uint8_t, 32> InputDispatcher::getSignature(
3460 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3461 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3462 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3463 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003464 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003465}
3466
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003468 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003469 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003470 if (DEBUG_DISPATCH_CYCLE) {
3471 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3472 connection->getInputChannelName().c_str(), seq, toString(handled));
3473 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003475 if (connection->status == Connection::Status::BROKEN ||
3476 connection->status == Connection::Status::ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003477 return;
3478 }
3479
3480 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003481 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3482 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3483 };
3484 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003485}
3486
3487void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003488 const sp<Connection>& connection,
3489 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003490 if (DEBUG_DISPATCH_CYCLE) {
3491 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3492 connection->getInputChannelName().c_str(), toString(notify));
3493 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494
3495 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003496 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003497 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003498 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003499 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003500
3501 // The connection appears to be unrecoverably broken.
3502 // Ignore already broken or zombie connections.
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003503 if (connection->status == Connection::Status::NORMAL) {
3504 connection->status = Connection::Status::BROKEN;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003505
3506 if (notify) {
3507 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003508 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3509 connection->getInputChannelName().c_str());
3510
3511 auto command = [this, connection]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003512 scoped_unlock unlock(mLock);
3513 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3514 };
3515 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003516 }
3517 }
3518}
3519
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003520void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3521 while (!queue.empty()) {
3522 DispatchEntry* dispatchEntry = queue.front();
3523 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003524 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003525 }
3526}
3527
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003528void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003529 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003530 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003531 }
3532 delete dispatchEntry;
3533}
3534
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003535int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3536 std::scoped_lock _l(mLock);
3537 sp<Connection> connection = getConnectionLocked(connectionToken);
3538 if (connection == nullptr) {
3539 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3540 connectionToken.get(), events);
3541 return 0; // remove the callback
3542 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003543
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003544 bool notify;
3545 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3546 if (!(events & ALOOPER_EVENT_INPUT)) {
3547 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3548 "events=0x%x",
3549 connection->getInputChannelName().c_str(), events);
3550 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003551 }
3552
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003553 nsecs_t currentTime = now();
3554 bool gotOne = false;
3555 status_t status = OK;
3556 for (;;) {
3557 Result<InputPublisher::ConsumerResponse> result =
3558 connection->inputPublisher.receiveConsumerResponse();
3559 if (!result.ok()) {
3560 status = result.error().code();
3561 break;
3562 }
3563
3564 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3565 const InputPublisher::Finished& finish =
3566 std::get<InputPublisher::Finished>(*result);
3567 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3568 finish.consumeTime);
3569 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003570 if (shouldReportMetricsForConnection(*connection)) {
3571 const InputPublisher::Timeline& timeline =
3572 std::get<InputPublisher::Timeline>(*result);
3573 mLatencyTracker
3574 .trackGraphicsLatency(timeline.inputEventId,
3575 connection->inputChannel->getConnectionToken(),
3576 std::move(timeline.graphicsTimeline));
3577 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003578 }
3579 gotOne = true;
3580 }
3581 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003582 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003583 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003584 return 1;
3585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003586 }
3587
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003588 notify = status != DEAD_OBJECT || !connection->monitor;
3589 if (notify) {
3590 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3591 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3592 status);
3593 }
3594 } else {
3595 // Monitor channels are never explicitly unregistered.
3596 // We do it automatically when the remote endpoint is closed so don't warn about them.
3597 const bool stillHaveWindowHandle =
3598 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3599 notify = !connection->monitor && stillHaveWindowHandle;
3600 if (notify) {
3601 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3602 connection->getInputChannelName().c_str(), events);
3603 }
3604 }
3605
3606 // Remove the channel.
3607 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3608 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003609}
3610
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003611void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003613 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003614 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003615 }
3616}
3617
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003618void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003619 const CancelationOptions& options) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08003620 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003621 for (const Monitor& monitor : monitors) {
3622 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003623 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003624 }
3625}
3626
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003628 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003629 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003630 if (connection == nullptr) {
3631 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003632 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003633
3634 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003635}
3636
3637void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3638 const sp<Connection>& connection, const CancelationOptions& options) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003639 if (connection->status == Connection::Status::BROKEN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640 return;
3641 }
3642
3643 nsecs_t currentTime = now();
3644
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003645 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003646 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003647
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003648 if (cancelationEvents.empty()) {
3649 return;
3650 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003651 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3652 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3653 "with reality: %s, mode=%d.",
3654 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3655 options.mode);
3656 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003657
Arthur Hungb3307ee2021-10-14 10:57:37 +00003658 std::string reason = std::string("reason=").append(options.reason);
3659 android_log_event_list(LOGTAG_INPUT_CANCEL)
3660 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3661
Svet Ganov5d3bc372020-01-26 23:11:07 -08003662 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003663 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003664 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3665 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003666 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003667 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003668 target.globalScaleFactor = windowInfo->globalScaleFactor;
3669 }
3670 target.inputChannel = connection->inputChannel;
3671 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3672
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003673 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003674 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003675 switch (cancelationEventEntry->type) {
3676 case EventEntry::Type::KEY: {
3677 logOutboundKeyDetails("cancel - ",
3678 static_cast<const KeyEntry&>(*cancelationEventEntry));
3679 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003680 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003681 case EventEntry::Type::MOTION: {
3682 logOutboundMotionDetails("cancel - ",
3683 static_cast<const MotionEntry&>(*cancelationEventEntry));
3684 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003685 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003686 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003687 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003688 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3689 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003690 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003691 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003692 break;
3693 }
3694 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003695 case EventEntry::Type::DEVICE_RESET:
3696 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003697 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003698 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003699 break;
3700 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003701 }
3702
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003703 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3704 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003705 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003706
3707 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003708}
3709
Svet Ganov5d3bc372020-01-26 23:11:07 -08003710void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3711 const sp<Connection>& connection) {
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08003712 if (connection->status == Connection::Status::BROKEN) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003713 return;
3714 }
3715
3716 nsecs_t currentTime = now();
3717
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003718 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003719 connection->inputState.synthesizePointerDownEvents(currentTime);
3720
3721 if (downEvents.empty()) {
3722 return;
3723 }
3724
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003725 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003726 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3727 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003728 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003729
3730 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003731 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003732 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3733 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003734 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003735 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003736 target.globalScaleFactor = windowInfo->globalScaleFactor;
3737 }
3738 target.inputChannel = connection->inputChannel;
3739 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3740
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003741 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003742 switch (downEventEntry->type) {
3743 case EventEntry::Type::MOTION: {
3744 logOutboundMotionDetails("down - ",
3745 static_cast<const MotionEntry&>(*downEventEntry));
3746 break;
3747 }
3748
3749 case EventEntry::Type::KEY:
3750 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003751 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003752 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003753 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003754 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003755 case EventEntry::Type::SENSOR:
3756 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003757 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003758 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003759 break;
3760 }
3761 }
3762
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003763 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3764 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003765 }
3766
3767 startDispatchCycleLocked(currentTime, connection);
3768}
3769
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003770std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3771 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003772 ALOG_ASSERT(pointerIds.value != 0);
3773
3774 uint32_t splitPointerIndexMap[MAX_POINTERS];
3775 PointerProperties splitPointerProperties[MAX_POINTERS];
3776 PointerCoords splitPointerCoords[MAX_POINTERS];
3777
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003778 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779 uint32_t splitPointerCount = 0;
3780
3781 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003782 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003784 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 uint32_t pointerId = uint32_t(pointerProperties.id);
3786 if (pointerIds.hasBit(pointerId)) {
3787 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3788 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3789 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003790 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791 splitPointerCount += 1;
3792 }
3793 }
3794
3795 if (splitPointerCount != pointerIds.count()) {
3796 // This is bad. We are missing some of the pointers that we expected to deliver.
3797 // Most likely this indicates that we received an ACTION_MOVE events that has
3798 // different pointer ids than we expected based on the previous ACTION_DOWN
3799 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3800 // in this way.
3801 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003802 "we expected there to be %d pointers. This probably means we received "
3803 "a broken sequence of pointer ids from the input device.",
3804 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003805 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003806 }
3807
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003808 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003809 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003810 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3811 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3813 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003814 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003815 uint32_t pointerId = uint32_t(pointerProperties.id);
3816 if (pointerIds.hasBit(pointerId)) {
3817 if (pointerIds.count() == 1) {
3818 // The first/last pointer went down/up.
3819 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003820 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003821 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3822 ? AMOTION_EVENT_ACTION_CANCEL
3823 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003824 } else {
3825 // A secondary pointer went down/up.
3826 uint32_t splitPointerIndex = 0;
3827 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3828 splitPointerIndex += 1;
3829 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003830 action = maskedAction |
3831 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003832 }
3833 } else {
3834 // An unrelated pointer changed.
3835 action = AMOTION_EVENT_ACTION_MOVE;
3836 }
3837 }
3838
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003839 int32_t newId = mIdGenerator.nextId();
3840 if (ATRACE_ENABLED()) {
3841 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3842 ") to MotionEvent(id=0x%" PRIx32 ").",
3843 originalMotionEntry.id, newId);
3844 ATRACE_NAME(message.c_str());
3845 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003846 std::unique_ptr<MotionEntry> splitMotionEntry =
3847 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3848 originalMotionEntry.deviceId, originalMotionEntry.source,
3849 originalMotionEntry.displayId,
3850 originalMotionEntry.policyFlags, action,
3851 originalMotionEntry.actionButton,
3852 originalMotionEntry.flags, originalMotionEntry.metaState,
3853 originalMotionEntry.buttonState,
3854 originalMotionEntry.classification,
3855 originalMotionEntry.edgeFlags,
3856 originalMotionEntry.xPrecision,
3857 originalMotionEntry.yPrecision,
3858 originalMotionEntry.xCursorPosition,
3859 originalMotionEntry.yCursorPosition,
3860 originalMotionEntry.downTime, splitPointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00003861 splitPointerProperties, splitPointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003862
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003863 if (originalMotionEntry.injectionState) {
3864 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 splitMotionEntry->injectionState->refCount += 1;
3866 }
3867
3868 return splitMotionEntry;
3869}
3870
3871void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003872 if (DEBUG_INBOUND_EVENT_DETAILS) {
3873 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3874 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875
Antonio Kantekf16f2832021-09-28 04:39:20 +00003876 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003877 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003878 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003880 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3881 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3882 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003883 } // release lock
3884
3885 if (needWake) {
3886 mLooper->wake();
3887 }
3888}
3889
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003890/**
3891 * If one of the meta shortcuts is detected, process them here:
3892 * Meta + Backspace -> generate BACK
3893 * Meta + Enter -> generate HOME
3894 * This will potentially overwrite keyCode and metaState.
3895 */
3896void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003897 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003898 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3899 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3900 if (keyCode == AKEYCODE_DEL) {
3901 newKeyCode = AKEYCODE_BACK;
3902 } else if (keyCode == AKEYCODE_ENTER) {
3903 newKeyCode = AKEYCODE_HOME;
3904 }
3905 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003906 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003907 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003908 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003909 keyCode = newKeyCode;
3910 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3911 }
3912 } else if (action == AKEY_EVENT_ACTION_UP) {
3913 // In order to maintain a consistent stream of up and down events, check to see if the key
3914 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3915 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003916 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003917 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003918 auto replacementIt = mReplacedKeys.find(replacement);
3919 if (replacementIt != mReplacedKeys.end()) {
3920 keyCode = replacementIt->second;
3921 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003922 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3923 }
3924 }
3925}
3926
Michael Wrightd02c5b62014-02-10 15:10:22 -08003927void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003928 if (DEBUG_INBOUND_EVENT_DETAILS) {
3929 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3930 "policyFlags=0x%x, action=0x%x, "
3931 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3932 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3933 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3934 args->downTime);
3935 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003936 if (!validateKeyEvent(args->action)) {
3937 return;
3938 }
3939
3940 uint32_t policyFlags = args->policyFlags;
3941 int32_t flags = args->flags;
3942 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003943 // InputDispatcher tracks and generates key repeats on behalf of
3944 // whatever notifies it, so repeatCount should always be set to 0
3945 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003946 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3947 policyFlags |= POLICY_FLAG_VIRTUAL;
3948 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3949 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950 if (policyFlags & POLICY_FLAG_FUNCTION) {
3951 metaState |= AMETA_FUNCTION_ON;
3952 }
3953
3954 policyFlags |= POLICY_FLAG_TRUSTED;
3955
Michael Wright78f24442014-08-06 15:55:28 -07003956 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003957 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003958
Michael Wrightd02c5b62014-02-10 15:10:22 -08003959 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003960 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003961 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3962 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003963
Michael Wright2b3c3302018-03-02 17:19:13 +00003964 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003965 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003966 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3967 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003968 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003969 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003970
Antonio Kantekf16f2832021-09-28 04:39:20 +00003971 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972 { // acquire lock
3973 mLock.lock();
3974
3975 if (shouldSendKeyToInputFilterLocked(args)) {
3976 mLock.unlock();
3977
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003978 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003979 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3980 return; // event was consumed by the filter
3981 }
3982
3983 mLock.lock();
3984 }
3985
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003986 std::unique_ptr<KeyEntry> newEntry =
3987 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3988 args->displayId, policyFlags, args->action, flags,
3989 keyCode, args->scanCode, metaState, repeatCount,
3990 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003991
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003992 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003993 mLock.unlock();
3994 } // release lock
3995
3996 if (needWake) {
3997 mLooper->wake();
3998 }
3999}
4000
4001bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
4002 return mInputFilterEnabled;
4003}
4004
4005void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004006 if (DEBUG_INBOUND_EVENT_DETAILS) {
4007 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4008 "displayId=%" PRId32 ", policyFlags=0x%x, "
4009 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
4010 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
4011 "yCursorPosition=%f, downTime=%" PRId64,
4012 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
4013 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
4014 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
4015 args->xCursorPosition, args->yCursorPosition, args->downTime);
4016 for (uint32_t i = 0; i < args->pointerCount; i++) {
4017 ALOGD(" Pointer %d: id=%d, toolType=%d, "
4018 "x=%f, y=%f, pressure=%f, size=%f, "
4019 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
4020 "orientation=%f",
4021 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
4022 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4023 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4024 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4025 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4026 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4027 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4028 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4029 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4030 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
4031 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004032 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004033 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
4034 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004035 return;
4036 }
4037
4038 uint32_t policyFlags = args->policyFlags;
4039 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004040
4041 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08004042 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00004043 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4044 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004045 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00004046 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004047
Antonio Kantekf16f2832021-09-28 04:39:20 +00004048 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004049 { // acquire lock
4050 mLock.lock();
4051
4052 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004053 ui::Transform displayTransform;
4054 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
4055 displayTransform = it->second.transform;
4056 }
4057
Michael Wrightd02c5b62014-02-10 15:10:22 -08004058 mLock.unlock();
4059
4060 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08004061 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
4062 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004063 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004064 displayTransform, args->xPrecision, args->yPrecision,
4065 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07004066 args->downTime, args->eventTime, args->pointerCount,
4067 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004068
4069 policyFlags |= POLICY_FLAG_FILTERED;
4070 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
4071 return; // event was consumed by the filter
4072 }
4073
4074 mLock.lock();
4075 }
4076
4077 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004078 std::unique_ptr<MotionEntry> newEntry =
4079 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
4080 args->source, args->displayId, policyFlags,
4081 args->action, args->actionButton, args->flags,
4082 args->metaState, args->buttonState,
4083 args->classification, args->edgeFlags,
4084 args->xPrecision, args->yPrecision,
4085 args->xCursorPosition, args->yCursorPosition,
4086 args->downTime, args->pointerCount,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004087 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004088
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004089 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4090 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4091 !mInputFilterEnabled) {
4092 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4093 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4094 }
4095
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004096 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097 mLock.unlock();
4098 } // release lock
4099
4100 if (needWake) {
4101 mLooper->wake();
4102 }
4103}
4104
Chris Yef59a2f42020-10-16 12:55:26 -07004105void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004106 if (DEBUG_INBOUND_EVENT_DETAILS) {
4107 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4108 " sensorType=%s",
4109 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004110 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004111 }
Chris Yef59a2f42020-10-16 12:55:26 -07004112
Antonio Kantekf16f2832021-09-28 04:39:20 +00004113 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004114 { // acquire lock
4115 mLock.lock();
4116
4117 // Just enqueue a new sensor event.
4118 std::unique_ptr<SensorEntry> newEntry =
4119 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4120 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4121 args->sensorType, args->accuracy,
4122 args->accuracyChanged, args->values);
4123
4124 needWake = enqueueInboundEventLocked(std::move(newEntry));
4125 mLock.unlock();
4126 } // release lock
4127
4128 if (needWake) {
4129 mLooper->wake();
4130 }
4131}
4132
Chris Yefb552902021-02-03 17:18:37 -08004133void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004134 if (DEBUG_INBOUND_EVENT_DETAILS) {
4135 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4136 args->deviceId, args->isOn);
4137 }
Chris Yefb552902021-02-03 17:18:37 -08004138 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4139}
4140
Michael Wrightd02c5b62014-02-10 15:10:22 -08004141bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004142 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004143}
4144
4145void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004146 if (DEBUG_INBOUND_EVENT_DETAILS) {
4147 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4148 "switchMask=0x%08x",
4149 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4150 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004151
4152 uint32_t policyFlags = args->policyFlags;
4153 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004154 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004155}
4156
4157void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004158 if (DEBUG_INBOUND_EVENT_DETAILS) {
4159 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4160 args->deviceId);
4161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004162
Antonio Kantekf16f2832021-09-28 04:39:20 +00004163 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004164 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004165 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004167 std::unique_ptr<DeviceResetEntry> newEntry =
4168 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4169 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170 } // release lock
4171
4172 if (needWake) {
4173 mLooper->wake();
4174 }
4175}
4176
Prabir Pradhan7e186182020-11-10 13:56:45 -08004177void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004178 if (DEBUG_INBOUND_EVENT_DETAILS) {
4179 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004180 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004181 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004182
Antonio Kantekf16f2832021-09-28 04:39:20 +00004183 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004184 { // acquire lock
4185 std::scoped_lock _l(mLock);
4186 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004187 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004188 needWake = enqueueInboundEventLocked(std::move(entry));
4189 } // release lock
4190
4191 if (needWake) {
4192 mLooper->wake();
4193 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004194}
4195
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004196InputEventInjectionResult InputDispatcher::injectInputEvent(
4197 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4198 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004199 if (DEBUG_INBOUND_EVENT_DETAILS) {
4200 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4201 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4202 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4203 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004204 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004205
4206 policyFlags |= POLICY_FLAG_INJECTED;
4207 if (hasInjectionPermission(injectorPid, injectorUid)) {
4208 policyFlags |= POLICY_FLAG_TRUSTED;
4209 }
4210
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004211 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004212 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4213 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4214 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4215 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4216 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004217 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004218 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004219 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004220 }
4221
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004222 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004224 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004225 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4226 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004227 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004228 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004229 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004230
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004231 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004232 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4233 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4234 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004235 int32_t keyCode = incomingKey.getKeyCode();
4236 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004237 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004238 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004239 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004240 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004241 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4242 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4243 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004244
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004245 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4246 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004247 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004248
4249 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4250 android::base::Timer t;
4251 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4252 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4253 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4254 std::to_string(t.duration().count()).c_str());
4255 }
4256 }
4257
4258 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004259 std::unique_ptr<KeyEntry> injectedEntry =
4260 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004261 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004262 incomingKey.getDisplayId(), policyFlags, action,
4263 flags, keyCode, incomingKey.getScanCode(), metaState,
4264 incomingKey.getRepeatCount(),
4265 incomingKey.getDownTime());
4266 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004267 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004268 }
4269
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004270 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004271 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004272 const int32_t action = motionEvent.getAction();
4273 const bool isPointerEvent =
4274 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4275 // If a pointer event has no displayId specified, inject it to the default display.
4276 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4277 ? ADISPLAY_ID_DEFAULT
4278 : event->getDisplayId();
4279 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004280 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004281 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004282 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004283 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004284 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004285 }
4286
4287 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004288 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004289 android::base::Timer t;
4290 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4291 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4292 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4293 std::to_string(t.duration().count()).c_str());
4294 }
4295 }
4296
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004297 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4298 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4299 }
4300
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004301 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004302 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4303 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004304 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004305 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4306 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004307 displayId, policyFlags, action, actionButton,
4308 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004309 motionEvent.getButtonState(),
4310 motionEvent.getClassification(),
4311 motionEvent.getEdgeFlags(),
4312 motionEvent.getXPrecision(),
4313 motionEvent.getYPrecision(),
4314 motionEvent.getRawXCursorPosition(),
4315 motionEvent.getRawYCursorPosition(),
4316 motionEvent.getDownTime(), uint32_t(pointerCount),
Prabir Pradhan5beda762021-12-10 09:30:08 +00004317 pointerProperties, samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004318 transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004319 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004320 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004321 sampleEventTimes += 1;
4322 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004323 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004324 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4325 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004326 displayId, policyFlags, action, actionButton,
4327 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004328 motionEvent.getButtonState(),
4329 motionEvent.getClassification(),
4330 motionEvent.getEdgeFlags(),
4331 motionEvent.getXPrecision(),
4332 motionEvent.getYPrecision(),
4333 motionEvent.getRawXCursorPosition(),
4334 motionEvent.getRawYCursorPosition(),
4335 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004336 uint32_t(pointerCount), pointerProperties,
Prabir Pradhan5beda762021-12-10 09:30:08 +00004337 samplePointerCoords);
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004338 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4339 motionEvent.getTransform());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004340 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004341 }
4342 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004344
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004345 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004346 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004347 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004348 }
4349
4350 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004351 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004352 injectionState->injectionIsAsync = true;
4353 }
4354
4355 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004356 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004357
4358 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004359 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004360 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004361 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004362 }
4363
4364 mLock.unlock();
4365
4366 if (needWake) {
4367 mLooper->wake();
4368 }
4369
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004370 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004371 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004372 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004373
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004374 if (syncMode == InputEventInjectionSync::NONE) {
4375 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004376 } else {
4377 for (;;) {
4378 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004379 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004380 break;
4381 }
4382
4383 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 injection result "
4387 "to become available.");
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 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004394 }
4395
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004396 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4397 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004398 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004399 if (DEBUG_INJECTION) {
4400 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4401 injectionState->pendingForegroundDispatches);
4402 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004403 nsecs_t remainingTimeout = endTime - now();
4404 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004405 if (DEBUG_INJECTION) {
4406 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4407 "dispatches to finish.");
4408 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004409 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004410 break;
4411 }
4412
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004413 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004414 }
4415 }
4416 }
4417
4418 injectionState->release();
4419 } // release lock
4420
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004421 if (DEBUG_INJECTION) {
4422 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4423 injectionResult, injectorPid, injectorUid);
4424 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004425
4426 return injectionResult;
4427}
4428
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004429std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004430 std::array<uint8_t, 32> calculatedHmac;
4431 std::unique_ptr<VerifiedInputEvent> result;
4432 switch (event.getType()) {
4433 case AINPUT_EVENT_TYPE_KEY: {
4434 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4435 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4436 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004437 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004438 break;
4439 }
4440 case AINPUT_EVENT_TYPE_MOTION: {
4441 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4442 VerifiedMotionEvent verifiedMotionEvent =
4443 verifiedMotionEventFromMotionEvent(motionEvent);
4444 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004445 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004446 break;
4447 }
4448 default: {
4449 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4450 return nullptr;
4451 }
4452 }
4453 if (calculatedHmac == INVALID_HMAC) {
4454 return nullptr;
4455 }
4456 if (calculatedHmac != event.getHmac()) {
4457 return nullptr;
4458 }
4459 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004460}
4461
Michael Wrightd02c5b62014-02-10 15:10:22 -08004462bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004463 return injectorUid == 0 ||
4464 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004465}
4466
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004467void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004468 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004469 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004470 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004471 if (DEBUG_INJECTION) {
4472 ALOGD("Setting input event injection result to %d. "
4473 "injectorPid=%d, injectorUid=%d",
4474 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4475 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004477 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478 // Log the outcome since the injector did not wait for the injection result.
4479 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004480 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004481 ALOGV("Asynchronous input event injection succeeded.");
4482 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004483 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004484 ALOGW("Asynchronous input event injection failed.");
4485 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004486 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004487 ALOGW("Asynchronous input event injection permission denied.");
4488 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004489 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004490 ALOGW("Asynchronous input event injection timed out.");
4491 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004492 case InputEventInjectionResult::PENDING:
4493 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4494 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004495 }
4496 }
4497
4498 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004499 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004500 }
4501}
4502
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004503void InputDispatcher::transformMotionEntryForInjectionLocked(
4504 MotionEntry& entry, const ui::Transform& injectedTransform) const {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004505 // Input injection works in the logical display coordinate space, but the input pipeline works
4506 // display space, so we need to transform the injected events accordingly.
4507 const auto it = mDisplayInfos.find(entry.displayId);
4508 if (it == mDisplayInfos.end()) return;
Prabir Pradhandaa2f142021-12-10 09:30:08 +00004509 const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004510
4511 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Prabir Pradhan8e6ce222022-02-24 09:08:54 -08004512 entry.pointerCoords[i] =
4513 MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
4514 entry.pointerCoords[i]);
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004515 }
4516}
4517
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004518void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4519 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004520 if (injectionState) {
4521 injectionState->pendingForegroundDispatches += 1;
4522 }
4523}
4524
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004525void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4526 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004527 if (injectionState) {
4528 injectionState->pendingForegroundDispatches -= 1;
4529
4530 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004531 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004532 }
4533 }
4534}
4535
chaviw98318de2021-05-19 16:45:23 -05004536const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004537 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004538 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004539 auto it = mWindowHandlesByDisplay.find(displayId);
4540 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004541}
4542
chaviw98318de2021-05-19 16:45:23 -05004543sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004544 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004545 if (windowHandleToken == nullptr) {
4546 return nullptr;
4547 }
4548
Arthur Hungb92218b2018-08-14 12:00:21 +08004549 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004550 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4551 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004552 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004553 return windowHandle;
4554 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004555 }
4556 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004557 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004558}
4559
chaviw98318de2021-05-19 16:45:23 -05004560sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4561 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004562 if (windowHandleToken == nullptr) {
4563 return nullptr;
4564 }
4565
chaviw98318de2021-05-19 16:45:23 -05004566 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004567 if (windowHandle->getToken() == windowHandleToken) {
4568 return windowHandle;
4569 }
4570 }
4571 return nullptr;
4572}
4573
chaviw98318de2021-05-19 16:45:23 -05004574sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4575 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004576 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004577 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4578 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004579 if (handle->getId() == windowHandle->getId() &&
4580 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004581 if (windowHandle->getInfo()->displayId != it.first) {
4582 ALOGE("Found window %s in display %" PRId32
4583 ", but it should belong to display %" PRId32,
4584 windowHandle->getName().c_str(), it.first,
4585 windowHandle->getInfo()->displayId);
4586 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004587 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004588 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589 }
4590 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004591 return nullptr;
4592}
4593
chaviw98318de2021-05-19 16:45:23 -05004594sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004595 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4596 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004597}
4598
chaviw98318de2021-05-19 16:45:23 -05004599bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004600 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4601 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004602 windowHandle.getInfo()->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004603 if (connection != nullptr && noInputChannel) {
4604 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4605 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4606 return false;
4607 }
4608
4609 if (connection == nullptr) {
4610 if (!noInputChannel) {
4611 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4612 }
4613 return false;
4614 }
4615 if (!connection->responsive) {
4616 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4617 return false;
4618 }
4619 return true;
4620}
4621
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004622std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4623 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004624 auto connectionIt = mConnectionsByToken.find(token);
4625 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004626 return nullptr;
4627 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004628 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004629}
4630
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004631void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004632 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4633 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004634 // Remove all handles on a display if there are no windows left.
4635 mWindowHandlesByDisplay.erase(displayId);
4636 return;
4637 }
4638
4639 // Since we compare the pointer of input window handles across window updates, we need
4640 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004641 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4642 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4643 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004644 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004645 }
4646
chaviw98318de2021-05-19 16:45:23 -05004647 std::vector<sp<WindowInfoHandle>> newHandles;
4648 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004649 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004650 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004651 const bool noInputChannel =
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004652 info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004653 const bool canReceiveInput =
4654 !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
4655 !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004656 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004657 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004658 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004659 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004660 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004661 }
4662
4663 if (info->displayId != displayId) {
4664 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4665 handle->getName().c_str(), displayId, info->displayId);
4666 continue;
4667 }
4668
Robert Carredd13602020-04-13 17:24:34 -07004669 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4670 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004671 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004672 oldHandle->updateFrom(handle);
4673 newHandles.push_back(oldHandle);
4674 } else {
4675 newHandles.push_back(handle);
4676 }
4677 }
4678
4679 // Insert or replace
4680 mWindowHandlesByDisplay[displayId] = newHandles;
4681}
4682
Arthur Hung72d8dc32020-03-28 00:48:39 +00004683void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004684 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004685 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004686 { // acquire lock
4687 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004688 for (const auto& [displayId, handles] : handlesPerDisplay) {
4689 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004690 }
4691 }
4692 // Wake up poll loop since it may need to make new input dispatching choices.
4693 mLooper->wake();
4694}
4695
Arthur Hungb92218b2018-08-14 12:00:21 +08004696/**
4697 * Called from InputManagerService, update window handle list by displayId that can receive input.
4698 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4699 * If set an empty list, remove all handles from the specific display.
4700 * For focused handle, check if need to change and send a cancel event to previous one.
4701 * For removed handle, check if need to send a cancel event if already in touch.
4702 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004703void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004704 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004705 if (DEBUG_FOCUS) {
4706 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004707 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004708 windowList += iwh->getName() + " ";
4709 }
4710 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4711 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004712
Prabir Pradhand65552b2021-10-07 11:23:50 -07004713 // Check preconditions for new input windows
chaviw98318de2021-05-19 16:45:23 -05004714 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Prabir Pradhand65552b2021-10-07 11:23:50 -07004715 const WindowInfo& info = *window->getInfo();
4716
4717 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
Prabir Pradhan51e7db02022-02-07 06:02:57 -08004718 const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004719 if (noInputWindow && window->getToken() != nullptr) {
4720 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4721 window->getName().c_str());
4722 window->releaseChannel();
4723 }
Prabir Pradhand65552b2021-10-07 11:23:50 -07004724
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004725 // Ensure all spy windows are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004726 LOG_ALWAYS_FATAL_IF(info.isSpy() &&
4727 !info.inputConfig.test(
4728 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhan5c85e052021-12-22 02:27:12 -08004729 "%s has feature SPY, but is not a trusted overlay.",
4730 window->getName().c_str());
4731
Prabir Pradhand65552b2021-10-07 11:23:50 -07004732 // Ensure all stylus interceptors are trusted overlays
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004733 LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
4734 !info.inputConfig.test(
4735 WindowInfo::InputConfig::TRUSTED_OVERLAY),
Prabir Pradhand65552b2021-10-07 11:23:50 -07004736 "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
4737 window->getName().c_str());
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004738 }
4739
Arthur Hung72d8dc32020-03-28 00:48:39 +00004740 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004741 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004742
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004743 // Save the old windows' orientation by ID before it gets updated.
4744 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004745 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004746 oldWindowOrientations.emplace(handle->getId(),
4747 handle->getInfo()->transform.getOrientation());
4748 }
4749
chaviw98318de2021-05-19 16:45:23 -05004750 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004751
chaviw98318de2021-05-19 16:45:23 -05004752 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004753 if (mLastHoverWindowHandle &&
4754 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4755 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004756 mLastHoverWindowHandle = nullptr;
4757 }
4758
Vishnu Nairc519ff72021-01-21 08:23:08 -08004759 std::optional<FocusResolver::FocusChanges> changes =
4760 mFocusResolver.setInputWindows(displayId, windowHandles);
4761 if (changes) {
4762 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004763 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004764
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004765 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4766 mTouchStatesByDisplay.find(displayId);
4767 if (stateIt != mTouchStatesByDisplay.end()) {
4768 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004769 for (size_t i = 0; i < state.windows.size();) {
4770 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004771 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004772 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004773 ALOGD("Touched window was removed: %s in display %" PRId32,
4774 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004775 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004776 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004777 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4778 if (touchedInputChannel != nullptr) {
4779 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4780 "touched window was removed");
4781 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004782 // Since we are about to drop the touch, cancel the events for the wallpaper as
4783 // well.
4784 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08004785 touchedWindow.windowHandle->getInfo()->inputConfig.test(
4786 gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004787 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4788 if (wallpaper != nullptr) {
4789 sp<Connection> wallpaperConnection =
4790 getConnectionLocked(wallpaper->getToken());
Siarhei Vishniakou2b030972021-11-18 10:01:27 -08004791 if (wallpaperConnection != nullptr) {
4792 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4793 options);
4794 }
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004795 }
4796 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004797 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004798 state.windows.erase(state.windows.begin() + i);
4799 } else {
4800 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004801 }
4802 }
arthurhungb89ccb02020-12-30 16:19:01 +08004803
arthurhung6d4bed92021-03-17 11:59:33 +08004804 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004805 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004806 if (mDragState &&
4807 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004808 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004809 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004810 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004811 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004812
Prabir Pradhan8b89c2f2021-07-29 16:30:14 +00004813 // Determine if the orientation of any of the input windows have changed, and cancel all
4814 // pointer events if necessary.
4815 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4816 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
4817 if (newWindowHandle != nullptr &&
4818 newWindowHandle->getInfo()->transform.getOrientation() !=
4819 oldWindowOrientations[oldWindowHandle->getId()]) {
4820 std::shared_ptr<InputChannel> inputChannel =
4821 getInputChannelLocked(newWindowHandle->getToken());
4822 if (inputChannel != nullptr) {
4823 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4824 "touched window's orientation changed");
4825 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004826 }
4827 }
4828 }
4829
Arthur Hung72d8dc32020-03-28 00:48:39 +00004830 // Release information for windows that are no longer present.
4831 // This ensures that unused input channels are released promptly.
4832 // Otherwise, they might stick around until the window handle is destroyed
4833 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004834 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004835 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004836 if (DEBUG_FOCUS) {
4837 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004838 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004839 oldWindowHandle->releaseChannel();
Arthur Hung25e2af12020-03-26 12:58:37 +00004840 }
chaviw291d88a2019-02-14 10:33:58 -08004841 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004842}
4843
4844void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004845 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004846 if (DEBUG_FOCUS) {
4847 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4848 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4849 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004850 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004851 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004852 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004853 } // release lock
4854
4855 // Wake up poll loop since it may need to make new input dispatching choices.
4856 mLooper->wake();
4857}
4858
Vishnu Nair599f1412021-06-21 10:39:58 -07004859void InputDispatcher::setFocusedApplicationLocked(
4860 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4861 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4862 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4863
4864 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4865 return; // This application is already focused. No need to wake up or change anything.
4866 }
4867
4868 // Set the new application handle.
4869 if (inputApplicationHandle != nullptr) {
4870 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4871 } else {
4872 mFocusedApplicationHandlesByDisplay.erase(displayId);
4873 }
4874
4875 // No matter what the old focused application was, stop waiting on it because it is
4876 // no longer focused.
4877 resetNoFocusedWindowTimeoutLocked();
4878}
4879
Tiger Huang721e26f2018-07-24 22:26:19 +08004880/**
4881 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4882 * the display not specified.
4883 *
4884 * We track any unreleased events for each window. If a window loses the ability to receive the
4885 * released event, we will send a cancel event to it. So when the focused display is changed, we
4886 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4887 * display. The display-specified events won't be affected.
4888 */
4889void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004890 if (DEBUG_FOCUS) {
4891 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4892 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004893 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004894 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004895
4896 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004897 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004898 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004899 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004900 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004901 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004902 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004903 CancelationOptions
4904 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4905 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004906 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004907 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4908 }
4909 }
4910 mFocusedDisplayId = displayId;
4911
Chris Ye3c2d6f52020-08-09 10:39:48 -07004912 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004913 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004914 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004915
Vishnu Nairad321cd2020-08-20 16:40:21 -07004916 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004917 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004918 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004919 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004920 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004921 }
4922 }
4923 }
4924
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004925 if (DEBUG_FOCUS) {
4926 logDispatchStateLocked();
4927 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004928 } // release lock
4929
4930 // Wake up poll loop since it may need to make new input dispatching choices.
4931 mLooper->wake();
4932}
4933
Michael Wrightd02c5b62014-02-10 15:10:22 -08004934void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004935 if (DEBUG_FOCUS) {
4936 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4937 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004938
4939 bool changed;
4940 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004941 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004942
4943 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4944 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004945 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004946 }
4947
4948 if (mDispatchEnabled && !enabled) {
4949 resetAndDropEverythingLocked("dispatcher is being disabled");
4950 }
4951
4952 mDispatchEnabled = enabled;
4953 mDispatchFrozen = frozen;
4954 changed = true;
4955 } else {
4956 changed = false;
4957 }
4958
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004959 if (DEBUG_FOCUS) {
4960 logDispatchStateLocked();
4961 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004962 } // release lock
4963
4964 if (changed) {
4965 // Wake up poll loop since it may need to make new input dispatching choices.
4966 mLooper->wake();
4967 }
4968}
4969
4970void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004971 if (DEBUG_FOCUS) {
4972 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4973 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004974
4975 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004976 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004977
4978 if (mInputFilterEnabled == enabled) {
4979 return;
4980 }
4981
4982 mInputFilterEnabled = enabled;
4983 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4984 } // release lock
4985
4986 // Wake up poll loop since there might be work to do to drop everything.
4987 mLooper->wake();
4988}
4989
Antonio Kantekea47acb2021-12-23 12:41:25 -08004990bool InputDispatcher::setInTouchMode(bool inTouchMode, int32_t pid, int32_t uid,
4991 bool hasPermission) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00004992 bool needWake = false;
4993 {
4994 std::scoped_lock lock(mLock);
4995 if (mInTouchMode == inTouchMode) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08004996 return false;
Antonio Kantekf16f2832021-09-28 04:39:20 +00004997 }
4998 if (DEBUG_TOUCH_MODE) {
Antonio Kantekea47acb2021-12-23 12:41:25 -08004999 ALOGD("Request to change touch mode from %s to %s (calling pid=%d, uid=%d, "
5000 "hasPermission=%s)",
5001 toString(mInTouchMode), toString(inTouchMode), pid, uid, toString(hasPermission));
5002 }
5003 if (!hasPermission) {
Antonio Kantek48710e42022-03-24 14:19:30 -07005004 if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5005 !recentWindowsAreOwnedByLocked(pid, uid)) {
5006 ALOGD("Touch mode switch rejected, caller (pid=%d, uid=%d) doesn't own the focused "
5007 "window nor none of the previously interacted window",
5008 pid, uid);
Antonio Kantekea47acb2021-12-23 12:41:25 -08005009 return false;
5010 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00005011 }
5012
5013 // TODO(b/198499018): Store touch mode per display.
5014 mInTouchMode = inTouchMode;
5015
Antonio Kantekf16f2832021-09-28 04:39:20 +00005016 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode);
5017 needWake = enqueueInboundEventLocked(std::move(entry));
5018 } // release lock
5019
5020 if (needWake) {
5021 mLooper->wake();
5022 }
Antonio Kantekea47acb2021-12-23 12:41:25 -08005023 return true;
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08005024}
5025
Antonio Kantek48710e42022-03-24 14:19:30 -07005026bool InputDispatcher::focusedWindowIsOwnedByLocked(int32_t pid, int32_t uid) {
5027 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5028 if (focusedToken == nullptr) {
5029 return false;
5030 }
5031 sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5032 return isWindowOwnedBy(windowHandle, pid, uid);
5033}
5034
5035bool InputDispatcher::recentWindowsAreOwnedByLocked(int32_t pid, int32_t uid) {
5036 return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5037 [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5038 const sp<WindowInfoHandle> windowHandle =
5039 getWindowHandleLocked(connectionToken);
5040 return isWindowOwnedBy(windowHandle, pid, uid);
5041 }) != mInteractionConnectionTokens.end();
5042}
5043
Bernardo Rufinoea97d182020-08-19 14:43:14 +01005044void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5045 if (opacity < 0 || opacity > 1) {
5046 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5047 return;
5048 }
5049
5050 std::scoped_lock lock(mLock);
5051 mMaximumObscuringOpacityForTouch = opacity;
5052}
5053
5054void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
5055 std::scoped_lock lock(mLock);
5056 mBlockUntrustedTouchesMode = mode;
5057}
5058
Arthur Hungabbb9d82021-09-01 14:52:30 +00005059std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
5060 const sp<IBinder>& token) {
5061 for (auto& [displayId, state] : mTouchStatesByDisplay) {
5062 for (TouchedWindow& w : state.windows) {
5063 if (w.windowHandle->getToken() == token) {
5064 return std::make_pair(&state, &w);
5065 }
5066 }
5067 }
5068 return std::make_pair(nullptr, nullptr);
5069}
5070
arthurhungb89ccb02020-12-30 16:19:01 +08005071bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5072 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08005073 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005074 if (DEBUG_FOCUS) {
5075 ALOGD("Trivial transfer to same window.");
5076 }
chaviwfbe5d9c2018-12-26 12:23:37 -08005077 return true;
5078 }
5079
Michael Wrightd02c5b62014-02-10 15:10:22 -08005080 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005081 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005082
Arthur Hungabbb9d82021-09-01 14:52:30 +00005083 // Find the target touch state and touched window by fromToken.
5084 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
5085 if (state == nullptr || touchedWindow == nullptr) {
5086 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005087 return false;
5088 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00005089
5090 const int32_t displayId = state->displayId;
5091 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5092 if (toWindowHandle == nullptr) {
5093 ALOGW("Cannot transfer focus because to window not found.");
5094 return false;
5095 }
5096
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005097 if (DEBUG_FOCUS) {
5098 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005099 touchedWindow->windowHandle->getName().c_str(),
5100 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005101 }
5102
Arthur Hungabbb9d82021-09-01 14:52:30 +00005103 // Erase old window.
5104 int32_t oldTargetFlags = touchedWindow->targetFlags;
5105 BitSet32 pointerIds = touchedWindow->pointerIds;
5106 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005107
Arthur Hungabbb9d82021-09-01 14:52:30 +00005108 // Add new window.
Prabir Pradhan6dfbf262022-03-14 15:24:30 +00005109 int32_t newTargetFlags =
5110 oldTargetFlags & (InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
5111 if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
5112 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
5113 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00005114 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005115
Arthur Hungabbb9d82021-09-01 14:52:30 +00005116 // Store the dragging window.
5117 if (isDragDrop) {
5118 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005119 }
5120
Arthur Hungabbb9d82021-09-01 14:52:30 +00005121 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005122 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5123 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005124 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005125 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005126 CancelationOptions
5127 options(CancelationOptions::CANCEL_POINTER_EVENTS,
5128 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005129 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005130 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005131 }
5132
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005133 if (DEBUG_FOCUS) {
5134 logDispatchStateLocked();
5135 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005136 } // release lock
5137
5138 // Wake up poll loop since it may need to make new input dispatching choices.
5139 mLooper->wake();
5140 return true;
5141}
5142
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005143// Binder call
5144bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5145 sp<IBinder> fromToken;
5146 { // acquire lock
5147 std::scoped_lock _l(mLock);
5148
Arthur Hungabbb9d82021-09-01 14:52:30 +00005149 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5150 [](const auto& pair) { return pair.second.windows.size() == 1; });
5151 if (it == mTouchStatesByDisplay.end()) {
5152 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5153 return false;
5154 }
5155 const int32_t displayId = it->first;
5156 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005157 if (toWindowHandle == nullptr) {
5158 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5159 return false;
5160 }
5161
Arthur Hungabbb9d82021-09-01 14:52:30 +00005162 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005163 const TouchedWindow& touchedWindow = state.windows[0];
5164 fromToken = touchedWindow.windowHandle->getToken();
5165 } // release lock
5166
5167 return transferTouchFocus(fromToken, destChannelToken);
5168}
5169
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005171 if (DEBUG_FOCUS) {
5172 ALOGD("Resetting and dropping all events (%s).", reason);
5173 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005174
5175 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5176 synthesizeCancelationEventsForAllConnectionsLocked(options);
5177
5178 resetKeyRepeatLocked();
5179 releasePendingEventLocked();
5180 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005181 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005182
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005183 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005184 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005185 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005186 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005187}
5188
5189void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005190 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005191 dumpDispatchStateLocked(dump);
5192
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005193 std::istringstream stream(dump);
5194 std::string line;
5195
5196 while (std::getline(stream, line, '\n')) {
5197 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005198 }
5199}
5200
Prabir Pradhan99987712020-11-10 18:43:05 -08005201std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5202 std::string dump;
5203
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005204 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5205 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005206
5207 std::string windowName = "None";
5208 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005209 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005210 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5211 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5212 : "token has capture without window";
5213 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005214 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005215
5216 return dump;
5217}
5218
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005219void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005220 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5221 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5222 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005223 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005224
Tiger Huang721e26f2018-07-24 22:26:19 +08005225 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5226 dump += StringPrintf(INDENT "FocusedApplications:\n");
5227 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5228 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005229 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005230 const std::chrono::duration timeout =
5231 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005232 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005233 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005234 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005235 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005236 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005237 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005238 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005239
Vishnu Nairc519ff72021-01-21 08:23:08 -08005240 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005241 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005242
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005243 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005244 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005245 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5246 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005247 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005248 state.displayId, toString(state.down), toString(state.split),
5249 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005250 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005251 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005252 for (size_t i = 0; i < state.windows.size(); i++) {
5253 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005254 dump += StringPrintf(INDENT4
5255 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5256 i, touchedWindow.windowHandle->getName().c_str(),
5257 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005258 }
5259 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005260 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005261 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005262 }
5263 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005264 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005265 }
5266
arthurhung6d4bed92021-03-17 11:59:33 +08005267 if (mDragState) {
5268 dump += StringPrintf(INDENT "DragState:\n");
5269 mDragState->dump(dump, INDENT2);
5270 }
5271
Arthur Hungb92218b2018-08-14 12:00:21 +08005272 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005273 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5274 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5275 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5276 const auto& displayInfo = it->second;
5277 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5278 displayInfo.logicalHeight);
5279 displayInfo.transform.dump(dump, "transform", INDENT4);
5280 } else {
5281 dump += INDENT2 "No DisplayInfo found!\n";
5282 }
5283
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005284 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005285 dump += INDENT2 "Windows:\n";
5286 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005287 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5288 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005290 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005291 "inputConfig=%s, alpha=%.2f, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005292 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005293 "applicationInfo.name=%s, "
5294 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005295 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005296 i, windowInfo->name.c_str(), windowInfo->id,
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005297 windowInfo->displayId,
5298 windowInfo->inputConfig.string().c_str(),
5299 windowInfo->alpha, windowInfo->frameLeft,
5300 windowInfo->frameTop, windowInfo->frameRight,
5301 windowInfo->frameBottom, windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005302 windowInfo->applicationInfo.name.c_str(),
5303 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005304 dump += dumpRegion(windowInfo->touchableRegion);
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005305 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -08005306 "ms, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005307 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005308 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005309 millis(windowInfo->dispatchingTimeout),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005310 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005311 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005312 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005313 }
5314 } else {
5315 dump += INDENT2 "Windows: <none>\n";
5316 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005317 }
5318 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005319 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005320 }
5321
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005322 if (!mGlobalMonitorsByDisplay.empty()) {
5323 for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
5324 dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
Michael Wright3dd60e22019-03-27 22:06:44 +00005325 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005326 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005327 } else {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005328 dump += INDENT "Global Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329 }
5330
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005331 const nsecs_t currentTime = now();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005332
5333 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005334 if (!mRecentQueue.empty()) {
5335 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005336 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005337 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005338 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005339 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005340 }
5341 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005342 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005343 }
5344
5345 // Dump event currently being dispatched.
5346 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005347 dump += INDENT "PendingEvent:\n";
5348 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005349 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005350 dump += StringPrintf(", age=%" PRId64 "ms\n",
5351 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005352 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005353 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005354 }
5355
5356 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005357 if (!mInboundQueue.empty()) {
5358 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005359 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005360 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005361 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005362 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005363 }
5364 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005365 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005366 }
5367
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005368 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005369 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005370 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5371 const KeyReplacement& replacement = pair.first;
5372 int32_t newKeyCode = pair.second;
5373 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005374 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005375 }
5376 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005377 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005378 }
5379
Prabir Pradhancef936d2021-07-21 16:17:52 +00005380 if (!mCommandQueue.empty()) {
5381 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5382 } else {
5383 dump += INDENT "CommandQueue: <empty>\n";
5384 }
5385
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005386 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005387 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005388 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005389 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005390 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005391 connection->inputChannel->getFd().get(),
5392 connection->getInputChannelName().c_str(),
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005393 connection->getWindowName().c_str(),
5394 ftl::enum_string(connection->status).c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005395 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005396
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005397 if (!connection->outboundQueue.empty()) {
5398 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5399 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005400 dump += dumpQueue(connection->outboundQueue, currentTime);
5401
Michael Wrightd02c5b62014-02-10 15:10:22 -08005402 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005403 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005404 }
5405
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005406 if (!connection->waitQueue.empty()) {
5407 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5408 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005409 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005410 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005411 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005412 }
5413 }
5414 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005415 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005416 }
5417
5418 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005419 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5420 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005421 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005422 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005423 }
5424
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005425 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005426 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5427 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5428 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005429 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005430 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005431}
5432
Michael Wright3dd60e22019-03-27 22:06:44 +00005433void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5434 const size_t numMonitors = monitors.size();
5435 for (size_t i = 0; i < numMonitors; i++) {
5436 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005437 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005438 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5439 dump += "\n";
5440 }
5441}
5442
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005443class LooperEventCallback : public LooperCallback {
5444public:
5445 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5446 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5447
5448private:
5449 std::function<int(int events)> mCallback;
5450};
5451
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005452Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005453 if (DEBUG_CHANNEL_CREATION) {
5454 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5455 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005456
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005457 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005458 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005459 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005460
5461 if (result) {
5462 return base::Error(result) << "Failed to open input channel pair with name " << name;
5463 }
5464
Michael Wrightd02c5b62014-02-10 15:10:22 -08005465 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005466 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005467 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005468 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005469 sp<Connection> connection =
5470 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005471
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005472 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5473 ALOGE("Created a new connection, but the token %p is already known", token.get());
5474 }
5475 mConnectionsByToken.emplace(token, connection);
5476
5477 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5478 this, std::placeholders::_1, token);
5479
5480 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005481 } // release lock
5482
5483 // Wake the looper because some connections have changed.
5484 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005485 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005486}
5487
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005488Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005489 const std::string& name,
5490 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005491 std::shared_ptr<InputChannel> serverChannel;
5492 std::unique_ptr<InputChannel> clientChannel;
5493 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5494 if (result) {
5495 return base::Error(result) << "Failed to open input channel pair with name " << name;
5496 }
5497
Michael Wright3dd60e22019-03-27 22:06:44 +00005498 { // acquire lock
5499 std::scoped_lock _l(mLock);
5500
5501 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005502 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5503 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005504 }
5505
Garfield Tan15601662020-09-22 15:32:38 -07005506 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005507 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005508 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005509
5510 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5511 ALOGE("Created a new connection, but the token %p is already known", token.get());
5512 }
5513 mConnectionsByToken.emplace(token, connection);
5514 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5515 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005516
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005517 mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005518
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005519 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wright3dd60e22019-03-27 22:06:44 +00005520 }
Garfield Tan15601662020-09-22 15:32:38 -07005521
Michael Wright3dd60e22019-03-27 22:06:44 +00005522 // Wake the looper because some connections have changed.
5523 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005524 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005525}
5526
Garfield Tan15601662020-09-22 15:32:38 -07005527status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005528 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005529 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005530
Garfield Tan15601662020-09-22 15:32:38 -07005531 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005532 if (status) {
5533 return status;
5534 }
5535 } // release lock
5536
5537 // Wake the poll loop because removing the connection may have changed the current
5538 // synchronization state.
5539 mLooper->wake();
5540 return OK;
5541}
5542
Garfield Tan15601662020-09-22 15:32:38 -07005543status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5544 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005545 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005546 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005547 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005548 return BAD_VALUE;
5549 }
5550
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005551 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005552
Michael Wrightd02c5b62014-02-10 15:10:22 -08005553 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005554 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005555 }
5556
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005557 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005558
5559 nsecs_t currentTime = now();
5560 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5561
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005562 connection->status = Connection::Status::ZOMBIE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005563 return OK;
5564}
5565
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005566void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005567 for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
5568 auto& [displayId, monitors] = *it;
5569 std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
5570 return monitor.inputChannel->getConnectionToken() == connectionToken;
5571 });
Michael Wright3dd60e22019-03-27 22:06:44 +00005572
Michael Wright3dd60e22019-03-27 22:06:44 +00005573 if (monitors.empty()) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005574 it = mGlobalMonitorsByDisplay.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) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005582 std::scoped_lock _l(mLock);
Michael Wright3dd60e22019-03-27 22:06:44 +00005583
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005584 const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
5585 if (!requestingChannel) {
5586 ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
5587 return BAD_VALUE;
Michael Wright3dd60e22019-03-27 22:06:44 +00005588 }
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005589
5590 auto [statePtr, windowPtr] = findTouchStateAndWindowLocked(token);
5591 if (statePtr == nullptr || windowPtr == nullptr || !statePtr->down) {
5592 ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
5593 " Ignoring.");
5594 return BAD_VALUE;
5595 }
5596
5597 TouchState& state = *statePtr;
5598
5599 // Send cancel events to all the input channels we're stealing from.
5600 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
5601 "input channel stole pointer stream");
5602 options.deviceId = state.deviceId;
5603 options.displayId = state.displayId;
5604 std::string canceledWindows;
5605 for (const TouchedWindow& window : state.windows) {
5606 const std::shared_ptr<InputChannel> channel =
5607 getInputChannelLocked(window.windowHandle->getToken());
5608 if (channel != nullptr && channel->getConnectionToken() != token) {
5609 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5610 canceledWindows += canceledWindows.empty() ? "[" : ", ";
5611 canceledWindows += channel->getName();
5612 }
5613 }
5614 canceledWindows += canceledWindows.empty() ? "[]" : "]";
5615 ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(),
5616 canceledWindows.c_str());
5617
Prabir Pradhane680f9b2022-02-04 04:24:00 -08005618 // Prevent the gesture from being sent to any other windows.
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005619 state.filterWindowsExcept(token);
Prabir Pradhane680f9b2022-02-04 04:24:00 -08005620 state.preventNewTargets = true;
Michael Wright3dd60e22019-03-27 22:06:44 +00005621 return OK;
5622}
5623
Prabir Pradhan99987712020-11-10 18:43:05 -08005624void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5625 { // acquire lock
5626 std::scoped_lock _l(mLock);
5627 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005628 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005629 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5630 windowHandle != nullptr ? windowHandle->getName().c_str()
5631 : "token without window");
5632 }
5633
Vishnu Nairc519ff72021-01-21 08:23:08 -08005634 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005635 if (focusedToken != windowToken) {
5636 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5637 enabled ? "enable" : "disable");
5638 return;
5639 }
5640
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005641 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005642 ALOGW("Ignoring request to %s Pointer Capture: "
5643 "window has %s requested pointer capture.",
5644 enabled ? "enable" : "disable", enabled ? "already" : "not");
5645 return;
5646 }
5647
Christine Franksb768bb42021-11-29 12:11:31 -08005648 if (enabled) {
5649 if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
5650 mIneligibleDisplaysForPointerCapture.end(),
5651 mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
5652 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
5653 return;
5654 }
5655 }
5656
Prabir Pradhan99987712020-11-10 18:43:05 -08005657 setPointerCaptureLocked(enabled);
5658 } // release lock
5659
5660 // Wake the thread to process command entries.
5661 mLooper->wake();
5662}
5663
Christine Franksb768bb42021-11-29 12:11:31 -08005664void InputDispatcher::setDisplayEligibilityForPointerCapture(int32_t displayId, bool isEligible) {
5665 { // acquire lock
5666 std::scoped_lock _l(mLock);
5667 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
5668 if (!isEligible) {
5669 mIneligibleDisplaysForPointerCapture.push_back(displayId);
5670 }
5671 } // release lock
5672}
5673
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005674std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5675 for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005676 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005677 if (monitor.inputChannel->getConnectionToken() == token) {
Prabir Pradhandfabf8a2022-01-21 08:19:30 -08005678 return monitor.pid;
Michael Wright3dd60e22019-03-27 22:06:44 +00005679 }
5680 }
5681 }
5682 return std::nullopt;
5683}
5684
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005685sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005686 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005687 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005688 }
5689
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005690 for (const auto& [token, connection] : mConnectionsByToken) {
5691 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005692 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005693 }
5694 }
Robert Carr4e670e52018-08-15 13:26:12 -07005695
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005696 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005697}
5698
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005699std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5700 sp<Connection> connection = getConnectionLocked(connectionToken);
5701 if (connection == nullptr) {
5702 return "<nullptr>";
5703 }
5704 return connection->getInputChannelName();
5705}
5706
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005707void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005708 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005709 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005710}
5711
Prabir Pradhancef936d2021-07-21 16:17:52 +00005712void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5713 const sp<Connection>& connection, uint32_t seq,
5714 bool handled, nsecs_t consumeTime) {
5715 // Handle post-event policy actions.
5716 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5717 if (dispatchEntryIt == connection->waitQueue.end()) {
5718 return;
5719 }
5720 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5721 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5722 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5723 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5724 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5725 }
5726 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5727 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5728 connection->inputChannel->getConnectionToken(),
5729 dispatchEntry->deliveryTime, consumeTime, finishTime);
5730 }
5731
5732 bool restartEvent;
5733 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5734 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5735 restartEvent =
5736 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5737 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5738 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5739 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5740 handled);
5741 } else {
5742 restartEvent = false;
5743 }
5744
5745 // Dequeue the event and start the next cycle.
5746 // Because the lock might have been released, it is possible that the
5747 // contents of the wait queue to have been drained, so we need to double-check
5748 // a few things.
5749 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5750 if (dispatchEntryIt != connection->waitQueue.end()) {
5751 dispatchEntry = *dispatchEntryIt;
5752 connection->waitQueue.erase(dispatchEntryIt);
5753 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5754 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5755 if (!connection->responsive) {
5756 connection->responsive = isConnectionResponsive(*connection);
5757 if (connection->responsive) {
5758 // The connection was unresponsive, and now it's responsive.
5759 processConnectionResponsiveLocked(*connection);
5760 }
5761 }
5762 traceWaitQueueLength(*connection);
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08005763 if (restartEvent && connection->status == Connection::Status::NORMAL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005764 connection->outboundQueue.push_front(dispatchEntry);
5765 traceOutboundQueueLength(*connection);
5766 } else {
5767 releaseDispatchEntry(dispatchEntry);
5768 }
5769 }
5770
5771 // Start the next dispatch cycle for this connection.
5772 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005773}
5774
Prabir Pradhancef936d2021-07-21 16:17:52 +00005775void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5776 const sp<IBinder>& newToken) {
5777 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5778 scoped_unlock unlock(mLock);
5779 mPolicy->notifyFocusChanged(oldToken, newToken);
5780 };
5781 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005782}
5783
Prabir Pradhancef936d2021-07-21 16:17:52 +00005784void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5785 auto command = [this, token, x, y]() REQUIRES(mLock) {
5786 scoped_unlock unlock(mLock);
5787 mPolicy->notifyDropWindow(token, x, y);
5788 };
5789 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005790}
5791
Prabir Pradhancef936d2021-07-21 16:17:52 +00005792void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5793 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5794 scoped_unlock unlock(mLock);
5795 mPolicy->notifyUntrustedTouch(obscuringPackage);
5796 };
5797 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005798}
5799
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005800void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5801 if (connection == nullptr) {
5802 LOG_ALWAYS_FATAL("Caller must check for nullness");
5803 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005804 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5805 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005806 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005807 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005808 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005809 return;
5810 }
5811 /**
5812 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5813 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5814 * has changed. This could cause newer entries to time out before the already dispatched
5815 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5816 * processes the events linearly. So providing information about the oldest entry seems to be
5817 * most useful.
5818 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005819 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005820 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5821 std::string reason =
5822 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005823 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005824 ns2ms(currentWait),
5825 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005826 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005827 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005828
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005829 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5830
5831 // Stop waking up for events on this connection, it is already unresponsive
5832 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005833}
5834
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005835void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5836 std::string reason =
5837 StringPrintf("%s does not have a focused window", application->getName().c_str());
5838 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005839
Prabir Pradhancef936d2021-07-21 16:17:52 +00005840 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5841 scoped_unlock unlock(mLock);
5842 mPolicy->notifyNoFocusedWindowAnr(application);
5843 };
5844 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005845}
5846
chaviw98318de2021-05-19 16:45:23 -05005847void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005848 const std::string& reason) {
5849 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5850 updateLastAnrStateLocked(windowLabel, reason);
5851}
5852
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005853void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5854 const std::string& reason) {
5855 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005856 updateLastAnrStateLocked(windowLabel, reason);
5857}
5858
5859void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5860 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005861 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005862 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005863 struct tm tm;
5864 localtime_r(&t, &tm);
5865 char timestr[64];
5866 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005867 mLastAnrState.clear();
5868 mLastAnrState += INDENT "ANR:\n";
5869 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005870 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5871 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005872 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005873}
5874
Prabir Pradhancef936d2021-07-21 16:17:52 +00005875void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5876 KeyEntry& entry) {
5877 const KeyEvent event = createKeyEvent(entry);
5878 nsecs_t delay = 0;
5879 { // release lock
5880 scoped_unlock unlock(mLock);
5881 android::base::Timer t;
5882 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5883 entry.policyFlags);
5884 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5885 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5886 std::to_string(t.duration().count()).c_str());
5887 }
5888 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005889
5890 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005891 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005892 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005893 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005894 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005895 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5896 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005897 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005898}
5899
Prabir Pradhancef936d2021-07-21 16:17:52 +00005900void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Prabir Pradhanedd96402022-02-15 01:46:16 -08005901 std::optional<int32_t> pid,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005902 std::string reason) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08005903 auto command = [this, token, pid, reason = std::move(reason)]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005904 scoped_unlock unlock(mLock);
Prabir Pradhanedd96402022-02-15 01:46:16 -08005905 mPolicy->notifyWindowUnresponsive(token, pid, reason);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005906 };
5907 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005908}
5909
Prabir Pradhanedd96402022-02-15 01:46:16 -08005910void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
5911 std::optional<int32_t> pid) {
5912 auto command = [this, token, pid]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005913 scoped_unlock unlock(mLock);
Prabir Pradhanedd96402022-02-15 01:46:16 -08005914 mPolicy->notifyWindowResponsive(token, pid);
Prabir Pradhancef936d2021-07-21 16:17:52 +00005915 };
5916 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005917}
5918
5919/**
5920 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5921 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5922 * command entry to the command queue.
5923 */
5924void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5925 std::string reason) {
5926 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanedd96402022-02-15 01:46:16 -08005927 std::optional<int32_t> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005928 if (connection.monitor) {
5929 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5930 reason.c_str());
Prabir Pradhanedd96402022-02-15 01:46:16 -08005931 pid = findMonitorPidByTokenLocked(connectionToken);
5932 } else {
5933 // The connection is a window
5934 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5935 reason.c_str());
5936 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
5937 if (handle != nullptr) {
5938 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005939 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005940 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08005941 sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005942}
5943
5944/**
5945 * Tell the policy that a connection has become responsive so that it can stop ANR.
5946 */
5947void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5948 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
Prabir Pradhanedd96402022-02-15 01:46:16 -08005949 std::optional<int32_t> pid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005950 if (connection.monitor) {
Prabir Pradhanedd96402022-02-15 01:46:16 -08005951 pid = findMonitorPidByTokenLocked(connectionToken);
5952 } else {
5953 // The connection is a window
5954 const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
5955 if (handle != nullptr) {
5956 pid = handle->getInfo()->ownerPid;
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005957 }
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005958 }
Prabir Pradhanedd96402022-02-15 01:46:16 -08005959 sendWindowResponsiveCommandLocked(connectionToken, pid);
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005960}
5961
Prabir Pradhancef936d2021-07-21 16:17:52 +00005962bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005963 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005964 KeyEntry& keyEntry, bool handled) {
5965 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005966 if (!handled) {
5967 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005968 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005969 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005970 return false;
5971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005972
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005973 // Get the fallback key state.
5974 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005975 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005976 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005977 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005978 connection->inputState.removeFallbackKey(originalKeyCode);
5979 }
5980
5981 if (handled || !dispatchEntry->hasForegroundTarget()) {
5982 // If the application handles the original key for which we previously
5983 // generated a fallback or if the window is not a foreground window,
5984 // then cancel the associated fallback key, if any.
5985 if (fallbackKeyCode != -1) {
5986 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005987 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5988 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5989 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5990 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5991 keyEntry.policyFlags);
5992 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005993 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005994 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005995
5996 mLock.unlock();
5997
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005998 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005999 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006000
6001 mLock.lock();
6002
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006003 // Cancel the fallback key.
6004 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006005 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006006 "application handled the original non-fallback key "
6007 "or is no longer a foreground target, "
6008 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08006009 options.keyCode = fallbackKeyCode;
6010 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006011 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006012 connection->inputState.removeFallbackKey(originalKeyCode);
6013 }
6014 } else {
6015 // If the application did not handle a non-fallback key, first check
6016 // that we are in a good state to perform unhandled key event processing
6017 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006018 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006019 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006020 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6021 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6022 "since this is not an initial down. "
6023 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6024 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6025 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006026 return false;
6027 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006028
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006029 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006030 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6031 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
6032 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6033 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6034 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006035 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006036
6037 mLock.unlock();
6038
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07006039 bool fallback =
6040 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006041 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006042
6043 mLock.lock();
6044
Siarhei Vishniakouf12f2f72021-11-17 17:49:45 -08006045 if (connection->status != Connection::Status::NORMAL) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006046 connection->inputState.removeFallbackKey(originalKeyCode);
6047 return false;
6048 }
6049
6050 // Latch the fallback keycode for this key on an initial down.
6051 // The fallback keycode cannot change at any other point in the lifecycle.
6052 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006053 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006054 fallbackKeyCode = event.getKeyCode();
6055 } else {
6056 fallbackKeyCode = AKEYCODE_UNKNOWN;
6057 }
6058 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
6059 }
6060
6061 ALOG_ASSERT(fallbackKeyCode != -1);
6062
6063 // Cancel the fallback key if the policy decides not to send it anymore.
6064 // We will continue to dispatch the key to the policy but we will no
6065 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006066 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
6067 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006068 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6069 if (fallback) {
6070 ALOGD("Unhandled key event: Policy requested to send key %d"
6071 "as a fallback for %d, but on the DOWN it had requested "
6072 "to send %d instead. Fallback canceled.",
6073 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
6074 } else {
6075 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6076 "but on the DOWN it had requested to send %d. "
6077 "Fallback canceled.",
6078 originalKeyCode, fallbackKeyCode);
6079 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006080 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006081
6082 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6083 "canceling fallback, policy no longer desires it");
6084 options.keyCode = fallbackKeyCode;
6085 synthesizeCancelationEventsForConnectionLocked(connection, options);
6086
6087 fallback = false;
6088 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006089 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006090 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006091 }
6092 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006093
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006094 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6095 {
6096 std::string msg;
6097 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6098 connection->inputState.getFallbackKeys();
6099 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6100 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6101 }
6102 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6103 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006104 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006105 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006106
6107 if (fallback) {
6108 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006109 keyEntry.eventTime = event.getEventTime();
6110 keyEntry.deviceId = event.getDeviceId();
6111 keyEntry.source = event.getSource();
6112 keyEntry.displayId = event.getDisplayId();
6113 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6114 keyEntry.keyCode = fallbackKeyCode;
6115 keyEntry.scanCode = event.getScanCode();
6116 keyEntry.metaState = event.getMetaState();
6117 keyEntry.repeatCount = event.getRepeatCount();
6118 keyEntry.downTime = event.getDownTime();
6119 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006120
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006121 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6122 ALOGD("Unhandled key event: Dispatching fallback key. "
6123 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6124 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6125 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006126 return true; // restart the event
6127 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006128 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6129 ALOGD("Unhandled key event: No fallback key.");
6130 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006131
6132 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006133 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006134 }
6135 }
6136 return false;
6137}
6138
Prabir Pradhancef936d2021-07-21 16:17:52 +00006139bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006140 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006141 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006142 return false;
6143}
6144
Michael Wrightd02c5b62014-02-10 15:10:22 -08006145void InputDispatcher::traceInboundQueueLengthLocked() {
6146 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006147 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006148 }
6149}
6150
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006151void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006152 if (ATRACE_ENABLED()) {
6153 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006154 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6155 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006156 }
6157}
6158
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006159void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006160 if (ATRACE_ENABLED()) {
6161 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006162 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6163 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006164 }
6165}
6166
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006167void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006168 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006169
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006170 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006171 dumpDispatchStateLocked(dump);
6172
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006173 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006174 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006175 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006176 }
6177}
6178
6179void InputDispatcher::monitor() {
6180 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006181 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006182 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006183 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006184}
6185
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006186/**
6187 * Wake up the dispatcher and wait until it processes all events and commands.
6188 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6189 * this method can be safely called from any thread, as long as you've ensured that
6190 * the work you are interested in completing has already been queued.
6191 */
6192bool InputDispatcher::waitForIdle() {
6193 /**
6194 * Timeout should represent the longest possible time that a device might spend processing
6195 * events and commands.
6196 */
6197 constexpr std::chrono::duration TIMEOUT = 100ms;
6198 std::unique_lock lock(mLock);
6199 mLooper->wake();
6200 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6201 return result == std::cv_status::no_timeout;
6202}
6203
Vishnu Naire798b472020-07-23 13:52:21 -07006204/**
6205 * Sets focus to the window identified by the token. This must be called
6206 * after updating any input window handles.
6207 *
6208 * Params:
6209 * request.token - input channel token used to identify the window that should gain focus.
6210 * request.focusedToken - the token that the caller expects currently to be focused. If the
6211 * specified token does not match the currently focused window, this request will be dropped.
6212 * If the specified focused token matches the currently focused window, the call will succeed.
6213 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6214 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6215 * when requesting the focus change. This determines which request gets
6216 * precedence if there is a focus change request from another source such as pointer down.
6217 */
Vishnu Nair958da932020-08-21 17:12:37 -07006218void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6219 { // acquire lock
6220 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006221 std::optional<FocusResolver::FocusChanges> changes =
6222 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6223 if (changes) {
6224 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006225 }
6226 } // release lock
6227 // Wake up poll loop since it may need to make new input dispatching choices.
6228 mLooper->wake();
6229}
6230
Vishnu Nairc519ff72021-01-21 08:23:08 -08006231void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6232 if (changes.oldFocus) {
6233 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006234 if (focusedInputChannel) {
6235 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6236 "focus left window");
6237 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006238 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006239 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006240 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006241 if (changes.newFocus) {
6242 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006243 }
6244
Prabir Pradhan99987712020-11-10 18:43:05 -08006245 // If a window has pointer capture, then it must have focus. We need to ensure that this
6246 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6247 // If the window loses focus before it loses pointer capture, then the window can be in a state
6248 // where it has pointer capture but not focus, violating the contract. Therefore we must
6249 // dispatch the pointer capture event before the focus event. Since focus events are added to
6250 // the front of the queue (above), we add the pointer capture event to the front of the queue
6251 // after the focus events are added. This ensures the pointer capture event ends up at the
6252 // front.
6253 disablePointerCaptureForcedLocked();
6254
Vishnu Nairc519ff72021-01-21 08:23:08 -08006255 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006256 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006257 }
6258}
Vishnu Nair958da932020-08-21 17:12:37 -07006259
Prabir Pradhan99987712020-11-10 18:43:05 -08006260void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006261 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006262 return;
6263 }
6264
6265 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6266
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006267 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006268 setPointerCaptureLocked(false);
6269 }
6270
6271 if (!mWindowTokenWithPointerCapture) {
6272 // No need to send capture changes because no window has capture.
6273 return;
6274 }
6275
6276 if (mPendingEvent != nullptr) {
6277 // Move the pending event to the front of the queue. This will give the chance
6278 // for the pending event to be dropped if it is a captured event.
6279 mInboundQueue.push_front(mPendingEvent);
6280 mPendingEvent = nullptr;
6281 }
6282
6283 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006284 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006285 mInboundQueue.push_front(std::move(entry));
6286}
6287
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006288void InputDispatcher::setPointerCaptureLocked(bool enable) {
6289 mCurrentPointerCaptureRequest.enable = enable;
6290 mCurrentPointerCaptureRequest.seq++;
6291 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006292 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006293 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006294 };
6295 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006296}
6297
Vishnu Nair599f1412021-06-21 10:39:58 -07006298void InputDispatcher::displayRemoved(int32_t displayId) {
6299 { // acquire lock
6300 std::scoped_lock _l(mLock);
6301 // Set an empty list to remove all handles from the specific display.
6302 setInputWindowsLocked(/* window handles */ {}, displayId);
6303 setFocusedApplicationLocked(displayId, nullptr);
6304 // Call focus resolver to clean up stale requests. This must be called after input windows
6305 // have been removed for the removed display.
6306 mFocusResolver.displayRemoved(displayId);
Christine Franksb768bb42021-11-29 12:11:31 -08006307 // Reset pointer capture eligibility, regardless of previous state.
6308 std::erase(mIneligibleDisplaysForPointerCapture, displayId);
Vishnu Nair599f1412021-06-21 10:39:58 -07006309 } // release lock
6310
6311 // Wake up poll loop since it may need to make new input dispatching choices.
6312 mLooper->wake();
6313}
6314
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006315void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6316 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006317 // The listener sends the windows as a flattened array. Separate the windows by display for
6318 // more convenient parsing.
6319 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006320 for (const auto& info : windowInfos) {
6321 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6322 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6323 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006324
6325 { // acquire lock
6326 std::scoped_lock _l(mLock);
6327 mDisplayInfos.clear();
6328 for (const auto& displayInfo : displayInfos) {
6329 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6330 }
6331
6332 for (const auto& [displayId, handles] : handlesPerDisplay) {
6333 setInputWindowsLocked(handles, displayId);
6334 }
6335 }
6336 // Wake up poll loop since it may need to make new input dispatching choices.
6337 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006338}
6339
Vishnu Nair062a8672021-09-03 16:07:44 -07006340bool InputDispatcher::shouldDropInput(
6341 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006342 if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
6343 (windowHandle->getInfo()->inputConfig.test(
6344 WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
Vishnu Nair062a8672021-09-03 16:07:44 -07006345 isWindowObscuredLocked(windowHandle))) {
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006346 ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
6347 "display %" PRId32 ".",
Vishnu Nair062a8672021-09-03 16:07:44 -07006348 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
Prabir Pradhan51e7db02022-02-07 06:02:57 -08006349 windowHandle->getInfo()->inputConfig.string().c_str(),
Vishnu Nair062a8672021-09-03 16:07:44 -07006350 windowHandle->getInfo()->displayId);
6351 return true;
6352 }
6353 return false;
6354}
6355
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006356void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6357 const std::vector<gui::WindowInfo>& windowInfos,
6358 const std::vector<DisplayInfo>& displayInfos) {
6359 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6360}
6361
Arthur Hungdfd528e2021-12-08 13:23:04 +00006362void InputDispatcher::cancelCurrentTouch() {
6363 {
6364 std::scoped_lock _l(mLock);
6365 ALOGD("Canceling all ongoing pointer gestures on all displays.");
6366 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
6367 "cancel current touch");
6368 synthesizeCancelationEventsForAllConnectionsLocked(options);
6369
6370 mTouchStatesByDisplay.clear();
6371 mLastHoverWindowHandle.clear();
6372 }
6373 // Wake up poll loop since there might be work to do.
6374 mLooper->wake();
6375}
6376
Prabir Pradhan1376fcd2022-01-21 09:56:35 -08006377void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
6378 std::scoped_lock _l(mLock);
6379 mMonitorDispatchingTimeout = timeout;
6380}
6381
Garfield Tane84e6f92019-08-29 17:28:41 -07006382} // namespace android::inputdispatcher