blob: ea5799a4ced14c0063fb62ab53ca7c1775cf9ba5 [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
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -070022#include <InputFlingerProperties.sysprop.h>
Michael Wright2b3c3302018-03-02 17:19:13 +000023#include <android-base/chrono_utils.h>
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080024#include <android-base/properties.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080025#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050026#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070027#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100028#include <binder/IServiceManager.h>
29#include <com/android/internal/compat/IPlatformCompatNative.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080030#include <ftl/enum.h>
chaviw15fab6f2021-06-07 14:15:52 -050031#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080032#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070033#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000034#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070035#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010036#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070037#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080038
Michael Wright44753b12020-07-08 13:48:11 +010039#include <cerrno>
40#include <cinttypes>
41#include <climits>
42#include <cstddef>
43#include <ctime>
44#include <queue>
45#include <sstream>
46
47#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070048#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010049
Michael Wrightd02c5b62014-02-10 15:10:22 -080050#define INDENT " "
51#define INDENT2 " "
52#define INDENT3 " "
53#define INDENT4 " "
54
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080055using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000056using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080057using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070058using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050059using android::gui::FocusRequest;
60using android::gui::TouchOcclusionMode;
61using android::gui::WindowInfo;
62using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080063using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100064using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080065using android::os::InputEventInjectionResult;
66using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100067using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080068
Garfield Tane84e6f92019-08-29 17:28:41 -070069namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080070
Prabir Pradhancef936d2021-07-21 16:17:52 +000071namespace {
72
Prabir Pradhan61a5d242021-07-26 16:41:09 +000073// Log detailed debug messages about each inbound event notification to the dispatcher.
74constexpr bool DEBUG_INBOUND_EVENT_DETAILS = false;
75
76// Log detailed debug messages about each outbound event processed by the dispatcher.
77constexpr bool DEBUG_OUTBOUND_EVENT_DETAILS = false;
78
79// Log debug messages about the dispatch cycle.
80constexpr bool DEBUG_DISPATCH_CYCLE = false;
81
82// Log debug messages about channel creation
83constexpr bool DEBUG_CHANNEL_CREATION = false;
84
85// Log debug messages about input event injection.
86constexpr bool DEBUG_INJECTION = false;
87
88// Log debug messages about input focus tracking.
89constexpr bool DEBUG_FOCUS = false;
90
Antonio Kantekf16f2832021-09-28 04:39:20 +000091// Log debug messages about touch mode event
92constexpr bool DEBUG_TOUCH_MODE = false;
93
Prabir Pradhan61a5d242021-07-26 16:41:09 +000094// Log debug messages about touch occlusion
95// STOPSHIP(b/169067926): Set to false
96constexpr bool DEBUG_TOUCH_OCCLUSION = true;
97
98// Log debug messages about the app switch latency optimization.
99constexpr bool DEBUG_APP_SWITCH = false;
100
101// Log debug messages about hover events.
102constexpr bool DEBUG_HOVER = false;
103
Prabir Pradhancef936d2021-07-21 16:17:52 +0000104// Temporarily releases a held mutex for the lifetime of the instance.
105// Named to match std::scoped_lock
106class scoped_unlock {
107public:
108 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
109 ~scoped_unlock() { mMutex.lock(); }
110
111private:
112 std::mutex& mMutex;
113};
114
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700115// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
116// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000117bool isPerWindowInputRotationEnabled() {
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700118 static const bool PER_WINDOW_INPUT_ROTATION =
Prabir Pradhan9c2d28c2021-09-29 17:42:14 +0000119 sysprop::InputFlingerProperties::per_window_input_rotation().value_or(true);
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -0700120
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700121 return PER_WINDOW_INPUT_ROTATION;
122}
123
Michael Wrightd02c5b62014-02-10 15:10:22 -0800124// Default input dispatching timeout if there is no focused application or paused window
125// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800126const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
127 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
128 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800129
130// Amount of time to allow for all pending events to be processed when an app switch
131// key is on the way. This is used to preempt input dispatch and drop input events
132// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000133constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134
135// Amount of time to allow for an event to be dispatched (measured since its eventTime)
136// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000137constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800138
Michael Wrightd02c5b62014-02-10 15:10:22 -0800139// 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 +0000140constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
141
142// Log a warning when an interception call takes longer than this to process.
143constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800144
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700145// Additional key latency in case a connection is still processing some motion events.
146// This will help with the case when a user touched a button that opens a new window,
147// and gives us the chance to dispatch the key to this new window.
148constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
149
Michael Wrightd02c5b62014-02-10 15:10:22 -0800150// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000151constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
152
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000153// Event log tags. See EventLogTags.logtags for reference
154constexpr int LOGTAG_INPUT_INTERACTION = 62000;
155constexpr int LOGTAG_INPUT_FOCUS = 62001;
156
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000157inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800158 return systemTime(SYSTEM_TIME_MONOTONIC);
159}
160
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000161inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800162 return value ? "true" : "false";
163}
164
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000165inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000166 if (binder == nullptr) {
167 return "<null>";
168 }
169 return StringPrintf("%p", binder.get());
170}
171
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000172inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700173 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
174 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175}
176
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000177bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800178 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700179 case AKEY_EVENT_ACTION_DOWN:
180 case AKEY_EVENT_ACTION_UP:
181 return true;
182 default:
183 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800184 }
185}
186
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000187bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700188 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800189 ALOGE("Key event has invalid action code 0x%x", action);
190 return false;
191 }
192 return true;
193}
194
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000195bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800196 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700197 case AMOTION_EVENT_ACTION_DOWN:
198 case AMOTION_EVENT_ACTION_UP:
199 case AMOTION_EVENT_ACTION_CANCEL:
200 case AMOTION_EVENT_ACTION_MOVE:
201 case AMOTION_EVENT_ACTION_OUTSIDE:
202 case AMOTION_EVENT_ACTION_HOVER_ENTER:
203 case AMOTION_EVENT_ACTION_HOVER_MOVE:
204 case AMOTION_EVENT_ACTION_HOVER_EXIT:
205 case AMOTION_EVENT_ACTION_SCROLL:
206 return true;
207 case AMOTION_EVENT_ACTION_POINTER_DOWN:
208 case AMOTION_EVENT_ACTION_POINTER_UP: {
209 int32_t index = getMotionEventActionPointerIndex(action);
210 return index >= 0 && index < pointerCount;
211 }
212 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
213 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
214 return actionButton != 0;
215 default:
216 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800217 }
218}
219
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000220int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500221 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
222}
223
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000224bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
225 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700226 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 ALOGE("Motion event has invalid action code 0x%x", action);
228 return false;
229 }
230 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000231 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700232 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800233 return false;
234 }
235 BitSet32 pointerIdBits;
236 for (size_t i = 0; i < pointerCount; i++) {
237 int32_t id = pointerProperties[i].id;
238 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700239 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
240 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800241 return false;
242 }
243 if (pointerIdBits.hasBit(id)) {
244 ALOGE("Motion event has duplicate pointer id %d", id);
245 return false;
246 }
247 pointerIdBits.markBit(id);
248 }
249 return true;
250}
251
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000252std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800253 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000254 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800255 }
256
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000257 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800258 bool first = true;
259 Region::const_iterator cur = region.begin();
260 Region::const_iterator const tail = region.end();
261 while (cur != tail) {
262 if (first) {
263 first = false;
264 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800265 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800266 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800267 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800268 cur++;
269 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000270 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800271}
272
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000273std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500274 constexpr size_t maxEntries = 50; // max events to print
275 constexpr size_t skipBegin = maxEntries / 2;
276 const size_t skipEnd = queue.size() - maxEntries / 2;
277 // skip from maxEntries / 2 ... size() - maxEntries/2
278 // only print from 0 .. skipBegin and then from skipEnd .. size()
279
280 std::string dump;
281 for (size_t i = 0; i < queue.size(); i++) {
282 const DispatchEntry& entry = *queue[i];
283 if (i >= skipBegin && i < skipEnd) {
284 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
285 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
286 continue;
287 }
288 dump.append(INDENT4);
289 dump += entry.eventEntry->getDescription();
290 dump += StringPrintf(", seq=%" PRIu32
291 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
292 entry.seq, entry.targetFlags, entry.resolvedAction,
293 ns2ms(currentTime - entry.eventEntry->eventTime));
294 if (entry.deliveryTime != 0) {
295 // This entry was delivered, so add information on how long we've been waiting
296 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
297 }
298 dump.append("\n");
299 }
300 return dump;
301}
302
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700303/**
304 * Find the entry in std::unordered_map by key, and return it.
305 * If the entry is not found, return a default constructed entry.
306 *
307 * Useful when the entries are vectors, since an empty vector will be returned
308 * if the entry is not found.
309 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
310 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700311template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000312V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700313 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700314 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800315}
316
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000317bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700318 if (first == second) {
319 return true;
320 }
321
322 if (first == nullptr || second == nullptr) {
323 return false;
324 }
325
326 return first->getToken() == second->getToken();
327}
328
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000329bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000330 if (first == nullptr || second == nullptr) {
331 return false;
332 }
333 return first->applicationInfo.token != nullptr &&
334 first->applicationInfo.token == second->applicationInfo.token;
335}
336
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000337bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800338 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
339}
340
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000341std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
342 std::shared_ptr<EventEntry> eventEntry,
343 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900344 if (eventEntry->type == EventEntry::Type::MOTION) {
345 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhan664834b2021-05-20 16:00:42 -0700346 if ((motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) ||
347 (motionEntry.source & AINPUT_SOURCE_CLASS_POSITION)) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900348 const ui::Transform identityTransform;
Prabir Pradhan664834b2021-05-20 16:00:42 -0700349 // Use identity transform for joystick and position-based (touchpad) events because they
350 // don't depend on the window transform.
yunho.shinf4a80b82020-11-16 21:13:57 +0900351 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700352 identityTransform, 1.0f /*globalScaleFactor*/);
yunho.shinf4a80b82020-11-16 21:13:57 +0900353 }
354 }
355
chaviw1ff3d1e2020-07-01 15:53:47 -0700356 if (inputTarget.useDefaultPointerTransform()) {
357 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700358 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700359 inputTarget.displayTransform,
360 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000361 }
362
363 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
364 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
365
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700366 std::vector<PointerCoords> pointerCoords;
367 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000368
369 // Use the first pointer information to normalize all other pointers. This could be any pointer
370 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700371 // uses the transform for the normalized pointer.
372 const ui::Transform& firstPointerTransform =
373 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
374 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000375
376 // Iterate through all pointers in the event to normalize against the first.
377 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
378 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
379 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700380 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000381
382 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700383 // First, apply the current pointer's transform to update the coordinates into
384 // window space.
385 pointerCoords[pointerIndex].transform(currTransform);
386 // Next, apply the inverse transform of the normalized coordinates so the
387 // current coordinates are transformed into the normalized coordinate space.
388 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000389 }
390
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700391 std::unique_ptr<MotionEntry> combinedMotionEntry =
392 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
393 motionEntry.deviceId, motionEntry.source,
394 motionEntry.displayId, motionEntry.policyFlags,
395 motionEntry.action, motionEntry.actionButton,
396 motionEntry.flags, motionEntry.metaState,
397 motionEntry.buttonState, motionEntry.classification,
398 motionEntry.edgeFlags, motionEntry.xPrecision,
399 motionEntry.yPrecision, motionEntry.xCursorPosition,
400 motionEntry.yCursorPosition, motionEntry.downTime,
401 motionEntry.pointerCount, motionEntry.pointerProperties,
402 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000403
404 if (motionEntry.injectionState) {
405 combinedMotionEntry->injectionState = motionEntry.injectionState;
406 combinedMotionEntry->injectionState->refCount += 1;
407 }
408
409 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700410 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700411 firstPointerTransform, inputTarget.displayTransform,
412 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000413 return dispatchEntry;
414}
415
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000416status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
417 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700418 std::unique_ptr<InputChannel> uniqueServerChannel;
419 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
420
421 serverChannel = std::move(uniqueServerChannel);
422 return result;
423}
424
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500425template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000426bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500427 if (lhs == nullptr && rhs == nullptr) {
428 return true;
429 }
430 if (lhs == nullptr || rhs == nullptr) {
431 return false;
432 }
433 return *lhs == *rhs;
434}
435
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000436sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000437 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
438 if (service == nullptr) {
439 ALOGE("Failed to link to compat service");
440 return nullptr;
441 }
442 return interface_cast<IPlatformCompatNative>(service);
443}
444
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000445KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000446 KeyEvent event;
447 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
448 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
449 entry.repeatCount, entry.downTime, entry.eventTime);
450 return event;
451}
452
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000453std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000454 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
455 const sp<IBinder>& token) {
456 for (const auto& it : monitorsByDisplay) {
457 const std::vector<Monitor>& monitors = it.second;
458 for (const Monitor& monitor : monitors) {
459 if (monitor.inputChannel->getConnectionToken() == token) {
460 return monitor.pid;
461 }
462 }
463 }
464 return std::nullopt;
465}
466
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000467bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000468 // Do not keep track of gesture monitors. They receive every event and would disproportionately
469 // affect the statistics.
470 if (connection.monitor) {
471 return false;
472 }
473 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
474 if (!connection.responsive) {
475 return false;
476 }
477 return true;
478}
479
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000480bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000481 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
482 const int32_t& inputEventId = eventEntry.id;
483 if (inputEventId != dispatchEntry.resolvedEventId) {
484 // Event was transmuted
485 return false;
486 }
487 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
488 return false;
489 }
490 // Only track latency for events that originated from hardware
491 if (eventEntry.isSynthesized()) {
492 return false;
493 }
494 const EventEntry::Type& inputEventEntryType = eventEntry.type;
495 if (inputEventEntryType == EventEntry::Type::KEY) {
496 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
497 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
498 return false;
499 }
500 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
501 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
502 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
503 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
504 return false;
505 }
506 } else {
507 // Not a key or a motion
508 return false;
509 }
510 if (!shouldReportMetricsForConnection(connection)) {
511 return false;
512 }
513 return true;
514}
515
Prabir Pradhancef936d2021-07-21 16:17:52 +0000516/**
517 * Connection is responsive if it has no events in the waitQueue that are older than the
518 * current time.
519 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000520bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000521 const nsecs_t currentTime = now();
522 for (const DispatchEntry* entry : connection.waitQueue) {
523 if (entry->timeoutTime < currentTime) {
524 return false;
525 }
526 }
527 return true;
528}
529
Prabir Pradhan81420cc2021-09-06 10:28:50 -0700530bool isFromSource(uint32_t source, uint32_t test) {
531 return (source & test) == test;
532}
533
534vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float y) {
535 const vec2 transformedXy = transform.transform(x, y);
536 const vec2 transformedOrigin = transform.transform(0, 0);
537 return transformedXy - transformedOrigin;
538}
539
Antonio Kantekf16f2832021-09-28 04:39:20 +0000540// Returns true if the event type passed as argument represents a user activity.
541bool isUserActivityEvent(const EventEntry& eventEntry) {
542 switch (eventEntry.type) {
543 case EventEntry::Type::FOCUS:
544 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
545 case EventEntry::Type::DRAG:
546 case EventEntry::Type::TOUCH_MODE_CHANGED:
547 case EventEntry::Type::SENSOR:
548 case EventEntry::Type::CONFIGURATION_CHANGED:
549 return false;
550 case EventEntry::Type::DEVICE_RESET:
551 case EventEntry::Type::KEY:
552 case EventEntry::Type::MOTION:
553 return true;
554 }
555}
556
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000557} // namespace
558
Michael Wrightd02c5b62014-02-10 15:10:22 -0800559// --- InputDispatcher ---
560
Garfield Tan00f511d2019-06-12 16:55:40 -0700561InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
562 : mPolicy(policy),
563 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700564 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800565 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700566 mAppSwitchSawKeyDown(false),
567 mAppSwitchDueTime(LONG_LONG_MAX),
568 mNextUnblockedEvent(nullptr),
569 mDispatchEnabled(false),
570 mDispatchFrozen(false),
571 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800572 // mInTouchMode will be initialized by the WindowManager to the default device config.
573 // To avoid leaking stack in case that call never comes, and for tests,
574 // initialize it here anyways.
Antonio Kantekf16f2832021-09-28 04:39:20 +0000575 mInTouchMode(kDefaultInTouchMode),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100576 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000577 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800578 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000579 mLatencyAggregator(),
580 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000581 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800582 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800583 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800584
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700585 mWindowInfoListener = new DispatcherWindowListener(*this);
586 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
587
Yi Kong9b14ac62018-07-17 13:48:38 -0700588 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589
590 policy->getDispatcherConfiguration(&mConfig);
591}
592
593InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000594 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800595
Prabir Pradhancef936d2021-07-21 16:17:52 +0000596 resetKeyRepeatLocked();
597 releasePendingEventLocked();
598 drainInboundQueueLocked();
599 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800600
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000601 while (!mConnectionsByToken.empty()) {
602 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000603 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
604 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800605 }
606}
607
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700608status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700609 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700610 return ALREADY_EXISTS;
611 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700612 mThread = std::make_unique<InputThread>(
613 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
614 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700615}
616
617status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700618 if (mThread && mThread->isCallingThread()) {
619 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700620 return INVALID_OPERATION;
621 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700622 mThread.reset();
623 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700624}
625
Michael Wrightd02c5b62014-02-10 15:10:22 -0800626void InputDispatcher::dispatchOnce() {
627 nsecs_t nextWakeupTime = LONG_LONG_MAX;
628 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800629 std::scoped_lock _l(mLock);
630 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800631
632 // Run a dispatch loop if there are no pending commands.
633 // The dispatch loop might enqueue commands to run afterwards.
634 if (!haveCommandsLocked()) {
635 dispatchOnceInnerLocked(&nextWakeupTime);
636 }
637
638 // Run all pending commands if there are any.
639 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000640 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641 nextWakeupTime = LONG_LONG_MIN;
642 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800643
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700644 // If we are still waiting for ack on some events,
645 // we might have to wake up earlier to check if an app is anr'ing.
646 const nsecs_t nextAnrCheck = processAnrsLocked();
647 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
648
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800649 // We are about to enter an infinitely long sleep, because we have no commands or
650 // pending or queued events
651 if (nextWakeupTime == LONG_LONG_MAX) {
652 mDispatcherEnteredIdle.notify_all();
653 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800654 } // release lock
655
656 // Wait for callback or timeout or wake. (make sure we round up, not down)
657 nsecs_t currentTime = now();
658 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
659 mLooper->pollOnce(timeoutMillis);
660}
661
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700662/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500663 * Raise ANR if there is no focused window.
664 * Before the ANR is raised, do a final state check:
665 * 1. The currently focused application must be the same one we are waiting for.
666 * 2. Ensure we still don't have a focused window.
667 */
668void InputDispatcher::processNoFocusedWindowAnrLocked() {
669 // Check if the application that we are waiting for is still focused.
670 std::shared_ptr<InputApplicationHandle> focusedApplication =
671 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
672 if (focusedApplication == nullptr ||
673 focusedApplication->getApplicationToken() !=
674 mAwaitedFocusedApplication->getApplicationToken()) {
675 // Unexpected because we should have reset the ANR timer when focused application changed
676 ALOGE("Waited for a focused window, but focused application has already changed to %s",
677 focusedApplication->getName().c_str());
678 return; // The focused application has changed.
679 }
680
chaviw98318de2021-05-19 16:45:23 -0500681 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500682 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
683 if (focusedWindowHandle != nullptr) {
684 return; // We now have a focused window. No need for ANR.
685 }
686 onAnrLocked(mAwaitedFocusedApplication);
687}
688
689/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700690 * Check if any of the connections' wait queues have events that are too old.
691 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
692 * Return the time at which we should wake up next.
693 */
694nsecs_t InputDispatcher::processAnrsLocked() {
695 const nsecs_t currentTime = now();
696 nsecs_t nextAnrCheck = LONG_LONG_MAX;
697 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
698 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
699 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500700 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700701 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500702 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700703 return LONG_LONG_MIN;
704 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500705 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700706 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
707 }
708 }
709
710 // Check if any connection ANRs are due
711 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
712 if (currentTime < nextAnrCheck) { // most likely scenario
713 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
714 }
715
716 // If we reached here, we have an unresponsive connection.
717 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
718 if (connection == nullptr) {
719 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
720 return nextAnrCheck;
721 }
722 connection->responsive = false;
723 // Stop waking up for this unresponsive connection
724 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000725 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700726 return LONG_LONG_MIN;
727}
728
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500729std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500730 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700731 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500732 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700733 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500734 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700735}
736
Michael Wrightd02c5b62014-02-10 15:10:22 -0800737void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
738 nsecs_t currentTime = now();
739
Jeff Browndc5992e2014-04-11 01:27:26 -0700740 // Reset the key repeat timer whenever normal dispatch is suspended while the
741 // device is in a non-interactive state. This is to ensure that we abort a key
742 // repeat if the device is just coming out of sleep.
743 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800744 resetKeyRepeatLocked();
745 }
746
747 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
748 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100749 if (DEBUG_FOCUS) {
750 ALOGD("Dispatch frozen. Waiting some more.");
751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800752 return;
753 }
754
755 // Optimize latency of app switches.
756 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
757 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
758 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
759 if (mAppSwitchDueTime < *nextWakeupTime) {
760 *nextWakeupTime = mAppSwitchDueTime;
761 }
762
763 // Ready to start a new event.
764 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700765 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700766 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800767 if (isAppSwitchDue) {
768 // The inbound queue is empty so the app switch key we were waiting
769 // for will never arrive. Stop waiting for it.
770 resetPendingAppSwitchLocked(false);
771 isAppSwitchDue = false;
772 }
773
774 // Synthesize a key repeat if appropriate.
775 if (mKeyRepeatState.lastKeyEntry) {
776 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
777 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
778 } else {
779 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
780 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
781 }
782 }
783 }
784
785 // Nothing to do if there is no pending event.
786 if (!mPendingEvent) {
787 return;
788 }
789 } else {
790 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700791 mPendingEvent = mInboundQueue.front();
792 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800793 traceInboundQueueLengthLocked();
794 }
795
796 // Poke user activity for this event.
797 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700798 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800799 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800800 }
801
802 // Now we have an event to dispatch.
803 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700804 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800805 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700806 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800807 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700808 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800809 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700810 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800811 }
812
813 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700814 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815 }
816
817 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700818 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700819 const ConfigurationChangedEntry& typedEntry =
820 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700821 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700822 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700823 break;
824 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800825
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700826 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700827 const DeviceResetEntry& typedEntry =
828 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700829 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700830 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700831 break;
832 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800833
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100834 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700835 std::shared_ptr<FocusEntry> typedEntry =
836 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100837 dispatchFocusLocked(currentTime, typedEntry);
838 done = true;
839 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
840 break;
841 }
842
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700843 case EventEntry::Type::TOUCH_MODE_CHANGED: {
844 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
845 dispatchTouchModeChangeLocked(currentTime, typedEntry);
846 done = true;
847 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
848 break;
849 }
850
Prabir Pradhan99987712020-11-10 18:43:05 -0800851 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
852 const auto typedEntry =
853 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
854 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
855 done = true;
856 break;
857 }
858
arthurhungb89ccb02020-12-30 16:19:01 +0800859 case EventEntry::Type::DRAG: {
860 std::shared_ptr<DragEntry> typedEntry =
861 std::static_pointer_cast<DragEntry>(mPendingEvent);
862 dispatchDragLocked(currentTime, typedEntry);
863 done = true;
864 break;
865 }
866
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700867 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700868 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700869 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700870 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700871 resetPendingAppSwitchLocked(true);
872 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700873 } else if (dropReason == DropReason::NOT_DROPPED) {
874 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 }
876 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700877 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700878 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700879 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700880 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
881 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700882 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700883 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700884 break;
885 }
886
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700887 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700888 std::shared_ptr<MotionEntry> motionEntry =
889 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700890 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
891 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700893 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700894 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700895 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700896 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
897 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700898 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700899 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700900 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800901 }
Chris Yef59a2f42020-10-16 12:55:26 -0700902
903 case EventEntry::Type::SENSOR: {
904 std::shared_ptr<SensorEntry> sensorEntry =
905 std::static_pointer_cast<SensorEntry>(mPendingEvent);
906 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
907 dropReason = DropReason::APP_SWITCH;
908 }
909 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
910 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
911 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
912 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
913 dropReason = DropReason::STALE;
914 }
915 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
916 done = true;
917 break;
918 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800919 }
920
921 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700922 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700923 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800924 }
Michael Wright3a981722015-06-10 15:26:13 +0100925 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800926
927 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700928 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800929 }
930}
931
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700932/**
933 * Return true if the events preceding this incoming motion event should be dropped
934 * Return false otherwise (the default behaviour)
935 */
936bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700937 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700938 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700939
940 // Optimize case where the current application is unresponsive and the user
941 // decides to touch a window in a different application.
942 // If the application takes too long to catch up then we drop all events preceding
943 // the touch into the other window.
944 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700945 int32_t displayId = motionEntry.displayId;
946 int32_t x = static_cast<int32_t>(
947 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
948 int32_t y = static_cast<int32_t>(
949 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500950 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700951 findTouchedWindowAtLocked(displayId, x, y, nullptr);
952 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700953 touchedWindowHandle->getApplicationToken() !=
954 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700955 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700956 ALOGI("Pruning input queue because user touched a different application while waiting "
957 "for %s",
958 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700959 return true;
960 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700961
962 // Alternatively, maybe there's a gesture monitor that could handle this event
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700963 for (const auto& monitor : getValueByKey(mGestureMonitorsByDisplay, displayId)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700964 sp<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700965 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000966 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700967 // This monitor could take more input. Drop all events preceding this
968 // event, so that gesture monitor could get a chance to receive the stream
969 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
970 "responsive gesture monitor that may handle the event",
971 mAwaitedFocusedApplication->getName().c_str());
972 return true;
973 }
974 }
975 }
976
977 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
978 // yet been processed by some connections, the dispatcher will wait for these motion
979 // events to be processed before dispatching the key event. This is because these motion events
980 // may cause a new window to be launched, which the user might expect to receive focus.
981 // To prevent waiting forever for such events, just send the key to the currently focused window
982 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
983 ALOGD("Received a new pointer down event, stop waiting for events to process and "
984 "just send the pending key event to the focused window.");
985 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700986 }
987 return false;
988}
989
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700990bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700991 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700992 mInboundQueue.push_back(std::move(newEntry));
993 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800994 traceInboundQueueLengthLocked();
995
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700996 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700997 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700998 // Optimize app switch latency.
999 // If the application takes too long to catch up then we drop all events preceding
1000 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001001 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001002 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001003 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001005 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001006 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001007 if (DEBUG_APP_SWITCH) {
1008 ALOGD("App switch is pending!");
1009 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001010 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001011 mAppSwitchSawKeyDown = false;
1012 needWake = true;
1013 }
1014 }
1015 }
1016 break;
1017 }
1018
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001019 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001020 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1021 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001022 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001023 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001024 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001025 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001026 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001027 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1028 break;
1029 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001030 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001031 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001032 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001033 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001034 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1035 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001036 // nothing to do
1037 break;
1038 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001039 }
1040
1041 return needWake;
1042}
1043
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001044void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001045 // Do not store sensor event in recent queue to avoid flooding the queue.
1046 if (entry->type != EventEntry::Type::SENSOR) {
1047 mRecentQueue.push_back(entry);
1048 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001049 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001050 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001051 }
1052}
1053
chaviw98318de2021-05-19 16:45:23 -05001054sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1055 int32_t y, TouchState* touchState,
1056 bool addOutsideTargets,
1057 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001058 if (addOutsideTargets && touchState == nullptr) {
1059 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001060 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001061 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001062 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1063 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001064 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001065 continue;
1066 }
chaviw98318de2021-05-19 16:45:23 -05001067 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001068 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001069 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001070
1071 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001072 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1073 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1074 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001075 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1076 // Found window.
1077 return windowHandle;
1078 }
1079 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001080
chaviw98318de2021-05-19 16:45:23 -05001081 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001082 touchState->addOrUpdateWindow(windowHandle,
1083 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1084 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001085 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001086 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001087 }
1088 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001089 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001090}
1091
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001092void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001093 const char* reason;
1094 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001095 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001096 if (DEBUG_INBOUND_EVENT_DETAILS) {
1097 ALOGD("Dropped event because policy consumed it.");
1098 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001099 reason = "inbound event was dropped because the policy consumed it";
1100 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001101 case DropReason::DISABLED:
1102 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001103 ALOGI("Dropped event because input dispatch is disabled.");
1104 }
1105 reason = "inbound event was dropped because input dispatch is disabled";
1106 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001107 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001108 ALOGI("Dropped event because of pending overdue app switch.");
1109 reason = "inbound event was dropped because of pending overdue app switch";
1110 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001111 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001112 ALOGI("Dropped event because the current application is not responding and the user "
1113 "has started interacting with a different application.");
1114 reason = "inbound event was dropped because the current application is not responding "
1115 "and the user has started interacting with a different application";
1116 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001117 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001118 ALOGI("Dropped event because it is stale.");
1119 reason = "inbound event was dropped because it is stale";
1120 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001121 case DropReason::NO_POINTER_CAPTURE:
1122 ALOGI("Dropped event because there is no window with Pointer Capture.");
1123 reason = "inbound event was dropped because there is no window with Pointer Capture";
1124 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001125 case DropReason::NOT_DROPPED: {
1126 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001127 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001128 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129 }
1130
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001131 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001132 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001133 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1134 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001135 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001136 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001137 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001138 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1139 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001140 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1141 synthesizeCancelationEventsForAllConnectionsLocked(options);
1142 } else {
1143 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1144 synthesizeCancelationEventsForAllConnectionsLocked(options);
1145 }
1146 break;
1147 }
Chris Yef59a2f42020-10-16 12:55:26 -07001148 case EventEntry::Type::SENSOR: {
1149 break;
1150 }
arthurhungb89ccb02020-12-30 16:19:01 +08001151 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1152 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001153 break;
1154 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001155 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001156 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001157 case EventEntry::Type::CONFIGURATION_CHANGED:
1158 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001159 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001160 break;
1161 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162 }
1163}
1164
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001165static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001166 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1167 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001168}
1169
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001170bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1171 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1172 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1173 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001174}
1175
1176bool InputDispatcher::isAppSwitchPendingLocked() {
1177 return mAppSwitchDueTime != LONG_LONG_MAX;
1178}
1179
1180void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1181 mAppSwitchDueTime = LONG_LONG_MAX;
1182
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001183 if (DEBUG_APP_SWITCH) {
1184 if (handled) {
1185 ALOGD("App switch has arrived.");
1186 } else {
1187 ALOGD("App switch was abandoned.");
1188 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001189 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001190}
1191
Michael Wrightd02c5b62014-02-10 15:10:22 -08001192bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001193 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001194}
1195
Prabir Pradhancef936d2021-07-21 16:17:52 +00001196bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001197 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001198 return false;
1199 }
1200
1201 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001202 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001203 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001204 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1205 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001206 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207 return true;
1208}
1209
Prabir Pradhancef936d2021-07-21 16:17:52 +00001210void InputDispatcher::postCommandLocked(Command&& command) {
1211 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001212}
1213
1214void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001215 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001216 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001217 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001218 releaseInboundEventLocked(entry);
1219 }
1220 traceInboundQueueLengthLocked();
1221}
1222
1223void InputDispatcher::releasePendingEventLocked() {
1224 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001225 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001226 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001227 }
1228}
1229
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001230void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001231 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001232 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001233 if (DEBUG_DISPATCH_CYCLE) {
1234 ALOGD("Injected inbound event was dropped.");
1235 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001236 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001237 }
1238 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001239 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001240 }
1241 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242}
1243
1244void InputDispatcher::resetKeyRepeatLocked() {
1245 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001246 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247 }
1248}
1249
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001250std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1251 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001252
Michael Wright2e732952014-09-24 13:26:59 -07001253 uint32_t policyFlags = entry->policyFlags &
1254 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001256 std::shared_ptr<KeyEntry> newEntry =
1257 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1258 entry->source, entry->displayId, policyFlags, entry->action,
1259 entry->flags, entry->keyCode, entry->scanCode,
1260 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001261
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001262 newEntry->syntheticRepeat = true;
1263 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001265 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001266}
1267
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001268bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001269 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001270 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1271 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1272 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273
1274 // Reset key repeating in case a keyboard device was added or removed or something.
1275 resetKeyRepeatLocked();
1276
1277 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001278 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1279 scoped_unlock unlock(mLock);
1280 mPolicy->notifyConfigurationChanged(eventTime);
1281 };
1282 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001283 return true;
1284}
1285
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001286bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1287 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001288 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1289 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1290 entry.deviceId);
1291 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001292
liushenxiang42232912021-05-21 20:24:09 +08001293 // Reset key repeating in case a keyboard device was disabled or enabled.
1294 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1295 resetKeyRepeatLocked();
1296 }
1297
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001298 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001299 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001300 synthesizeCancelationEventsForAllConnectionsLocked(options);
1301 return true;
1302}
1303
Vishnu Nairad321cd2020-08-20 16:40:21 -07001304void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001305 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001306 if (mPendingEvent != nullptr) {
1307 // Move the pending event to the front of the queue. This will give the chance
1308 // for the pending event to get dispatched to the newly focused window
1309 mInboundQueue.push_front(mPendingEvent);
1310 mPendingEvent = nullptr;
1311 }
1312
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001313 std::unique_ptr<FocusEntry> focusEntry =
1314 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1315 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001316
1317 // This event should go to the front of the queue, but behind all other focus events
1318 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001319 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001320 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001321 [](const std::shared_ptr<EventEntry>& event) {
1322 return event->type == EventEntry::Type::FOCUS;
1323 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001324
1325 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001326 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001327}
1328
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001329void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001330 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001331 if (channel == nullptr) {
1332 return; // Window has gone away
1333 }
1334 InputTarget target;
1335 target.inputChannel = channel;
1336 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1337 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001338 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1339 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001340 std::string reason = std::string("reason=").append(entry->reason);
1341 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001342 dispatchEventLocked(currentTime, entry, {target});
1343}
1344
Prabir Pradhan99987712020-11-10 18:43:05 -08001345void InputDispatcher::dispatchPointerCaptureChangedLocked(
1346 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1347 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001348 dropReason = DropReason::NOT_DROPPED;
1349
Prabir Pradhan99987712020-11-10 18:43:05 -08001350 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001351 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001352
1353 if (entry->pointerCaptureRequest.enable) {
1354 // Enable Pointer Capture.
1355 if (haveWindowWithPointerCapture &&
1356 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1357 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1358 "to the window.");
1359 }
1360 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001361 // This can happen if a window requests capture and immediately releases capture.
1362 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001363 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001364 return;
1365 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001366 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1367 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1368 return;
1369 }
1370
Vishnu Nairc519ff72021-01-21 08:23:08 -08001371 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001372 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1373 mWindowTokenWithPointerCapture = token;
1374 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001375 // Disable Pointer Capture.
1376 // We do not check if the sequence number matches for requests to disable Pointer Capture
1377 // for two reasons:
1378 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1379 // to disable capture with the same sequence number: one generated by
1380 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1381 // Capture being disabled in InputReader.
1382 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1383 // actual Pointer Capture state that affects events being generated by input devices is
1384 // in InputReader.
1385 if (!haveWindowWithPointerCapture) {
1386 // Pointer capture was already forcefully disabled because of focus change.
1387 dropReason = DropReason::NOT_DROPPED;
1388 return;
1389 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001390 token = mWindowTokenWithPointerCapture;
1391 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001392 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001393 setPointerCaptureLocked(false);
1394 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001395 }
1396
1397 auto channel = getInputChannelLocked(token);
1398 if (channel == nullptr) {
1399 // Window has gone away, clean up Pointer Capture state.
1400 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001401 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001402 setPointerCaptureLocked(false);
1403 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001404 return;
1405 }
1406 InputTarget target;
1407 target.inputChannel = channel;
1408 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1409 entry->dispatchInProgress = true;
1410 dispatchEventLocked(currentTime, entry, {target});
1411
1412 dropReason = DropReason::NOT_DROPPED;
1413}
1414
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001415void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1416 const std::shared_ptr<TouchModeEntry>& entry) {
1417 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1418 getWindowHandlesLocked(mFocusedDisplayId);
1419 if (windowHandles.empty()) {
1420 return;
1421 }
1422 const std::vector<InputTarget> inputTargets =
1423 getInputTargetsFromWindowHandlesLocked(windowHandles);
1424 if (inputTargets.empty()) {
1425 return;
1426 }
1427 entry->dispatchInProgress = true;
1428 dispatchEventLocked(currentTime, entry, inputTargets);
1429}
1430
1431std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1432 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1433 std::vector<InputTarget> inputTargets;
1434 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1435 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1436 const sp<IBinder>& token = handle->getToken();
1437 if (token == nullptr) {
1438 continue;
1439 }
1440 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1441 if (channel == nullptr) {
1442 continue; // Window has gone away
1443 }
1444 InputTarget target;
1445 target.inputChannel = channel;
1446 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1447 inputTargets.push_back(target);
1448 }
1449 return inputTargets;
1450}
1451
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001452bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001453 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001454 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001455 if (!entry->dispatchInProgress) {
1456 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1457 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1458 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1459 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001460 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001461 // We have seen two identical key downs in a row which indicates that the device
1462 // driver is automatically generating key repeats itself. We take note of the
1463 // repeat here, but we disable our own next key repeat timer since it is clear that
1464 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001465 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1466 // Make sure we don't get key down from a different device. If a different
1467 // device Id has same key pressed down, the new device Id will replace the
1468 // current one to hold the key repeat with repeat count reset.
1469 // In the future when got a KEY_UP on the device id, drop it and do not
1470 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001471 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1472 resetKeyRepeatLocked();
1473 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1474 } else {
1475 // Not a repeat. Save key down state in case we do see a repeat later.
1476 resetKeyRepeatLocked();
1477 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1478 }
1479 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001480 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1481 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001482 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001483 if (DEBUG_INBOUND_EVENT_DETAILS) {
1484 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1485 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001486 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001487 resetKeyRepeatLocked();
1488 }
1489
1490 if (entry->repeatCount == 1) {
1491 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1492 } else {
1493 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1494 }
1495
1496 entry->dispatchInProgress = true;
1497
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001498 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 }
1500
1501 // Handle case where the policy asked us to try again later last time.
1502 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1503 if (currentTime < entry->interceptKeyWakeupTime) {
1504 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1505 *nextWakeupTime = entry->interceptKeyWakeupTime;
1506 }
1507 return false; // wait until next wakeup
1508 }
1509 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1510 entry->interceptKeyWakeupTime = 0;
1511 }
1512
1513 // Give the policy a chance to intercept the key.
1514 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1515 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001516 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001517 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001518
1519 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1520 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1521 };
1522 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001523 return false; // wait for the command to run
1524 } else {
1525 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1526 }
1527 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001528 if (*dropReason == DropReason::NOT_DROPPED) {
1529 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001530 }
1531 }
1532
1533 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001534 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001535 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001536 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1537 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001538 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001539 return true;
1540 }
1541
1542 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001543 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001544 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001545 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001546 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001547 return false;
1548 }
1549
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001550 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001551 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552 return true;
1553 }
1554
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001555 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001556 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001557
1558 // Dispatch the key.
1559 dispatchEventLocked(currentTime, entry, inputTargets);
1560 return true;
1561}
1562
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001563void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001564 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1565 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1566 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1567 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1568 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1569 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1570 entry.metaState, entry.repeatCount, entry.downTime);
1571 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001572}
1573
Prabir Pradhancef936d2021-07-21 16:17:52 +00001574void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1575 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001576 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001577 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1578 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1579 "source=0x%x, sensorType=%s",
1580 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001581 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001582 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001583 auto command = [this, entry]() REQUIRES(mLock) {
1584 scoped_unlock unlock(mLock);
1585
1586 if (entry->accuracyChanged) {
1587 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1588 }
1589 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1590 entry->hwTimestamp, entry->values);
1591 };
1592 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001593}
1594
1595bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001596 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1597 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001598 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001599 }
Chris Yef59a2f42020-10-16 12:55:26 -07001600 { // acquire lock
1601 std::scoped_lock _l(mLock);
1602
1603 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1604 std::shared_ptr<EventEntry> entry = *it;
1605 if (entry->type == EventEntry::Type::SENSOR) {
1606 it = mInboundQueue.erase(it);
1607 releaseInboundEventLocked(entry);
1608 }
1609 }
1610 }
1611 return true;
1612}
1613
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001614bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001615 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001616 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001617 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001618 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001619 entry->dispatchInProgress = true;
1620
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001621 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001622 }
1623
1624 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001625 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001626 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001627 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1628 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001629 return true;
1630 }
1631
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001632 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633
1634 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001635 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001636
1637 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001638 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639 if (isPointerEvent) {
1640 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001641 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001642 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001643 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001644 } else {
1645 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001646 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001647 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001648 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001649 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650 return false;
1651 }
1652
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001653 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001654 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001655 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1656 return true;
1657 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001658 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001659 CancelationOptions::Mode mode(isPointerEvent
1660 ? CancelationOptions::CANCEL_POINTER_EVENTS
1661 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1662 CancelationOptions options(mode, "input event injection failed");
1663 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001664 return true;
1665 }
1666
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001667 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001668 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001669
1670 // Dispatch the motion.
1671 if (conflictingPointerActions) {
1672 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001673 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001674 synthesizeCancelationEventsForAllConnectionsLocked(options);
1675 }
1676 dispatchEventLocked(currentTime, entry, inputTargets);
1677 return true;
1678}
1679
chaviw98318de2021-05-19 16:45:23 -05001680void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001681 bool isExiting, const MotionEntry& motionEntry) {
1682 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1683 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1684 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1685 PointerCoords pointerCoords;
1686 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1687 pointerCoords.transform(windowHandle->getInfo()->transform);
1688
1689 std::unique_ptr<DragEntry> dragEntry =
1690 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1691 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1692 pointerCoords.getY());
1693
1694 enqueueInboundEventLocked(std::move(dragEntry));
1695}
1696
1697void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1698 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1699 if (channel == nullptr) {
1700 return; // Window has gone away
1701 }
1702 InputTarget target;
1703 target.inputChannel = channel;
1704 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1705 entry->dispatchInProgress = true;
1706 dispatchEventLocked(currentTime, entry, {target});
1707}
1708
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001709void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001710 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1711 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1712 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001713 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001714 "metaState=0x%x, buttonState=0x%x,"
1715 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1716 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001717 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1718 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1719 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001720
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001721 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1722 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1723 "x=%f, y=%f, pressure=%f, size=%f, "
1724 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1725 "orientation=%f",
1726 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1727 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1728 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1729 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1730 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1731 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1732 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1733 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1734 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1735 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1736 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001737 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001738}
1739
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001740void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1741 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001742 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001743 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001744 if (DEBUG_DISPATCH_CYCLE) {
1745 ALOGD("dispatchEventToCurrentInputTargets");
1746 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001747
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001748 updateInteractionTokensLocked(*eventEntry, inputTargets);
1749
Michael Wrightd02c5b62014-02-10 15:10:22 -08001750 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1751
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001752 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001753
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001754 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001755 sp<Connection> connection =
1756 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001757 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001758 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001759 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001760 if (DEBUG_FOCUS) {
1761 ALOGD("Dropping event delivery to target with channel '%s' because it "
1762 "is no longer registered with the input dispatcher.",
1763 inputTarget.inputChannel->getName().c_str());
1764 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001765 }
1766 }
1767}
1768
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001769void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1770 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1771 // If the policy decides to close the app, we will get a channel removal event via
1772 // unregisterInputChannel, and will clean up the connection that way. We are already not
1773 // sending new pointers to the connection when it blocked, but focused events will continue to
1774 // pile up.
1775 ALOGW("Canceling events for %s because it is unresponsive",
1776 connection->inputChannel->getName().c_str());
1777 if (connection->status == Connection::STATUS_NORMAL) {
1778 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1779 "application not responding");
1780 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001781 }
1782}
1783
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001784void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001785 if (DEBUG_FOCUS) {
1786 ALOGD("Resetting ANR timeouts.");
1787 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001788
1789 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001790 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001791 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001792}
1793
Tiger Huang721e26f2018-07-24 22:26:19 +08001794/**
1795 * Get the display id that the given event should go to. If this event specifies a valid display id,
1796 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1797 * Focused display is the display that the user most recently interacted with.
1798 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001799int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001800 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001801 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001802 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001803 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1804 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001805 break;
1806 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001807 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001808 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1809 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001810 break;
1811 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001812 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001813 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001814 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001815 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001816 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001817 case EventEntry::Type::SENSOR:
1818 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001819 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001820 return ADISPLAY_ID_NONE;
1821 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001822 }
1823 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1824}
1825
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001826bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1827 const char* focusedWindowName) {
1828 if (mAnrTracker.empty()) {
1829 // already processed all events that we waited for
1830 mKeyIsWaitingForEventsTimeout = std::nullopt;
1831 return false;
1832 }
1833
1834 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1835 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001836 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001837 mKeyIsWaitingForEventsTimeout = currentTime +
1838 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1839 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001840 return true;
1841 }
1842
1843 // We still have pending events, and already started the timer
1844 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1845 return true; // Still waiting
1846 }
1847
1848 // Waited too long, and some connection still hasn't processed all motions
1849 // Just send the key to the focused window
1850 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1851 focusedWindowName);
1852 mKeyIsWaitingForEventsTimeout = std::nullopt;
1853 return false;
1854}
1855
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001856InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1857 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1858 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001859 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001860
Tiger Huang721e26f2018-07-24 22:26:19 +08001861 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001862 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001863 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001864 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1865
Michael Wrightd02c5b62014-02-10 15:10:22 -08001866 // If there is no currently focused window and no focused application
1867 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001868 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1869 ALOGI("Dropping %s event because there is no focused window or focused application in "
1870 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001871 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001872 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001873 }
1874
Vishnu Nair062a8672021-09-03 16:07:44 -07001875 // Drop key events if requested by input feature
1876 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1877 return InputEventInjectionResult::FAILED;
1878 }
1879
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001880 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1881 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1882 // start interacting with another application via touch (app switch). This code can be removed
1883 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1884 // an app is expected to have a focused window.
1885 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1886 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1887 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001888 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1889 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1890 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001891 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001892 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001893 ALOGW("Waiting because no window has focus but %s may eventually add a "
1894 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001895 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001896 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001897 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001898 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1899 // Already raised ANR. Drop the event
1900 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001901 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001902 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001903 } else {
1904 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001905 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001906 }
1907 }
1908
1909 // we have a valid, non-null focused window
1910 resetNoFocusedWindowTimeoutLocked();
1911
Michael Wrightd02c5b62014-02-10 15:10:22 -08001912 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001913 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001914 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001915 }
1916
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001917 if (focusedWindowHandle->getInfo()->paused) {
1918 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001919 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001920 }
1921
1922 // If the event is a key event, then we must wait for all previous events to
1923 // complete before delivering it because previous events may have the
1924 // side-effect of transferring focus to a different window and we want to
1925 // ensure that the following keys are sent to the new window.
1926 //
1927 // Suppose the user touches a button in a window then immediately presses "A".
1928 // If the button causes a pop-up window to appear then we want to ensure that
1929 // the "A" key is delivered to the new pop-up window. This is because users
1930 // often anticipate pending UI changes when typing on a keyboard.
1931 // To obtain this behavior, we must serialize key events with respect to all
1932 // prior input events.
1933 if (entry.type == EventEntry::Type::KEY) {
1934 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1935 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001936 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001937 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001938 }
1939
1940 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001941 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001942 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1943 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001944
1945 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001946 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001947}
1948
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001949/**
1950 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1951 * that are currently unresponsive.
1952 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001953std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
1954 const std::vector<Monitor>& monitors) const {
1955 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001956 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001957 [this](const Monitor& monitor) REQUIRES(mLock) {
1958 sp<Connection> connection =
1959 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001960 if (connection == nullptr) {
1961 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001962 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001963 return false;
1964 }
1965 if (!connection->responsive) {
1966 ALOGW("Unresponsive monitor %s will not get the new gesture",
1967 connection->inputChannel->getName().c_str());
1968 return false;
1969 }
1970 return true;
1971 });
1972 return responsiveMonitors;
1973}
1974
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001975InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1976 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1977 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001978 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 enum InjectionPermission {
1980 INJECTION_PERMISSION_UNKNOWN,
1981 INJECTION_PERMISSION_GRANTED,
1982 INJECTION_PERMISSION_DENIED
1983 };
1984
Michael Wrightd02c5b62014-02-10 15:10:22 -08001985 // For security reasons, we defer updating the touch state until we are sure that
1986 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001987 int32_t displayId = entry.displayId;
1988 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001989 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1990
1991 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001992 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001993 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001994 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1995 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001996
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001997 // Copy current touch state into tempTouchState.
1998 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1999 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07002000 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002001 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07002002 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
2003 mTouchStatesByDisplay.find(displayId);
2004 if (oldStateIt != mTouchStatesByDisplay.end()) {
2005 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002006 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08002007 }
2008
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002009 bool isSplit = tempTouchState.split;
2010 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2011 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2012 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002013 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2014 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2015 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2016 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2017 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002018 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002019 bool wrongDevice = false;
2020 if (newGesture) {
2021 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002022 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002023 ALOGI("Dropping event because a pointer for a different device is already down "
2024 "in display %" PRId32,
2025 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002026 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002027 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002028 switchedDevice = false;
2029 wrongDevice = true;
2030 goto Failed;
2031 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002032 tempTouchState.reset();
2033 tempTouchState.down = down;
2034 tempTouchState.deviceId = entry.deviceId;
2035 tempTouchState.source = entry.source;
2036 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002037 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002038 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002039 ALOGI("Dropping move event because a pointer for a different device is already active "
2040 "in display %" PRId32,
2041 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002042 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002043 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002044 switchedDevice = false;
2045 wrongDevice = true;
2046 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047 }
2048
2049 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2050 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2051
Garfield Tan00f511d2019-06-12 16:55:40 -07002052 int32_t x;
2053 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002054 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002055 // Always dispatch mouse events to cursor position.
2056 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002057 x = int32_t(entry.xCursorPosition);
2058 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002059 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002060 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2061 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002062 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002063 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002064 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
2065 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002066
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002068 if (newTouchedWindowHandle != nullptr &&
2069 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07002070 // New window supports splitting, but we should never split mouse events.
2071 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072 } else if (isSplit) {
2073 // New window does not support splitting but we have already split events.
2074 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002075 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002076 }
2077
2078 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002079 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002080 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002081 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002082 }
2083
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002084 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2085 ALOGI("Not sending touch event to %s because it is paused",
2086 newTouchedWindowHandle->getName().c_str());
2087 newTouchedWindowHandle = nullptr;
2088 }
2089
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002090 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002091 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002092 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2093 if (!isResponsive) {
2094 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002095 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2096 newTouchedWindowHandle = nullptr;
2097 }
2098 }
2099
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002100 // Drop events that can't be trusted due to occlusion
2101 if (newTouchedWindowHandle != nullptr &&
2102 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2103 TouchOcclusionInfo occlusionInfo =
2104 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002105 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002106 if (DEBUG_TOUCH_OCCLUSION) {
2107 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2108 for (const auto& log : occlusionInfo.debugInfo) {
2109 ALOGD("%s", log.c_str());
2110 }
2111 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002112 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002113 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2114 ALOGW("Dropping untrusted touch event due to %s/%d",
2115 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2116 newTouchedWindowHandle = nullptr;
2117 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002118 }
2119 }
2120
Vishnu Nair062a8672021-09-03 16:07:44 -07002121 // Drop touch events if requested by input feature
2122 if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) {
2123 newTouchedWindowHandle = nullptr;
2124 }
2125
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002126 const std::vector<Monitor> newGestureMonitors = isDown
2127 ? selectResponsiveMonitorsLocked(
2128 getValueByKey(mGestureMonitorsByDisplay, displayId))
2129 : std::vector<Monitor>{};
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002130
Michael Wright3dd60e22019-03-27 22:06:44 +00002131 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2132 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002133 "(%d, %d) in display %" PRId32 ".",
2134 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002135 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002136 goto Failed;
2137 }
2138
2139 if (newTouchedWindowHandle != nullptr) {
2140 // Set target flags.
2141 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2142 if (isSplit) {
2143 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002144 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002145 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2146 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2147 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2148 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2149 }
2150
2151 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002152 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2153 newHoverWindowHandle = nullptr;
2154 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002155 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002156 }
2157
2158 // Update the temporary touch state.
2159 BitSet32 pointerIds;
2160 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002161 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002162 pointerIds.markBit(pointerId);
2163 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002164 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002165 }
2166
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002167 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 } else {
2169 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2170
2171 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002172 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002173 if (DEBUG_FOCUS) {
2174 ALOGD("Dropping event because the pointer is not down or we previously "
2175 "dropped the pointer down event in display %" PRId32,
2176 displayId);
2177 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002178 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002179 goto Failed;
2180 }
2181
arthurhung6d4bed92021-03-17 11:59:33 +08002182 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002183
Michael Wrightd02c5b62014-02-10 15:10:22 -08002184 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002185 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002186 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002187 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2188 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002189
chaviw98318de2021-05-19 16:45:23 -05002190 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002191 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002192 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Vishnu Nair062a8672021-09-03 16:07:44 -07002193
2194 // Drop touch events if requested by input feature
2195 if (newTouchedWindowHandle != nullptr &&
2196 shouldDropInput(entry, newTouchedWindowHandle)) {
2197 newTouchedWindowHandle = nullptr;
2198 }
2199
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002200 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2201 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002202 if (DEBUG_FOCUS) {
2203 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2204 oldTouchedWindowHandle->getName().c_str(),
2205 newTouchedWindowHandle->getName().c_str(), displayId);
2206 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002207 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002208 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2209 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2210 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002211
2212 // Make a slippery entrance into the new window.
2213 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2214 isSplit = true;
2215 }
2216
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002217 int32_t targetFlags =
2218 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002219 if (isSplit) {
2220 targetFlags |= InputTarget::FLAG_SPLIT;
2221 }
2222 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2223 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002224 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2225 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226 }
2227
2228 BitSet32 pointerIds;
2229 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002230 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002231 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002232 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002233 }
2234 }
2235 }
2236
2237 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002238 // Let the previous window know that the hover sequence is over, unless we already did it
2239 // when dispatching it as is to newTouchedWindowHandle.
2240 if (mLastHoverWindowHandle != nullptr &&
2241 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2242 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002243 if (DEBUG_HOVER) {
2244 ALOGD("Sending hover exit event to window %s.",
2245 mLastHoverWindowHandle->getName().c_str());
2246 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002247 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2248 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002249 }
2250
Garfield Tandf26e862020-07-01 20:18:19 -07002251 // Let the new window know that the hover sequence is starting, unless we already did it
2252 // when dispatching it as is to newTouchedWindowHandle.
2253 if (newHoverWindowHandle != nullptr &&
2254 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2255 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002256 if (DEBUG_HOVER) {
2257 ALOGD("Sending hover enter event to window %s.",
2258 newHoverWindowHandle->getName().c_str());
2259 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002260 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2261 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2262 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263 }
2264 }
2265
2266 // Check permission to inject into all touched foreground windows and ensure there
2267 // is at least one touched foreground window.
2268 {
2269 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002270 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2272 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002273 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002274 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002275 injectionPermission = INJECTION_PERMISSION_DENIED;
2276 goto Failed;
2277 }
2278 }
2279 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002280 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002281 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002282 ALOGI("Dropping event because there is no touched foreground window in display "
2283 "%" PRId32 " or gesture monitor to receive it.",
2284 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002285 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002286 goto Failed;
2287 }
2288
2289 // Permission granted to injection into all touched foreground windows.
2290 injectionPermission = INJECTION_PERMISSION_GRANTED;
2291 }
2292
2293 // Check whether windows listening for outside touches are owned by the same UID. If it is
2294 // set the policy flag that we will not reveal coordinate information to this window.
2295 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002296 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002297 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002298 if (foregroundWindowHandle) {
2299 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002300 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002301 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002302 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2303 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2304 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002305 InputTarget::FLAG_ZERO_COORDS,
2306 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002307 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002308 }
2309 }
2310 }
2311 }
2312
Michael Wrightd02c5b62014-02-10 15:10:22 -08002313 // If this is the first pointer going down and the touched window has a wallpaper
2314 // then also add the touched wallpaper windows so they are locked in for the duration
2315 // of the touch gesture.
2316 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2317 // engine only supports touch events. We would need to add a mechanism similar
2318 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2319 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002320 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002321 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002322 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002323 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002324 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002325 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2326 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002327 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002328 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002329 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002330 .addOrUpdateWindow(windowHandle,
2331 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2332 InputTarget::
2333 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2334 InputTarget::FLAG_DISPATCH_AS_IS,
2335 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002336 }
2337 }
2338 }
2339 }
2340
2341 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002342 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002343
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002344 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002345 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002346 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002347 }
2348
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002349 for (const auto& monitor : tempTouchState.gestureMonitors) {
2350 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002351 }
2352
Michael Wrightd02c5b62014-02-10 15:10:22 -08002353 // Drop the outside or hover touch windows since we will not care about them
2354 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002355 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356
2357Failed:
2358 // Check injection permission once and for all.
2359 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002360 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002361 injectionPermission = INJECTION_PERMISSION_GRANTED;
2362 } else {
2363 injectionPermission = INJECTION_PERMISSION_DENIED;
2364 }
2365 }
2366
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002367 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2368 return injectionResult;
2369 }
2370
Michael Wrightd02c5b62014-02-10 15:10:22 -08002371 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002372 if (!wrongDevice) {
2373 if (switchedDevice) {
2374 if (DEBUG_FOCUS) {
2375 ALOGD("Conflicting pointer actions: Switched to a different device.");
2376 }
2377 *outConflictingPointerActions = true;
2378 }
2379
2380 if (isHoverAction) {
2381 // Started hovering, therefore no longer down.
2382 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002383 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002384 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2385 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002386 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002387 *outConflictingPointerActions = true;
2388 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002389 tempTouchState.reset();
2390 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2391 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2392 tempTouchState.deviceId = entry.deviceId;
2393 tempTouchState.source = entry.source;
2394 tempTouchState.displayId = displayId;
2395 }
2396 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2397 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2398 // All pointers up or canceled.
2399 tempTouchState.reset();
2400 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2401 // First pointer went down.
2402 if (oldState && oldState->down) {
2403 if (DEBUG_FOCUS) {
2404 ALOGD("Conflicting pointer actions: Down received while already down.");
2405 }
2406 *outConflictingPointerActions = true;
2407 }
2408 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2409 // One pointer went up.
2410 if (isSplit) {
2411 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2412 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002413
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002414 for (size_t i = 0; i < tempTouchState.windows.size();) {
2415 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2416 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2417 touchedWindow.pointerIds.clearBit(pointerId);
2418 if (touchedWindow.pointerIds.isEmpty()) {
2419 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2420 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002421 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002422 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002423 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002424 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002425 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002426 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002427
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002428 // Save changes unless the action was scroll in which case the temporary touch
2429 // state was only valid for this one action.
2430 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2431 if (tempTouchState.displayId >= 0) {
2432 mTouchStatesByDisplay[displayId] = tempTouchState;
2433 } else {
2434 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002435 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002436 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002437
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002438 // Update hover state.
2439 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002440 }
2441
Michael Wrightd02c5b62014-02-10 15:10:22 -08002442 return injectionResult;
2443}
2444
arthurhung6d4bed92021-03-17 11:59:33 +08002445void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002446 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002447 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002448 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002449 if (dropWindow) {
2450 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002451 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002452 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002453 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002454 }
2455 mDragState.reset();
2456}
2457
2458void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2459 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002460 return;
2461 }
2462
arthurhung6d4bed92021-03-17 11:59:33 +08002463 if (!mDragState->isStartDrag) {
2464 mDragState->isStartDrag = true;
2465 mDragState->isStylusButtonDownAtStart =
2466 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2467 }
2468
arthurhungb89ccb02020-12-30 16:19:01 +08002469 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2470 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2471 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2472 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002473 // Handle the special case : stylus button no longer pressed.
2474 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2475 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2476 finishDragAndDrop(entry.displayId, x, y);
2477 return;
2478 }
2479
chaviw98318de2021-05-19 16:45:23 -05002480 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002481 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002482 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002483 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002484 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2485 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2486 if (mDragState->dragHoverWindowHandle != nullptr) {
2487 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2488 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002489 }
arthurhung6d4bed92021-03-17 11:59:33 +08002490 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002491 }
2492 // enqueue drag location if needed.
2493 if (hoverWindowHandle != nullptr) {
2494 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2495 }
arthurhung6d4bed92021-03-17 11:59:33 +08002496 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2497 finishDragAndDrop(entry.displayId, x, y);
2498 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002499 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002500 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002501 }
2502}
2503
chaviw98318de2021-05-19 16:45:23 -05002504void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002505 int32_t targetFlags, BitSet32 pointerIds,
2506 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002507 std::vector<InputTarget>::iterator it =
2508 std::find_if(inputTargets.begin(), inputTargets.end(),
2509 [&windowHandle](const InputTarget& inputTarget) {
2510 return inputTarget.inputChannel->getConnectionToken() ==
2511 windowHandle->getToken();
2512 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002513
chaviw98318de2021-05-19 16:45:23 -05002514 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002515
2516 if (it == inputTargets.end()) {
2517 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002518 std::shared_ptr<InputChannel> inputChannel =
2519 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002520 if (inputChannel == nullptr) {
2521 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2522 return;
2523 }
2524 inputTarget.inputChannel = inputChannel;
2525 inputTarget.flags = targetFlags;
2526 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002527 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2528 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002529 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002530 } else {
2531 ALOGI_IF(isPerWindowInputRotationEnabled(),
2532 "DisplayInfo not found for window on display: %d", windowInfo->displayId);
2533 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002534 inputTargets.push_back(inputTarget);
2535 it = inputTargets.end() - 1;
2536 }
2537
2538 ALOG_ASSERT(it->flags == targetFlags);
2539 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2540
chaviw1ff3d1e2020-07-01 15:53:47 -07002541 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002542}
2543
Michael Wright3dd60e22019-03-27 22:06:44 +00002544void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002545 int32_t displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002546 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2547 mGlobalMonitorsByDisplay.find(displayId);
2548
2549 if (it != mGlobalMonitorsByDisplay.end()) {
2550 const std::vector<Monitor>& monitors = it->second;
2551 for (const Monitor& monitor : monitors) {
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002552 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002553 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002554 }
2555}
2556
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002557void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002558 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002559 InputTarget target;
2560 target.inputChannel = monitor.inputChannel;
2561 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002562 ui::Transform t;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002563 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
Prabir Pradhanb5402b22021-10-04 05:52:50 -07002564 const auto& displayTransform = it->second.transform;
2565 target.displayTransform = displayTransform;
2566 t = displayTransform;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002567 }
chaviw1ff3d1e2020-07-01 15:53:47 -07002568 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002569 inputTargets.push_back(target);
2570}
2571
chaviw98318de2021-05-19 16:45:23 -05002572bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002573 const InjectionState* injectionState) {
2574 if (injectionState &&
2575 (windowHandle == nullptr ||
2576 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2577 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002578 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002580 "owned by uid %d",
2581 injectionState->injectorPid, injectionState->injectorUid,
2582 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002583 } else {
2584 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002585 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586 }
2587 return false;
2588 }
2589 return true;
2590}
2591
Robert Carrc9bf1d32020-04-13 17:21:08 -07002592/**
2593 * Indicate whether one window handle should be considered as obscuring
2594 * another window handle. We only check a few preconditions. Actually
2595 * checking the bounds is left to the caller.
2596 */
chaviw98318de2021-05-19 16:45:23 -05002597static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2598 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002599 // Compare by token so cloned layers aren't counted
2600 if (haveSameToken(windowHandle, otherHandle)) {
2601 return false;
2602 }
2603 auto info = windowHandle->getInfo();
2604 auto otherInfo = otherHandle->getInfo();
2605 if (!otherInfo->visible) {
2606 return false;
chaviw98318de2021-05-19 16:45:23 -05002607 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002608 // Those act as if they were invisible, so we don't need to flag them.
2609 // We do want to potentially flag touchable windows even if they have 0
2610 // opacity, since they can consume touches and alter the effects of the
2611 // user interaction (eg. apps that rely on
2612 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2613 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2614 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002615 } else if (info->ownerUid == otherInfo->ownerUid) {
2616 // If ownerUid is the same we don't generate occlusion events as there
2617 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002618 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002619 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002620 return false;
2621 } else if (otherInfo->displayId != info->displayId) {
2622 return false;
2623 }
2624 return true;
2625}
2626
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002627/**
2628 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2629 * untrusted, one should check:
2630 *
2631 * 1. If result.hasBlockingOcclusion is true.
2632 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2633 * BLOCK_UNTRUSTED.
2634 *
2635 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2636 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2637 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2638 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2639 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2640 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2641 *
2642 * If neither of those is true, then it means the touch can be allowed.
2643 */
2644InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002645 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2646 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002647 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002648 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002649 TouchOcclusionInfo info;
2650 info.hasBlockingOcclusion = false;
2651 info.obscuringOpacity = 0;
2652 info.obscuringUid = -1;
2653 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002654 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002655 if (windowHandle == otherHandle) {
2656 break; // All future windows are below us. Exit early.
2657 }
chaviw98318de2021-05-19 16:45:23 -05002658 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002659 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2660 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002661 if (DEBUG_TOUCH_OCCLUSION) {
2662 info.debugInfo.push_back(
2663 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2664 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002665 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2666 // we perform the checks below to see if the touch can be propagated or not based on the
2667 // window's touch occlusion mode
2668 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2669 info.hasBlockingOcclusion = true;
2670 info.obscuringUid = otherInfo->ownerUid;
2671 info.obscuringPackage = otherInfo->packageName;
2672 break;
2673 }
2674 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2675 uint32_t uid = otherInfo->ownerUid;
2676 float opacity =
2677 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2678 // Given windows A and B:
2679 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2680 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2681 opacityByUid[uid] = opacity;
2682 if (opacity > info.obscuringOpacity) {
2683 info.obscuringOpacity = opacity;
2684 info.obscuringUid = uid;
2685 info.obscuringPackage = otherInfo->packageName;
2686 }
2687 }
2688 }
2689 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002690 if (DEBUG_TOUCH_OCCLUSION) {
2691 info.debugInfo.push_back(
2692 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2693 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002694 return info;
2695}
2696
chaviw98318de2021-05-19 16:45:23 -05002697std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002698 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002699 return StringPrintf(INDENT2
2700 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2701 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2702 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2703 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002704 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002705 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002706 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2707 info->frameTop, info->frameRight, info->frameBottom,
2708 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002709 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2710 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2711 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002712}
2713
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002714bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2715 if (occlusionInfo.hasBlockingOcclusion) {
2716 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2717 occlusionInfo.obscuringUid);
2718 return false;
2719 }
2720 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2721 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2722 "%.2f, maximum allowed = %.2f)",
2723 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2724 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2725 return false;
2726 }
2727 return true;
2728}
2729
chaviw98318de2021-05-19 16:45:23 -05002730bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002731 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002733 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2734 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002735 if (windowHandle == otherHandle) {
2736 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002737 }
chaviw98318de2021-05-19 16:45:23 -05002738 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002739 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002740 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 return true;
2742 }
2743 }
2744 return false;
2745}
2746
chaviw98318de2021-05-19 16:45:23 -05002747bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002748 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002749 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2750 const WindowInfo* windowInfo = windowHandle->getInfo();
2751 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002752 if (windowHandle == otherHandle) {
2753 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002754 }
chaviw98318de2021-05-19 16:45:23 -05002755 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002756 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002757 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002758 return true;
2759 }
2760 }
2761 return false;
2762}
2763
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002764std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002765 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002766 if (applicationHandle != nullptr) {
2767 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002768 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769 } else {
2770 return applicationHandle->getName();
2771 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002772 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002773 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002774 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002775 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002776 }
2777}
2778
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002779void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002780 if (!isUserActivityEvent(eventEntry)) {
2781 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002782 return;
2783 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002784 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002785 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002786 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002787 const WindowInfo* info = focusedWindowHandle->getInfo();
2788 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002789 if (DEBUG_DISPATCH_CYCLE) {
2790 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2791 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002792 return;
2793 }
2794 }
2795
2796 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002797 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002798 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002799 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2800 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002801 return;
2802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002803
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002804 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002805 eventType = USER_ACTIVITY_EVENT_TOUCH;
2806 }
2807 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002808 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002809 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002810 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2811 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002812 return;
2813 }
2814 eventType = USER_ACTIVITY_EVENT_BUTTON;
2815 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002816 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002817 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002818 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002819 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002820 break;
2821 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002822 }
2823
Prabir Pradhancef936d2021-07-21 16:17:52 +00002824 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2825 REQUIRES(mLock) {
2826 scoped_unlock unlock(mLock);
2827 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2828 };
2829 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830}
2831
2832void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002833 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002834 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002835 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002836 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002837 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002838 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002839 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002840 ATRACE_NAME(message.c_str());
2841 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002842 if (DEBUG_DISPATCH_CYCLE) {
2843 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2844 "globalScaleFactor=%f, pointerIds=0x%x %s",
2845 connection->getInputChannelName().c_str(), inputTarget.flags,
2846 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2847 inputTarget.getPointerInfoString().c_str());
2848 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002849
2850 // Skip this event if the connection status is not normal.
2851 // We don't want to enqueue additional outbound events if the connection is broken.
2852 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002853 if (DEBUG_DISPATCH_CYCLE) {
2854 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2855 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2856 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002857 return;
2858 }
2859
2860 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002861 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2862 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2863 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002864 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002865
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002866 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002867 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002868 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002869 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002870 if (!splitMotionEntry) {
2871 return; // split event was dropped
2872 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002873 if (DEBUG_FOCUS) {
2874 ALOGD("channel '%s' ~ Split motion event.",
2875 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002876 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002877 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002878 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2879 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002880 return;
2881 }
2882 }
2883
2884 // Not splitting. Enqueue dispatch entries for the event as is.
2885 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2886}
2887
2888void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002889 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002890 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002891 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002892 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002893 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002894 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002895 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002896 ATRACE_NAME(message.c_str());
2897 }
2898
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002899 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002900
2901 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002902 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002903 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002904 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002905 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002906 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002907 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002908 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002909 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002910 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002911 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002912 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002913 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002914
2915 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002916 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002917 startDispatchCycleLocked(currentTime, connection);
2918 }
2919}
2920
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002921void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002922 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002923 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002924 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002925 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002926 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2927 connection->getInputChannelName().c_str(),
2928 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002929 ATRACE_NAME(message.c_str());
2930 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002931 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002932 if (!(inputTargetFlags & dispatchMode)) {
2933 return;
2934 }
2935 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2936
2937 // This is a new event.
2938 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002939 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002940 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002942 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2943 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002944 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002945 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002946 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002947 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002948 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002949 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002950 dispatchEntry->resolvedAction = keyEntry.action;
2951 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002953 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2954 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002955 if (DEBUG_DISPATCH_CYCLE) {
2956 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2957 "event",
2958 connection->getInputChannelName().c_str());
2959 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002960 return; // skip the inconsistent event
2961 }
2962 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002963 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002964
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002965 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002966 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002967 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2968 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2969 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2970 static_cast<int32_t>(IdGenerator::Source::OTHER);
2971 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002972 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2973 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2974 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2975 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2976 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2977 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2978 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2979 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2980 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2981 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2982 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002983 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002984 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002985 }
2986 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002987 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2988 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002989 if (DEBUG_DISPATCH_CYCLE) {
2990 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
2991 "enter event",
2992 connection->getInputChannelName().c_str());
2993 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002994 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2995 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002996 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2997 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002998
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002999 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003000 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
3001 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3002 }
3003 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3004 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3005 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003006
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003007 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3008 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003009 if (DEBUG_DISPATCH_CYCLE) {
3010 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3011 "event",
3012 connection->getInputChannelName().c_str());
3013 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003014 return; // skip the inconsistent event
3015 }
3016
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003017 dispatchEntry->resolvedEventId =
3018 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3019 ? mIdGenerator.nextId()
3020 : motionEntry.id;
3021 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3022 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3023 ") to MotionEvent(id=0x%" PRIx32 ").",
3024 motionEntry.id, dispatchEntry->resolvedEventId);
3025 ATRACE_NAME(message.c_str());
3026 }
3027
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003028 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3029 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3030 // Skip reporting pointer down outside focus to the policy.
3031 break;
3032 }
3033
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003034 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003035 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003036
3037 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003038 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003039 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003040 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003041 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3042 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003043 break;
3044 }
Chris Yef59a2f42020-10-16 12:55:26 -07003045 case EventEntry::Type::SENSOR: {
3046 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3047 break;
3048 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003049 case EventEntry::Type::CONFIGURATION_CHANGED:
3050 case EventEntry::Type::DEVICE_RESET: {
3051 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003052 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003053 break;
3054 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003055 }
3056
3057 // Remember that we are waiting for this dispatch to complete.
3058 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003059 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003060 }
3061
3062 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003063 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003064 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003065}
3066
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003067/**
3068 * This function is purely for debugging. It helps us understand where the user interaction
3069 * was taking place. For example, if user is touching launcher, we will see a log that user
3070 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3071 * We will see both launcher and wallpaper in that list.
3072 * Once the interaction with a particular set of connections starts, no new logs will be printed
3073 * until the set of interacted connections changes.
3074 *
3075 * The following items are skipped, to reduce the logspam:
3076 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3077 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3078 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3079 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3080 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003081 */
3082void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3083 const std::vector<InputTarget>& targets) {
3084 // Skip ACTION_UP events, and all events other than keys and motions
3085 if (entry.type == EventEntry::Type::KEY) {
3086 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3087 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3088 return;
3089 }
3090 } else if (entry.type == EventEntry::Type::MOTION) {
3091 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3092 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3093 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3094 return;
3095 }
3096 } else {
3097 return; // Not a key or a motion
3098 }
3099
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003100 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003101 std::vector<sp<Connection>> newConnections;
3102 for (const InputTarget& target : targets) {
3103 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3104 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3105 continue; // Skip windows that receive ACTION_OUTSIDE
3106 }
3107
3108 sp<IBinder> token = target.inputChannel->getConnectionToken();
3109 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003110 if (connection == nullptr) {
3111 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003112 }
3113 newConnectionTokens.insert(std::move(token));
3114 newConnections.emplace_back(connection);
3115 }
3116 if (newConnectionTokens == mInteractionConnectionTokens) {
3117 return; // no change
3118 }
3119 mInteractionConnectionTokens = newConnectionTokens;
3120
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003121 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003122 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003123 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003124 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003125 std::string message = "Interaction with: " + targetList;
3126 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003127 message += "<none>";
3128 }
3129 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3130}
3131
chaviwfd6d3512019-03-25 13:23:49 -07003132void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003133 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003134 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003135 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3136 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003137 return;
3138 }
3139
Vishnu Nairc519ff72021-01-21 08:23:08 -08003140 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003141 if (focusedToken == token) {
3142 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003143 return;
3144 }
3145
Prabir Pradhancef936d2021-07-21 16:17:52 +00003146 auto command = [this, token]() REQUIRES(mLock) {
3147 scoped_unlock unlock(mLock);
3148 mPolicy->onPointerDownOutsideFocus(token);
3149 };
3150 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003151}
3152
3153void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003154 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003155 if (ATRACE_ENABLED()) {
3156 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003157 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003158 ATRACE_NAME(message.c_str());
3159 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003160 if (DEBUG_DISPATCH_CYCLE) {
3161 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3162 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003163
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003164 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3165 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003166 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003167 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003168 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003169 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003170
3171 // Publish the event.
3172 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003173 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3174 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003175 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003176 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3177 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003179 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003180 status = connection->inputPublisher
3181 .publishKeyEvent(dispatchEntry->seq,
3182 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3183 keyEntry.source, keyEntry.displayId,
3184 std::move(hmac), dispatchEntry->resolvedAction,
3185 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3186 keyEntry.scanCode, keyEntry.metaState,
3187 keyEntry.repeatCount, keyEntry.downTime,
3188 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003189 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003190 }
3191
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003192 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003193 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003194
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003195 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003196 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003197
chaviw82357092020-01-28 13:13:06 -08003198 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003199 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003200 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3201 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003202 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003203 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3204 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003205 // Don't apply window scale here since we don't want scale to affect raw
3206 // coordinates. The scale will be sent back to the client and applied
3207 // later when requesting relative coordinates.
3208 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3209 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003210 }
3211 usingCoords = scaledCoords;
3212 }
3213 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003214 // We don't want the dispatch target to know.
3215 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003216 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003217 scaledCoords[i].clear();
3218 }
3219 usingCoords = scaledCoords;
3220 }
3221 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003222
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003223 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003224
3225 // Publish the motion event.
3226 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003227 .publishMotionEvent(dispatchEntry->seq,
3228 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003229 motionEntry.deviceId, motionEntry.source,
3230 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003231 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003232 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003233 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003234 motionEntry.edgeFlags, motionEntry.metaState,
3235 motionEntry.buttonState,
3236 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003237 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003238 motionEntry.xPrecision, motionEntry.yPrecision,
3239 motionEntry.xCursorPosition,
3240 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003241 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003242 motionEntry.downTime, motionEntry.eventTime,
3243 motionEntry.pointerCount,
3244 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003245 break;
3246 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003247
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003248 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003249 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003250 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003251 focusEntry.id,
3252 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003253 mInTouchMode);
3254 break;
3255 }
3256
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003257 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3258 const TouchModeEntry& touchModeEntry =
3259 static_cast<const TouchModeEntry&>(eventEntry);
3260 status = connection->inputPublisher
3261 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3262 touchModeEntry.inTouchMode);
3263
3264 break;
3265 }
3266
Prabir Pradhan99987712020-11-10 18:43:05 -08003267 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3268 const auto& captureEntry =
3269 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3270 status = connection->inputPublisher
3271 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003272 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003273 break;
3274 }
3275
arthurhungb89ccb02020-12-30 16:19:01 +08003276 case EventEntry::Type::DRAG: {
3277 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3278 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3279 dragEntry.id, dragEntry.x,
3280 dragEntry.y,
3281 dragEntry.isExiting);
3282 break;
3283 }
3284
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003285 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003286 case EventEntry::Type::DEVICE_RESET:
3287 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003288 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003289 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003290 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003291 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003292 }
3293
3294 // Check the result.
3295 if (status) {
3296 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003297 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003298 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003299 "This is unexpected because the wait queue is empty, so the pipe "
3300 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003301 "event to it, status=%s(%d)",
3302 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3303 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3305 } else {
3306 // Pipe is full and we are waiting for the app to finish process some events
3307 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003308 if (DEBUG_DISPATCH_CYCLE) {
3309 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3310 "waiting for the application to catch up",
3311 connection->getInputChannelName().c_str());
3312 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 }
3314 } else {
3315 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003316 "status=%s(%d)",
3317 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3318 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3320 }
3321 return;
3322 }
3323
3324 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003325 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3326 connection->outboundQueue.end(),
3327 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003328 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003329 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003330 if (connection->responsive) {
3331 mAnrTracker.insert(dispatchEntry->timeoutTime,
3332 connection->inputChannel->getConnectionToken());
3333 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003334 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003335 }
3336}
3337
chaviw09c8d2d2020-08-24 15:48:26 -07003338std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3339 size_t size;
3340 switch (event.type) {
3341 case VerifiedInputEvent::Type::KEY: {
3342 size = sizeof(VerifiedKeyEvent);
3343 break;
3344 }
3345 case VerifiedInputEvent::Type::MOTION: {
3346 size = sizeof(VerifiedMotionEvent);
3347 break;
3348 }
3349 }
3350 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3351 return mHmacKeyManager.sign(start, size);
3352}
3353
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003354const std::array<uint8_t, 32> InputDispatcher::getSignature(
3355 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003356 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3357 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003358 // Only sign events up and down events as the purely move events
3359 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003360 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003361 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003362
3363 VerifiedMotionEvent verifiedEvent =
3364 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3365 verifiedEvent.actionMasked = actionMasked;
3366 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3367 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003368}
3369
3370const std::array<uint8_t, 32> InputDispatcher::getSignature(
3371 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3372 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3373 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3374 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003375 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003376}
3377
Michael Wrightd02c5b62014-02-10 15:10:22 -08003378void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003379 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003380 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003381 if (DEBUG_DISPATCH_CYCLE) {
3382 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3383 connection->getInputChannelName().c_str(), seq, toString(handled));
3384 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003385
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003386 if (connection->status == Connection::STATUS_BROKEN ||
3387 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003388 return;
3389 }
3390
3391 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003392 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3393 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3394 };
3395 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003396}
3397
3398void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003399 const sp<Connection>& connection,
3400 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003401 if (DEBUG_DISPATCH_CYCLE) {
3402 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3403 connection->getInputChannelName().c_str(), toString(notify));
3404 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003405
3406 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003407 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003408 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003409 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003410 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003411
3412 // The connection appears to be unrecoverably broken.
3413 // Ignore already broken or zombie connections.
3414 if (connection->status == Connection::STATUS_NORMAL) {
3415 connection->status = Connection::STATUS_BROKEN;
3416
3417 if (notify) {
3418 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003419 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3420 connection->getInputChannelName().c_str());
3421
3422 auto command = [this, connection]() REQUIRES(mLock) {
3423 if (connection->status == Connection::STATUS_ZOMBIE) return;
3424 scoped_unlock unlock(mLock);
3425 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3426 };
3427 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003428 }
3429 }
3430}
3431
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003432void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3433 while (!queue.empty()) {
3434 DispatchEntry* dispatchEntry = queue.front();
3435 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003436 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003437 }
3438}
3439
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003440void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003441 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003442 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003443 }
3444 delete dispatchEntry;
3445}
3446
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003447int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3448 std::scoped_lock _l(mLock);
3449 sp<Connection> connection = getConnectionLocked(connectionToken);
3450 if (connection == nullptr) {
3451 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3452 connectionToken.get(), events);
3453 return 0; // remove the callback
3454 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003455
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003456 bool notify;
3457 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3458 if (!(events & ALOOPER_EVENT_INPUT)) {
3459 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3460 "events=0x%x",
3461 connection->getInputChannelName().c_str(), events);
3462 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003463 }
3464
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003465 nsecs_t currentTime = now();
3466 bool gotOne = false;
3467 status_t status = OK;
3468 for (;;) {
3469 Result<InputPublisher::ConsumerResponse> result =
3470 connection->inputPublisher.receiveConsumerResponse();
3471 if (!result.ok()) {
3472 status = result.error().code();
3473 break;
3474 }
3475
3476 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3477 const InputPublisher::Finished& finish =
3478 std::get<InputPublisher::Finished>(*result);
3479 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3480 finish.consumeTime);
3481 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003482 if (shouldReportMetricsForConnection(*connection)) {
3483 const InputPublisher::Timeline& timeline =
3484 std::get<InputPublisher::Timeline>(*result);
3485 mLatencyTracker
3486 .trackGraphicsLatency(timeline.inputEventId,
3487 connection->inputChannel->getConnectionToken(),
3488 std::move(timeline.graphicsTimeline));
3489 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003490 }
3491 gotOne = true;
3492 }
3493 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003494 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003495 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003496 return 1;
3497 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003498 }
3499
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003500 notify = status != DEAD_OBJECT || !connection->monitor;
3501 if (notify) {
3502 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3503 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3504 status);
3505 }
3506 } else {
3507 // Monitor channels are never explicitly unregistered.
3508 // We do it automatically when the remote endpoint is closed so don't warn about them.
3509 const bool stillHaveWindowHandle =
3510 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3511 notify = !connection->monitor && stillHaveWindowHandle;
3512 if (notify) {
3513 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3514 connection->getInputChannelName().c_str(), events);
3515 }
3516 }
3517
3518 // Remove the channel.
3519 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3520 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003521}
3522
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003523void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003524 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003525 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003526 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003527 }
3528}
3529
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003530void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003531 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003532 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3533 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3534}
3535
3536void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3537 const CancelationOptions& options,
3538 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3539 for (const auto& it : monitorsByDisplay) {
3540 const std::vector<Monitor>& monitors = it.second;
3541 for (const Monitor& monitor : monitors) {
3542 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003543 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003544 }
3545}
3546
Michael Wrightd02c5b62014-02-10 15:10:22 -08003547void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003548 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003549 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003550 if (connection == nullptr) {
3551 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003552 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003553
3554 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003555}
3556
3557void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3558 const sp<Connection>& connection, const CancelationOptions& options) {
3559 if (connection->status == Connection::STATUS_BROKEN) {
3560 return;
3561 }
3562
3563 nsecs_t currentTime = now();
3564
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003565 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003566 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003567
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003568 if (cancelationEvents.empty()) {
3569 return;
3570 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003571 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3572 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3573 "with reality: %s, mode=%d.",
3574 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3575 options.mode);
3576 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003577
3578 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003579 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003580 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3581 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003582 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003583 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003584 target.globalScaleFactor = windowInfo->globalScaleFactor;
3585 }
3586 target.inputChannel = connection->inputChannel;
3587 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3588
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003589 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003590 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003591 switch (cancelationEventEntry->type) {
3592 case EventEntry::Type::KEY: {
3593 logOutboundKeyDetails("cancel - ",
3594 static_cast<const KeyEntry&>(*cancelationEventEntry));
3595 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003596 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003597 case EventEntry::Type::MOTION: {
3598 logOutboundMotionDetails("cancel - ",
3599 static_cast<const MotionEntry&>(*cancelationEventEntry));
3600 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003601 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003602 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003603 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003604 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3605 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003606 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Dominik Laskowski75788452021-02-09 18:51:25 -08003607 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003608 break;
3609 }
3610 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003611 case EventEntry::Type::DEVICE_RESET:
3612 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003613 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003614 ftl::enum_string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003615 break;
3616 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003617 }
3618
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003619 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3620 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003621 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003622
3623 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003624}
3625
Svet Ganov5d3bc372020-01-26 23:11:07 -08003626void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3627 const sp<Connection>& connection) {
3628 if (connection->status == Connection::STATUS_BROKEN) {
3629 return;
3630 }
3631
3632 nsecs_t currentTime = now();
3633
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003634 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003635 connection->inputState.synthesizePointerDownEvents(currentTime);
3636
3637 if (downEvents.empty()) {
3638 return;
3639 }
3640
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003641 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003642 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3643 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003644 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003645
3646 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003647 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003648 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3649 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003650 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003651 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003652 target.globalScaleFactor = windowInfo->globalScaleFactor;
3653 }
3654 target.inputChannel = connection->inputChannel;
3655 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3656
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003657 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003658 switch (downEventEntry->type) {
3659 case EventEntry::Type::MOTION: {
3660 logOutboundMotionDetails("down - ",
3661 static_cast<const MotionEntry&>(*downEventEntry));
3662 break;
3663 }
3664
3665 case EventEntry::Type::KEY:
3666 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003667 case EventEntry::Type::TOUCH_MODE_CHANGED:
Svet Ganov5d3bc372020-01-26 23:11:07 -08003668 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003669 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003670 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003671 case EventEntry::Type::SENSOR:
3672 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003673 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Dominik Laskowski75788452021-02-09 18:51:25 -08003674 ftl::enum_string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003675 break;
3676 }
3677 }
3678
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003679 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3680 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003681 }
3682
3683 startDispatchCycleLocked(currentTime, connection);
3684}
3685
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003686std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3687 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003688 ALOG_ASSERT(pointerIds.value != 0);
3689
3690 uint32_t splitPointerIndexMap[MAX_POINTERS];
3691 PointerProperties splitPointerProperties[MAX_POINTERS];
3692 PointerCoords splitPointerCoords[MAX_POINTERS];
3693
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003694 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003695 uint32_t splitPointerCount = 0;
3696
3697 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003698 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003699 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003700 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003701 uint32_t pointerId = uint32_t(pointerProperties.id);
3702 if (pointerIds.hasBit(pointerId)) {
3703 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3704 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3705 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003706 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003707 splitPointerCount += 1;
3708 }
3709 }
3710
3711 if (splitPointerCount != pointerIds.count()) {
3712 // This is bad. We are missing some of the pointers that we expected to deliver.
3713 // Most likely this indicates that we received an ACTION_MOVE events that has
3714 // different pointer ids than we expected based on the previous ACTION_DOWN
3715 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3716 // in this way.
3717 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003718 "we expected there to be %d pointers. This probably means we received "
3719 "a broken sequence of pointer ids from the input device.",
3720 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003721 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003722 }
3723
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003724 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003725 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003726 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3727 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003728 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3729 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003730 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003731 uint32_t pointerId = uint32_t(pointerProperties.id);
3732 if (pointerIds.hasBit(pointerId)) {
3733 if (pointerIds.count() == 1) {
3734 // The first/last pointer went down/up.
3735 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003736 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003737 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3738 ? AMOTION_EVENT_ACTION_CANCEL
3739 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003740 } else {
3741 // A secondary pointer went down/up.
3742 uint32_t splitPointerIndex = 0;
3743 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3744 splitPointerIndex += 1;
3745 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003746 action = maskedAction |
3747 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003748 }
3749 } else {
3750 // An unrelated pointer changed.
3751 action = AMOTION_EVENT_ACTION_MOVE;
3752 }
3753 }
3754
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003755 int32_t newId = mIdGenerator.nextId();
3756 if (ATRACE_ENABLED()) {
3757 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3758 ") to MotionEvent(id=0x%" PRIx32 ").",
3759 originalMotionEntry.id, newId);
3760 ATRACE_NAME(message.c_str());
3761 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003762 std::unique_ptr<MotionEntry> splitMotionEntry =
3763 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3764 originalMotionEntry.deviceId, originalMotionEntry.source,
3765 originalMotionEntry.displayId,
3766 originalMotionEntry.policyFlags, action,
3767 originalMotionEntry.actionButton,
3768 originalMotionEntry.flags, originalMotionEntry.metaState,
3769 originalMotionEntry.buttonState,
3770 originalMotionEntry.classification,
3771 originalMotionEntry.edgeFlags,
3772 originalMotionEntry.xPrecision,
3773 originalMotionEntry.yPrecision,
3774 originalMotionEntry.xCursorPosition,
3775 originalMotionEntry.yCursorPosition,
3776 originalMotionEntry.downTime, splitPointerCount,
3777 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003778
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003779 if (originalMotionEntry.injectionState) {
3780 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003781 splitMotionEntry->injectionState->refCount += 1;
3782 }
3783
3784 return splitMotionEntry;
3785}
3786
3787void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003788 if (DEBUG_INBOUND_EVENT_DETAILS) {
3789 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3790 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791
Antonio Kantekf16f2832021-09-28 04:39:20 +00003792 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003793 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003794 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003795
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003796 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3797 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3798 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003799 } // release lock
3800
3801 if (needWake) {
3802 mLooper->wake();
3803 }
3804}
3805
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003806/**
3807 * If one of the meta shortcuts is detected, process them here:
3808 * Meta + Backspace -> generate BACK
3809 * Meta + Enter -> generate HOME
3810 * This will potentially overwrite keyCode and metaState.
3811 */
3812void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003813 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003814 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3815 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3816 if (keyCode == AKEYCODE_DEL) {
3817 newKeyCode = AKEYCODE_BACK;
3818 } else if (keyCode == AKEYCODE_ENTER) {
3819 newKeyCode = AKEYCODE_HOME;
3820 }
3821 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003822 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003823 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003824 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003825 keyCode = newKeyCode;
3826 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3827 }
3828 } else if (action == AKEY_EVENT_ACTION_UP) {
3829 // In order to maintain a consistent stream of up and down events, check to see if the key
3830 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3831 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003832 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003833 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003834 auto replacementIt = mReplacedKeys.find(replacement);
3835 if (replacementIt != mReplacedKeys.end()) {
3836 keyCode = replacementIt->second;
3837 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003838 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3839 }
3840 }
3841}
3842
Michael Wrightd02c5b62014-02-10 15:10:22 -08003843void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003844 if (DEBUG_INBOUND_EVENT_DETAILS) {
3845 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3846 "policyFlags=0x%x, action=0x%x, "
3847 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3848 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3849 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3850 args->downTime);
3851 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003852 if (!validateKeyEvent(args->action)) {
3853 return;
3854 }
3855
3856 uint32_t policyFlags = args->policyFlags;
3857 int32_t flags = args->flags;
3858 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003859 // InputDispatcher tracks and generates key repeats on behalf of
3860 // whatever notifies it, so repeatCount should always be set to 0
3861 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003862 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3863 policyFlags |= POLICY_FLAG_VIRTUAL;
3864 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3865 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003866 if (policyFlags & POLICY_FLAG_FUNCTION) {
3867 metaState |= AMETA_FUNCTION_ON;
3868 }
3869
3870 policyFlags |= POLICY_FLAG_TRUSTED;
3871
Michael Wright78f24442014-08-06 15:55:28 -07003872 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003873 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003874
Michael Wrightd02c5b62014-02-10 15:10:22 -08003875 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003876 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003877 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3878 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003879
Michael Wright2b3c3302018-03-02 17:19:13 +00003880 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003881 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003882 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3883 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003884 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003885 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003886
Antonio Kantekf16f2832021-09-28 04:39:20 +00003887 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003888 { // acquire lock
3889 mLock.lock();
3890
3891 if (shouldSendKeyToInputFilterLocked(args)) {
3892 mLock.unlock();
3893
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003894 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003895 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3896 return; // event was consumed by the filter
3897 }
3898
3899 mLock.lock();
3900 }
3901
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003902 std::unique_ptr<KeyEntry> newEntry =
3903 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3904 args->displayId, policyFlags, args->action, flags,
3905 keyCode, args->scanCode, metaState, repeatCount,
3906 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003907
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003908 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003909 mLock.unlock();
3910 } // release lock
3911
3912 if (needWake) {
3913 mLooper->wake();
3914 }
3915}
3916
3917bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3918 return mInputFilterEnabled;
3919}
3920
3921void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003922 if (DEBUG_INBOUND_EVENT_DETAILS) {
3923 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3924 "displayId=%" PRId32 ", policyFlags=0x%x, "
3925 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3926 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3927 "yCursorPosition=%f, downTime=%" PRId64,
3928 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3929 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3930 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3931 args->xCursorPosition, args->yCursorPosition, args->downTime);
3932 for (uint32_t i = 0; i < args->pointerCount; i++) {
3933 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3934 "x=%f, y=%f, pressure=%f, size=%f, "
3935 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3936 "orientation=%f",
3937 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3938 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3939 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3940 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3941 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3942 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3943 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3944 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3945 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3946 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3947 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003948 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003949 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3950 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951 return;
3952 }
3953
3954 uint32_t policyFlags = args->policyFlags;
3955 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003956
3957 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003958 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003959 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3960 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003961 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003962 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003963
Antonio Kantekf16f2832021-09-28 04:39:20 +00003964 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003965 { // acquire lock
3966 mLock.lock();
3967
3968 if (shouldSendMotionToInputFilterLocked(args)) {
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003969 ui::Transform displayTransform;
3970 if (const auto it = mDisplayInfos.find(args->displayId); it != mDisplayInfos.end()) {
3971 displayTransform = it->second.transform;
3972 }
3973
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974 mLock.unlock();
3975
3976 MotionEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003977 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3978 args->action, args->actionButton, args->flags, args->edgeFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003979 args->metaState, args->buttonState, args->classification,
Prabir Pradhan81420cc2021-09-06 10:28:50 -07003980 displayTransform, args->xPrecision, args->yPrecision,
3981 args->xCursorPosition, args->yCursorPosition, displayTransform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003982 args->downTime, args->eventTime, args->pointerCount,
3983 args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984
3985 policyFlags |= POLICY_FLAG_FILTERED;
3986 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3987 return; // event was consumed by the filter
3988 }
3989
3990 mLock.lock();
3991 }
3992
3993 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003994 std::unique_ptr<MotionEntry> newEntry =
3995 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3996 args->source, args->displayId, policyFlags,
3997 args->action, args->actionButton, args->flags,
3998 args->metaState, args->buttonState,
3999 args->classification, args->edgeFlags,
4000 args->xPrecision, args->yPrecision,
4001 args->xCursorPosition, args->yCursorPosition,
4002 args->downTime, args->pointerCount,
4003 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004004
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00004005 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4006 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
4007 !mInputFilterEnabled) {
4008 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
4009 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
4010 }
4011
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004012 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004013 mLock.unlock();
4014 } // release lock
4015
4016 if (needWake) {
4017 mLooper->wake();
4018 }
4019}
4020
Chris Yef59a2f42020-10-16 12:55:26 -07004021void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004022 if (DEBUG_INBOUND_EVENT_DETAILS) {
4023 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4024 " sensorType=%s",
4025 args->id, args->eventTime, args->deviceId, args->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08004026 ftl::enum_string(args->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004027 }
Chris Yef59a2f42020-10-16 12:55:26 -07004028
Antonio Kantekf16f2832021-09-28 04:39:20 +00004029 bool needWake = false;
Chris Yef59a2f42020-10-16 12:55:26 -07004030 { // acquire lock
4031 mLock.lock();
4032
4033 // Just enqueue a new sensor event.
4034 std::unique_ptr<SensorEntry> newEntry =
4035 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
4036 args->source, 0 /* policyFlags*/, args->hwTimestamp,
4037 args->sensorType, args->accuracy,
4038 args->accuracyChanged, args->values);
4039
4040 needWake = enqueueInboundEventLocked(std::move(newEntry));
4041 mLock.unlock();
4042 } // release lock
4043
4044 if (needWake) {
4045 mLooper->wake();
4046 }
4047}
4048
Chris Yefb552902021-02-03 17:18:37 -08004049void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004050 if (DEBUG_INBOUND_EVENT_DETAILS) {
4051 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
4052 args->deviceId, args->isOn);
4053 }
Chris Yefb552902021-02-03 17:18:37 -08004054 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
4055}
4056
Michael Wrightd02c5b62014-02-10 15:10:22 -08004057bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08004058 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059}
4060
4061void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004062 if (DEBUG_INBOUND_EVENT_DETAILS) {
4063 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4064 "switchMask=0x%08x",
4065 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
4066 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004067
4068 uint32_t policyFlags = args->policyFlags;
4069 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004070 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004071}
4072
4073void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004074 if (DEBUG_INBOUND_EVENT_DETAILS) {
4075 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
4076 args->deviceId);
4077 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004078
Antonio Kantekf16f2832021-09-28 04:39:20 +00004079 bool needWake = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004080 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004081 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004082
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004083 std::unique_ptr<DeviceResetEntry> newEntry =
4084 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
4085 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004086 } // release lock
4087
4088 if (needWake) {
4089 mLooper->wake();
4090 }
4091}
4092
Prabir Pradhan7e186182020-11-10 13:56:45 -08004093void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004094 if (DEBUG_INBOUND_EVENT_DETAILS) {
4095 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004096 args->request.enable ? "true" : "false");
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004097 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004098
Antonio Kantekf16f2832021-09-28 04:39:20 +00004099 bool needWake = false;
Prabir Pradhan99987712020-11-10 18:43:05 -08004100 { // acquire lock
4101 std::scoped_lock _l(mLock);
4102 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00004103 args->request);
Prabir Pradhan99987712020-11-10 18:43:05 -08004104 needWake = enqueueInboundEventLocked(std::move(entry));
4105 } // release lock
4106
4107 if (needWake) {
4108 mLooper->wake();
4109 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004110}
4111
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004112InputEventInjectionResult InputDispatcher::injectInputEvent(
4113 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4114 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004115 if (DEBUG_INBOUND_EVENT_DETAILS) {
4116 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4117 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4118 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4119 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004120 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004121
4122 policyFlags |= POLICY_FLAG_INJECTED;
4123 if (hasInjectionPermission(injectorPid, injectorUid)) {
4124 policyFlags |= POLICY_FLAG_TRUSTED;
4125 }
4126
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004127 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004128 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4129 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4130 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4131 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4132 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004133 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004134 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004135 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004136 }
4137
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004138 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004139 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004140 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004141 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4142 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004143 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004144 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004145 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004146
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004147 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004148 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4149 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4150 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004151 int32_t keyCode = incomingKey.getKeyCode();
4152 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004153 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004154 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004155 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004156 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004157 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4158 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4159 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004160
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004161 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4162 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004163 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004164
4165 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4166 android::base::Timer t;
4167 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4168 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4169 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4170 std::to_string(t.duration().count()).c_str());
4171 }
4172 }
4173
4174 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004175 std::unique_ptr<KeyEntry> injectedEntry =
4176 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004177 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004178 incomingKey.getDisplayId(), policyFlags, action,
4179 flags, keyCode, incomingKey.getScanCode(), metaState,
4180 incomingKey.getRepeatCount(),
4181 incomingKey.getDownTime());
4182 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004183 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 }
4185
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004186 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004187 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004188 const int32_t action = motionEvent.getAction();
4189 const bool isPointerEvent =
4190 isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4191 // If a pointer event has no displayId specified, inject it to the default display.
4192 const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
4193 ? ADISPLAY_ID_DEFAULT
4194 : event->getDisplayId();
4195 const size_t pointerCount = motionEvent.getPointerCount();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004196 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004197 const int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004198 int32_t flags = motionEvent.getFlags();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004199 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004200 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004201 }
4202
4203 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004204 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004205 android::base::Timer t;
4206 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4207 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4208 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4209 std::to_string(t.duration().count()).c_str());
4210 }
4211 }
4212
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004213 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4214 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4215 }
4216
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004217 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004218 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4219 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004220 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004221 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4222 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004223 displayId, policyFlags, action, actionButton,
4224 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004225 motionEvent.getButtonState(),
4226 motionEvent.getClassification(),
4227 motionEvent.getEdgeFlags(),
4228 motionEvent.getXPrecision(),
4229 motionEvent.getYPrecision(),
4230 motionEvent.getRawXCursorPosition(),
4231 motionEvent.getRawYCursorPosition(),
4232 motionEvent.getDownTime(), uint32_t(pointerCount),
4233 pointerProperties, samplePointerCoords,
4234 motionEvent.getXOffset(),
4235 motionEvent.getYOffset());
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004236 transformMotionEntryForInjectionLocked(*injectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004237 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004238 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004239 sampleEventTimes += 1;
4240 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004241 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004242 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4243 resolvedDeviceId, motionEvent.getSource(),
Prabir Pradhanaa561d12021-09-24 06:57:33 -07004244 displayId, policyFlags, action, actionButton,
4245 flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004246 motionEvent.getButtonState(),
4247 motionEvent.getClassification(),
4248 motionEvent.getEdgeFlags(),
4249 motionEvent.getXPrecision(),
4250 motionEvent.getYPrecision(),
4251 motionEvent.getRawXCursorPosition(),
4252 motionEvent.getRawYCursorPosition(),
4253 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004254 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004255 samplePointerCoords, motionEvent.getXOffset(),
4256 motionEvent.getYOffset());
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004257 transformMotionEntryForInjectionLocked(*nextInjectedEntry);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004258 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004259 }
4260 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004261 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004262
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004263 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004264 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004265 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004266 }
4267
4268 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004269 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004270 injectionState->injectionIsAsync = true;
4271 }
4272
4273 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004274 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275
4276 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004277 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004278 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004279 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004280 }
4281
4282 mLock.unlock();
4283
4284 if (needWake) {
4285 mLooper->wake();
4286 }
4287
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004288 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004290 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004291
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004292 if (syncMode == InputEventInjectionSync::NONE) {
4293 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004294 } else {
4295 for (;;) {
4296 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004297 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004298 break;
4299 }
4300
4301 nsecs_t remainingTimeout = endTime - now();
4302 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004303 if (DEBUG_INJECTION) {
4304 ALOGD("injectInputEvent - Timed out waiting for injection result "
4305 "to become available.");
4306 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004307 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004308 break;
4309 }
4310
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004311 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004312 }
4313
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004314 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4315 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004316 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004317 if (DEBUG_INJECTION) {
4318 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4319 injectionState->pendingForegroundDispatches);
4320 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004321 nsecs_t remainingTimeout = endTime - now();
4322 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004323 if (DEBUG_INJECTION) {
4324 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4325 "dispatches to finish.");
4326 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004327 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004328 break;
4329 }
4330
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004331 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004332 }
4333 }
4334 }
4335
4336 injectionState->release();
4337 } // release lock
4338
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004339 if (DEBUG_INJECTION) {
4340 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4341 injectionResult, injectorPid, injectorUid);
4342 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004343
4344 return injectionResult;
4345}
4346
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004347std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004348 std::array<uint8_t, 32> calculatedHmac;
4349 std::unique_ptr<VerifiedInputEvent> result;
4350 switch (event.getType()) {
4351 case AINPUT_EVENT_TYPE_KEY: {
4352 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4353 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4354 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004355 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004356 break;
4357 }
4358 case AINPUT_EVENT_TYPE_MOTION: {
4359 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4360 VerifiedMotionEvent verifiedMotionEvent =
4361 verifiedMotionEventFromMotionEvent(motionEvent);
4362 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004363 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004364 break;
4365 }
4366 default: {
4367 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4368 return nullptr;
4369 }
4370 }
4371 if (calculatedHmac == INVALID_HMAC) {
4372 return nullptr;
4373 }
4374 if (calculatedHmac != event.getHmac()) {
4375 return nullptr;
4376 }
4377 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004378}
4379
Michael Wrightd02c5b62014-02-10 15:10:22 -08004380bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004381 return injectorUid == 0 ||
4382 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004383}
4384
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004385void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004386 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004387 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004388 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004389 if (DEBUG_INJECTION) {
4390 ALOGD("Setting input event injection result to %d. "
4391 "injectorPid=%d, injectorUid=%d",
4392 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4393 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004394
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004395 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004396 // Log the outcome since the injector did not wait for the injection result.
4397 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004398 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004399 ALOGV("Asynchronous input event injection succeeded.");
4400 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004401 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004402 ALOGW("Asynchronous input event injection failed.");
4403 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004404 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004405 ALOGW("Asynchronous input event injection permission denied.");
4406 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004407 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004408 ALOGW("Asynchronous input event injection timed out.");
4409 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004410 case InputEventInjectionResult::PENDING:
4411 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4412 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004413 }
4414 }
4415
4416 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004417 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004418 }
4419}
4420
Prabir Pradhan81420cc2021-09-06 10:28:50 -07004421void InputDispatcher::transformMotionEntryForInjectionLocked(MotionEntry& entry) const {
4422 const bool isRelativeMouseEvent = isFromSource(entry.source, AINPUT_SOURCE_MOUSE_RELATIVE);
4423 if (!isRelativeMouseEvent && !isFromSource(entry.source, AINPUT_SOURCE_CLASS_POINTER)) {
4424 return;
4425 }
4426
4427 // Input injection works in the logical display coordinate space, but the input pipeline works
4428 // display space, so we need to transform the injected events accordingly.
4429 const auto it = mDisplayInfos.find(entry.displayId);
4430 if (it == mDisplayInfos.end()) return;
4431 const auto& transformToDisplay = it->second.transform.inverse();
4432
4433 for (uint32_t i = 0; i < entry.pointerCount; i++) {
4434 PointerCoords& pc = entry.pointerCoords[i];
4435 const auto xy = isRelativeMouseEvent
4436 ? transformWithoutTranslation(transformToDisplay, pc.getX(), pc.getY())
4437 : transformToDisplay.transform(pc.getXYValue());
4438 pc.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
4439 pc.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
4440
4441 // Axes with relative values never represent points on a screen, so they should never have
4442 // translation applied. If a device does not report relative values, these values are always
4443 // 0, and will remain unaffected by the following operation.
4444 const auto rel =
4445 transformWithoutTranslation(transformToDisplay,
4446 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
4447 pc.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
4448 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, rel.x);
4449 pc.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, rel.y);
4450 }
4451}
4452
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004453void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4454 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004455 if (injectionState) {
4456 injectionState->pendingForegroundDispatches += 1;
4457 }
4458}
4459
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004460void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4461 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004462 if (injectionState) {
4463 injectionState->pendingForegroundDispatches -= 1;
4464
4465 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004466 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004467 }
4468 }
4469}
4470
chaviw98318de2021-05-19 16:45:23 -05004471const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004472 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004473 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004474 auto it = mWindowHandlesByDisplay.find(displayId);
4475 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004476}
4477
chaviw98318de2021-05-19 16:45:23 -05004478sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004479 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004480 if (windowHandleToken == nullptr) {
4481 return nullptr;
4482 }
4483
Arthur Hungb92218b2018-08-14 12:00:21 +08004484 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004485 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4486 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004487 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004488 return windowHandle;
4489 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004490 }
4491 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004492 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004493}
4494
chaviw98318de2021-05-19 16:45:23 -05004495sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4496 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004497 if (windowHandleToken == nullptr) {
4498 return nullptr;
4499 }
4500
chaviw98318de2021-05-19 16:45:23 -05004501 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004502 if (windowHandle->getToken() == windowHandleToken) {
4503 return windowHandle;
4504 }
4505 }
4506 return nullptr;
4507}
4508
chaviw98318de2021-05-19 16:45:23 -05004509sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4510 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004511 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004512 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4513 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004514 if (handle->getId() == windowHandle->getId() &&
4515 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004516 if (windowHandle->getInfo()->displayId != it.first) {
4517 ALOGE("Found window %s in display %" PRId32
4518 ", but it should belong to display %" PRId32,
4519 windowHandle->getName().c_str(), it.first,
4520 windowHandle->getInfo()->displayId);
4521 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004522 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004523 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004524 }
4525 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004526 return nullptr;
4527}
4528
chaviw98318de2021-05-19 16:45:23 -05004529sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004530 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4531 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004532}
4533
chaviw98318de2021-05-19 16:45:23 -05004534bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004535 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4536 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004537 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004538 if (connection != nullptr && noInputChannel) {
4539 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4540 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4541 return false;
4542 }
4543
4544 if (connection == nullptr) {
4545 if (!noInputChannel) {
4546 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4547 }
4548 return false;
4549 }
4550 if (!connection->responsive) {
4551 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4552 return false;
4553 }
4554 return true;
4555}
4556
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004557std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4558 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004559 auto connectionIt = mConnectionsByToken.find(token);
4560 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004561 return nullptr;
4562 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004563 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004564}
4565
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004566void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004567 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4568 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004569 // Remove all handles on a display if there are no windows left.
4570 mWindowHandlesByDisplay.erase(displayId);
4571 return;
4572 }
4573
4574 // Since we compare the pointer of input window handles across window updates, we need
4575 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004576 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4577 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4578 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004579 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004580 }
4581
chaviw98318de2021-05-19 16:45:23 -05004582 std::vector<sp<WindowInfoHandle>> newHandles;
4583 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004584 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004585 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004586 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004587 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4588 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4589 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004590 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004591 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004592 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004593 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004594 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004595 }
4596
4597 if (info->displayId != displayId) {
4598 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4599 handle->getName().c_str(), displayId, info->displayId);
4600 continue;
4601 }
4602
Robert Carredd13602020-04-13 17:24:34 -07004603 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4604 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004605 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004606 oldHandle->updateFrom(handle);
4607 newHandles.push_back(oldHandle);
4608 } else {
4609 newHandles.push_back(handle);
4610 }
4611 }
4612
4613 // Insert or replace
4614 mWindowHandlesByDisplay[displayId] = newHandles;
4615}
4616
Arthur Hung72d8dc32020-03-28 00:48:39 +00004617void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004618 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004619 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004620 { // acquire lock
4621 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004622 for (const auto& [displayId, handles] : handlesPerDisplay) {
4623 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004624 }
4625 }
4626 // Wake up poll loop since it may need to make new input dispatching choices.
4627 mLooper->wake();
4628}
4629
Arthur Hungb92218b2018-08-14 12:00:21 +08004630/**
4631 * Called from InputManagerService, update window handle list by displayId that can receive input.
4632 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4633 * If set an empty list, remove all handles from the specific display.
4634 * For focused handle, check if need to change and send a cancel event to previous one.
4635 * For removed handle, check if need to send a cancel event if already in touch.
4636 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004637void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004638 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004639 if (DEBUG_FOCUS) {
4640 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004641 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004642 windowList += iwh->getName() + " ";
4643 }
4644 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4645 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004647 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004648 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004649 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004650 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004651 if (noInputWindow && window->getToken() != nullptr) {
4652 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4653 window->getName().c_str());
4654 window->releaseChannel();
4655 }
4656 }
4657
Arthur Hung72d8dc32020-03-28 00:48:39 +00004658 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004659 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004660
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004661 // Save the old windows' orientation by ID before it gets updated.
4662 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004663 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004664 oldWindowOrientations.emplace(handle->getId(),
4665 handle->getInfo()->transform.getOrientation());
4666 }
4667
chaviw98318de2021-05-19 16:45:23 -05004668 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004669
chaviw98318de2021-05-19 16:45:23 -05004670 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004671 if (mLastHoverWindowHandle &&
4672 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4673 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004674 mLastHoverWindowHandle = nullptr;
4675 }
4676
Vishnu Nairc519ff72021-01-21 08:23:08 -08004677 std::optional<FocusResolver::FocusChanges> changes =
4678 mFocusResolver.setInputWindows(displayId, windowHandles);
4679 if (changes) {
4680 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004681 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004682
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004683 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4684 mTouchStatesByDisplay.find(displayId);
4685 if (stateIt != mTouchStatesByDisplay.end()) {
4686 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004687 for (size_t i = 0; i < state.windows.size();) {
4688 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004689 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004690 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004691 ALOGD("Touched window was removed: %s in display %" PRId32,
4692 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004693 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004694 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004695 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4696 if (touchedInputChannel != nullptr) {
4697 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4698 "touched window was removed");
4699 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Siarhei Vishniakouca205502021-07-16 21:31:58 +00004700 // Since we are about to drop the touch, cancel the events for the wallpaper as
4701 // well.
4702 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND &&
4703 touchedWindow.windowHandle->getInfo()->hasWallpaper) {
4704 sp<WindowInfoHandle> wallpaper = state.getWallpaperWindow();
4705 if (wallpaper != nullptr) {
4706 sp<Connection> wallpaperConnection =
4707 getConnectionLocked(wallpaper->getToken());
4708 synthesizeCancelationEventsForConnectionLocked(wallpaperConnection,
4709 options);
4710 }
4711 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004712 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004713 state.windows.erase(state.windows.begin() + i);
4714 } else {
4715 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004716 }
4717 }
arthurhungb89ccb02020-12-30 16:19:01 +08004718
arthurhung6d4bed92021-03-17 11:59:33 +08004719 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004720 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004721 if (mDragState &&
4722 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004723 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004724 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004725 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004726 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004727
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004728 if (isPerWindowInputRotationEnabled()) {
4729 // Determine if the orientation of any of the input windows have changed, and cancel all
4730 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004731 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4732 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004733 if (newWindowHandle != nullptr &&
4734 newWindowHandle->getInfo()->transform.getOrientation() !=
4735 oldWindowOrientations[oldWindowHandle->getId()]) {
4736 std::shared_ptr<InputChannel> inputChannel =
4737 getInputChannelLocked(newWindowHandle->getToken());
4738 if (inputChannel != nullptr) {
4739 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4740 "touched window's orientation changed");
4741 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4742 }
4743 }
4744 }
4745 }
4746
Arthur Hung72d8dc32020-03-28 00:48:39 +00004747 // Release information for windows that are no longer present.
4748 // This ensures that unused input channels are released promptly.
4749 // Otherwise, they might stick around until the window handle is destroyed
4750 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004751 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004752 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004753 if (DEBUG_FOCUS) {
4754 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004755 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004756 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004757 // To avoid making too many calls into the compat framework, only
4758 // check for window flags when windows are going away.
4759 // TODO(b/157929241) : delete this. This is only needed temporarily
4760 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004761 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004762 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4763 oldWindowHandle->getName().c_str());
4764 if (mCompatService != nullptr) {
4765 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4766 oldWindowHandle->getInfo()->ownerUid);
4767 }
4768 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004769 }
chaviw291d88a2019-02-14 10:33:58 -08004770 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004771}
4772
4773void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004774 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004775 if (DEBUG_FOCUS) {
4776 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4777 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4778 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004779 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004780 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004781 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004782 } // release lock
4783
4784 // Wake up poll loop since it may need to make new input dispatching choices.
4785 mLooper->wake();
4786}
4787
Vishnu Nair599f1412021-06-21 10:39:58 -07004788void InputDispatcher::setFocusedApplicationLocked(
4789 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4790 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4791 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4792
4793 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4794 return; // This application is already focused. No need to wake up or change anything.
4795 }
4796
4797 // Set the new application handle.
4798 if (inputApplicationHandle != nullptr) {
4799 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4800 } else {
4801 mFocusedApplicationHandlesByDisplay.erase(displayId);
4802 }
4803
4804 // No matter what the old focused application was, stop waiting on it because it is
4805 // no longer focused.
4806 resetNoFocusedWindowTimeoutLocked();
4807}
4808
Tiger Huang721e26f2018-07-24 22:26:19 +08004809/**
4810 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4811 * the display not specified.
4812 *
4813 * We track any unreleased events for each window. If a window loses the ability to receive the
4814 * released event, we will send a cancel event to it. So when the focused display is changed, we
4815 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4816 * display. The display-specified events won't be affected.
4817 */
4818void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004819 if (DEBUG_FOCUS) {
4820 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4821 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004822 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004823 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004824
4825 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004826 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004827 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004828 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004829 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004830 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004831 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004832 CancelationOptions
4833 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4834 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004835 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004836 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4837 }
4838 }
4839 mFocusedDisplayId = displayId;
4840
Chris Ye3c2d6f52020-08-09 10:39:48 -07004841 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004842 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004843 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004844
Vishnu Nairad321cd2020-08-20 16:40:21 -07004845 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004846 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004847 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004848 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004849 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004850 }
4851 }
4852 }
4853
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004854 if (DEBUG_FOCUS) {
4855 logDispatchStateLocked();
4856 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004857 } // release lock
4858
4859 // Wake up poll loop since it may need to make new input dispatching choices.
4860 mLooper->wake();
4861}
4862
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004864 if (DEBUG_FOCUS) {
4865 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4866 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867
4868 bool changed;
4869 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004870 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004871
4872 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4873 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004874 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004875 }
4876
4877 if (mDispatchEnabled && !enabled) {
4878 resetAndDropEverythingLocked("dispatcher is being disabled");
4879 }
4880
4881 mDispatchEnabled = enabled;
4882 mDispatchFrozen = frozen;
4883 changed = true;
4884 } else {
4885 changed = false;
4886 }
4887
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004888 if (DEBUG_FOCUS) {
4889 logDispatchStateLocked();
4890 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004891 } // release lock
4892
4893 if (changed) {
4894 // Wake up poll loop since it may need to make new input dispatching choices.
4895 mLooper->wake();
4896 }
4897}
4898
4899void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004900 if (DEBUG_FOCUS) {
4901 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4902 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004903
4904 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004905 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004906
4907 if (mInputFilterEnabled == enabled) {
4908 return;
4909 }
4910
4911 mInputFilterEnabled = enabled;
4912 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4913 } // release lock
4914
4915 // Wake up poll loop since there might be work to do to drop everything.
4916 mLooper->wake();
4917}
4918
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004919void InputDispatcher::setInTouchMode(bool inTouchMode) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00004920 bool needWake = false;
4921 {
4922 std::scoped_lock lock(mLock);
4923 if (mInTouchMode == inTouchMode) {
4924 return;
4925 }
4926 if (DEBUG_TOUCH_MODE) {
4927 ALOGD("Request to change touch mode from %s to %s", toString(mInTouchMode),
4928 toString(inTouchMode));
4929 // TODO(b/198487159): Also print the current last interacted apps.
4930 }
4931
4932 // TODO(b/198499018): Store touch mode per display.
4933 mInTouchMode = inTouchMode;
4934
4935 // TODO(b/198487159): Enforce that only last interacted apps can change touch mode.
4936 auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode);
4937 needWake = enqueueInboundEventLocked(std::move(entry));
4938 } // release lock
4939
4940 if (needWake) {
4941 mLooper->wake();
4942 }
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004943}
4944
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004945void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4946 if (opacity < 0 || opacity > 1) {
4947 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4948 return;
4949 }
4950
4951 std::scoped_lock lock(mLock);
4952 mMaximumObscuringOpacityForTouch = opacity;
4953}
4954
4955void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4956 std::scoped_lock lock(mLock);
4957 mBlockUntrustedTouchesMode = mode;
4958}
4959
Arthur Hungabbb9d82021-09-01 14:52:30 +00004960std::pair<TouchState*, TouchedWindow*> InputDispatcher::findTouchStateAndWindowLocked(
4961 const sp<IBinder>& token) {
4962 for (auto& [displayId, state] : mTouchStatesByDisplay) {
4963 for (TouchedWindow& w : state.windows) {
4964 if (w.windowHandle->getToken() == token) {
4965 return std::make_pair(&state, &w);
4966 }
4967 }
4968 }
4969 return std::make_pair(nullptr, nullptr);
4970}
4971
arthurhungb89ccb02020-12-30 16:19:01 +08004972bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4973 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004974 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004975 if (DEBUG_FOCUS) {
4976 ALOGD("Trivial transfer to same window.");
4977 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004978 return true;
4979 }
4980
Michael Wrightd02c5b62014-02-10 15:10:22 -08004981 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004982 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983
Arthur Hungabbb9d82021-09-01 14:52:30 +00004984 // Find the target touch state and touched window by fromToken.
4985 auto [state, touchedWindow] = findTouchStateAndWindowLocked(fromToken);
4986 if (state == nullptr || touchedWindow == nullptr) {
4987 ALOGD("Focus transfer failed because from window is not being touched.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004988 return false;
4989 }
Arthur Hungabbb9d82021-09-01 14:52:30 +00004990
4991 const int32_t displayId = state->displayId;
4992 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
4993 if (toWindowHandle == nullptr) {
4994 ALOGW("Cannot transfer focus because to window not found.");
4995 return false;
4996 }
4997
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004998 if (DEBUG_FOCUS) {
4999 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
Arthur Hungabbb9d82021-09-01 14:52:30 +00005000 touchedWindow->windowHandle->getName().c_str(),
5001 toWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005002 }
5003
Arthur Hungabbb9d82021-09-01 14:52:30 +00005004 // Erase old window.
5005 int32_t oldTargetFlags = touchedWindow->targetFlags;
5006 BitSet32 pointerIds = touchedWindow->pointerIds;
5007 state->removeWindowByToken(fromToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005008
Arthur Hungabbb9d82021-09-01 14:52:30 +00005009 // Add new window.
5010 int32_t newTargetFlags = oldTargetFlags &
5011 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
5012 InputTarget::FLAG_DISPATCH_AS_IS);
5013 state->addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005014
Arthur Hungabbb9d82021-09-01 14:52:30 +00005015 // Store the dragging window.
5016 if (isDragDrop) {
5017 mDragState = std::make_unique<DragState>(toWindowHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005018 }
5019
Arthur Hungabbb9d82021-09-01 14:52:30 +00005020 // Synthesize cancel for old window and down for new window.
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005021 sp<Connection> fromConnection = getConnectionLocked(fromToken);
5022 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005023 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08005024 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005025 CancelationOptions
5026 options(CancelationOptions::CANCEL_POINTER_EVENTS,
5027 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005028 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08005029 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005030 }
5031
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005032 if (DEBUG_FOCUS) {
5033 logDispatchStateLocked();
5034 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005035 } // release lock
5036
5037 // Wake up poll loop since it may need to make new input dispatching choices.
5038 mLooper->wake();
5039 return true;
5040}
5041
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005042// Binder call
5043bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
5044 sp<IBinder> fromToken;
5045 { // acquire lock
5046 std::scoped_lock _l(mLock);
5047
Arthur Hungabbb9d82021-09-01 14:52:30 +00005048 auto it = std::find_if(mTouchStatesByDisplay.begin(), mTouchStatesByDisplay.end(),
5049 [](const auto& pair) { return pair.second.windows.size() == 1; });
5050 if (it == mTouchStatesByDisplay.end()) {
5051 ALOGW("Cannot transfer touch state because there is no exact window being touched");
5052 return false;
5053 }
5054 const int32_t displayId = it->first;
5055 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005056 if (toWindowHandle == nullptr) {
5057 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
5058 return false;
5059 }
5060
Arthur Hungabbb9d82021-09-01 14:52:30 +00005061 TouchState& state = it->second;
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00005062 const TouchedWindow& touchedWindow = state.windows[0];
5063 fromToken = touchedWindow.windowHandle->getToken();
5064 } // release lock
5065
5066 return transferTouchFocus(fromToken, destChannelToken);
5067}
5068
Michael Wrightd02c5b62014-02-10 15:10:22 -08005069void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01005070 if (DEBUG_FOCUS) {
5071 ALOGD("Resetting and dropping all events (%s).", reason);
5072 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005073
5074 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
5075 synthesizeCancelationEventsForAllConnectionsLocked(options);
5076
5077 resetKeyRepeatLocked();
5078 releasePendingEventLocked();
5079 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005080 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005081
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005082 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08005083 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005084 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07005085 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005086}
5087
5088void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005089 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005090 dumpDispatchStateLocked(dump);
5091
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005092 std::istringstream stream(dump);
5093 std::string line;
5094
5095 while (std::getline(stream, line, '\n')) {
5096 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005097 }
5098}
5099
Prabir Pradhan99987712020-11-10 18:43:05 -08005100std::string InputDispatcher::dumpPointerCaptureStateLocked() {
5101 std::string dump;
5102
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005103 dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5104 toString(mCurrentPointerCaptureRequest.enable));
Prabir Pradhan99987712020-11-10 18:43:05 -08005105
5106 std::string windowName = "None";
5107 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05005108 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08005109 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5110 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5111 : "token has capture without window";
5112 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005113 dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
Prabir Pradhan99987712020-11-10 18:43:05 -08005114
5115 return dump;
5116}
5117
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005118void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07005119 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5120 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5121 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08005122 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005123
Tiger Huang721e26f2018-07-24 22:26:19 +08005124 if (!mFocusedApplicationHandlesByDisplay.empty()) {
5125 dump += StringPrintf(INDENT "FocusedApplications:\n");
5126 for (auto& it : mFocusedApplicationHandlesByDisplay) {
5127 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07005128 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005129 const std::chrono::duration timeout =
5130 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005131 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005132 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05005133 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08005134 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005135 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08005136 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005137 }
Tiger Huang721e26f2018-07-24 22:26:19 +08005138
Vishnu Nairc519ff72021-01-21 08:23:08 -08005139 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08005140 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005141
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005142 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005143 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005144 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
5145 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005146 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005147 state.displayId, toString(state.down), toString(state.split),
5148 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005149 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005150 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005151 for (size_t i = 0; i < state.windows.size(); i++) {
5152 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005153 dump += StringPrintf(INDENT4
5154 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5155 i, touchedWindow.windowHandle->getName().c_str(),
5156 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005157 }
5158 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005159 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005160 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005161 }
5162 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005163 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005164 }
5165
arthurhung6d4bed92021-03-17 11:59:33 +08005166 if (mDragState) {
5167 dump += StringPrintf(INDENT "DragState:\n");
5168 mDragState->dump(dump, INDENT2);
5169 }
5170
Arthur Hungb92218b2018-08-14 12:00:21 +08005171 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005172 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5173 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5174 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5175 const auto& displayInfo = it->second;
5176 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5177 displayInfo.logicalHeight);
5178 displayInfo.transform.dump(dump, "transform", INDENT4);
5179 } else {
5180 dump += INDENT2 "No DisplayInfo found!\n";
5181 }
5182
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005183 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005184 dump += INDENT2 "Windows:\n";
5185 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005186 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5187 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005188
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005189 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005190 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005191 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005192 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005193 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005194 "applicationInfo.name=%s, "
5195 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005196 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005197 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005198 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005199 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005200 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005201 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005202 windowInfo->flags.string().c_str(),
Dominik Laskowski75788452021-02-09 18:51:25 -08005203 ftl::enum_string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005204 windowInfo->frameLeft, windowInfo->frameTop,
5205 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005206 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005207 windowInfo->applicationInfo.name.c_str(),
5208 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005209 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005210 dump += StringPrintf(", inputFeatures=%s",
5211 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005212 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005213 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005214 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005215 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005216 millis(windowInfo->dispatchingTimeout),
5217 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005218 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005219 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005220 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005221 }
5222 } else {
5223 dump += INDENT2 "Windows: <none>\n";
5224 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005225 }
5226 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005227 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005228 }
5229
Michael Wright3dd60e22019-03-27 22:06:44 +00005230 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005231 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005232 const std::vector<Monitor>& monitors = it.second;
5233 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5234 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005235 }
5236 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005237 const std::vector<Monitor>& monitors = it.second;
5238 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5239 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005240 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005241 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005242 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005243 }
5244
5245 nsecs_t currentTime = now();
5246
5247 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005248 if (!mRecentQueue.empty()) {
5249 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005250 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005251 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005252 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005253 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005254 }
5255 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005256 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005257 }
5258
5259 // Dump event currently being dispatched.
5260 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005261 dump += INDENT "PendingEvent:\n";
5262 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005263 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005264 dump += StringPrintf(", age=%" PRId64 "ms\n",
5265 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005266 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005267 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005268 }
5269
5270 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005271 if (!mInboundQueue.empty()) {
5272 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005273 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005274 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005275 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005276 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005277 }
5278 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005279 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005280 }
5281
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005282 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005283 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005284 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5285 const KeyReplacement& replacement = pair.first;
5286 int32_t newKeyCode = pair.second;
5287 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005288 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005289 }
5290 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005291 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005292 }
5293
Prabir Pradhancef936d2021-07-21 16:17:52 +00005294 if (!mCommandQueue.empty()) {
5295 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5296 } else {
5297 dump += INDENT "CommandQueue: <empty>\n";
5298 }
5299
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005300 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005301 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005302 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005303 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005304 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005305 connection->inputChannel->getFd().get(),
5306 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005307 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005308 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005309
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005310 if (!connection->outboundQueue.empty()) {
5311 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5312 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005313 dump += dumpQueue(connection->outboundQueue, currentTime);
5314
Michael Wrightd02c5b62014-02-10 15:10:22 -08005315 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005316 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005317 }
5318
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005319 if (!connection->waitQueue.empty()) {
5320 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5321 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005322 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005323 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005324 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005325 }
5326 }
5327 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005328 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329 }
5330
5331 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005332 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5333 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005334 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005335 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005336 }
5337
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005338 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005339 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5340 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5341 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005342 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005343 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005344}
5345
Michael Wright3dd60e22019-03-27 22:06:44 +00005346void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5347 const size_t numMonitors = monitors.size();
5348 for (size_t i = 0; i < numMonitors; i++) {
5349 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005350 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005351 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5352 dump += "\n";
5353 }
5354}
5355
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005356class LooperEventCallback : public LooperCallback {
5357public:
5358 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5359 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5360
5361private:
5362 std::function<int(int events)> mCallback;
5363};
5364
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005365Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005366 if (DEBUG_CHANNEL_CREATION) {
5367 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5368 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005369
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005370 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005371 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005372 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005373
5374 if (result) {
5375 return base::Error(result) << "Failed to open input channel pair with name " << name;
5376 }
5377
Michael Wrightd02c5b62014-02-10 15:10:22 -08005378 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005379 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005380 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005381 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005382 sp<Connection> connection =
5383 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005384
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005385 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5386 ALOGE("Created a new connection, but the token %p is already known", token.get());
5387 }
5388 mConnectionsByToken.emplace(token, connection);
5389
5390 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5391 this, std::placeholders::_1, token);
5392
5393 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005394 } // release lock
5395
5396 // Wake the looper because some connections have changed.
5397 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005398 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005399}
5400
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005401Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5402 bool isGestureMonitor,
5403 const std::string& name,
5404 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005405 std::shared_ptr<InputChannel> serverChannel;
5406 std::unique_ptr<InputChannel> clientChannel;
5407 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5408 if (result) {
5409 return base::Error(result) << "Failed to open input channel pair with name " << name;
5410 }
5411
Michael Wright3dd60e22019-03-27 22:06:44 +00005412 { // acquire lock
5413 std::scoped_lock _l(mLock);
5414
5415 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005416 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5417 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005418 }
5419
Garfield Tan15601662020-09-22 15:32:38 -07005420 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005421 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005422 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005423
5424 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5425 ALOGE("Created a new connection, but the token %p is already known", token.get());
5426 }
5427 mConnectionsByToken.emplace(token, connection);
5428 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5429 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005430
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005431 auto& monitorsByDisplay =
5432 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005433 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005434
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005435 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005436 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5437 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005438 }
Garfield Tan15601662020-09-22 15:32:38 -07005439
Michael Wright3dd60e22019-03-27 22:06:44 +00005440 // Wake the looper because some connections have changed.
5441 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005442 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005443}
5444
Garfield Tan15601662020-09-22 15:32:38 -07005445status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005446 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005447 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005448
Garfield Tan15601662020-09-22 15:32:38 -07005449 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005450 if (status) {
5451 return status;
5452 }
5453 } // release lock
5454
5455 // Wake the poll loop because removing the connection may have changed the current
5456 // synchronization state.
5457 mLooper->wake();
5458 return OK;
5459}
5460
Garfield Tan15601662020-09-22 15:32:38 -07005461status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5462 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005463 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005464 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005465 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005466 return BAD_VALUE;
5467 }
5468
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005469 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005470
Michael Wrightd02c5b62014-02-10 15:10:22 -08005471 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005472 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005473 }
5474
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005475 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005476
5477 nsecs_t currentTime = now();
5478 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5479
5480 connection->status = Connection::STATUS_ZOMBIE;
5481 return OK;
5482}
5483
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005484void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5485 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5486 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005487}
5488
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005489void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005490 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005491 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005492 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005493 std::vector<Monitor>& monitors = it->second;
5494 const size_t numMonitors = monitors.size();
5495 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005496 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005497 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5498 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005499 monitors.erase(monitors.begin() + i);
5500 break;
5501 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005502 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005503 if (monitors.empty()) {
5504 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005505 } else {
5506 ++it;
5507 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005508 }
5509}
5510
Michael Wright3dd60e22019-03-27 22:06:44 +00005511status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5512 { // acquire lock
5513 std::scoped_lock _l(mLock);
5514 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5515
5516 if (!foundDisplayId) {
5517 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5518 return BAD_VALUE;
5519 }
5520 int32_t displayId = foundDisplayId.value();
5521
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005522 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5523 mTouchStatesByDisplay.find(displayId);
5524 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005525 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5526 return BAD_VALUE;
5527 }
5528
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005529 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005530 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005531 std::optional<int32_t> foundDeviceId;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07005532 for (const auto& monitor : state.gestureMonitors) {
5533 if (monitor.inputChannel->getConnectionToken() == token) {
5534 requestingChannel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005535 foundDeviceId = state.deviceId;
5536 }
5537 }
5538 if (!foundDeviceId || !state.down) {
5539 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005540 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005541 return BAD_VALUE;
5542 }
5543 int32_t deviceId = foundDeviceId.value();
5544
5545 // Send cancel events to all the input channels we're stealing from.
5546 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005547 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005548 options.deviceId = deviceId;
5549 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005550 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005551 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005552 std::shared_ptr<InputChannel> channel =
5553 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005554 if (channel != nullptr) {
5555 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005556 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005557 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005558 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005559 canceledWindows += "]";
5560 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5561 canceledWindows.c_str());
5562
Michael Wright3dd60e22019-03-27 22:06:44 +00005563 // Then clear the current touch state so we stop dispatching to them as well.
5564 state.filterNonMonitors();
5565 }
5566 return OK;
5567}
5568
Prabir Pradhan99987712020-11-10 18:43:05 -08005569void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5570 { // acquire lock
5571 std::scoped_lock _l(mLock);
5572 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005573 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005574 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5575 windowHandle != nullptr ? windowHandle->getName().c_str()
5576 : "token without window");
5577 }
5578
Vishnu Nairc519ff72021-01-21 08:23:08 -08005579 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005580 if (focusedToken != windowToken) {
5581 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5582 enabled ? "enable" : "disable");
5583 return;
5584 }
5585
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00005586 if (enabled == mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08005587 ALOGW("Ignoring request to %s Pointer Capture: "
5588 "window has %s requested pointer capture.",
5589 enabled ? "enable" : "disable", enabled ? "already" : "not");
5590 return;
5591 }
5592
Prabir Pradhan99987712020-11-10 18:43:05 -08005593 setPointerCaptureLocked(enabled);
5594 } // release lock
5595
5596 // Wake the thread to process command entries.
5597 mLooper->wake();
5598}
5599
Michael Wright3dd60e22019-03-27 22:06:44 +00005600std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5601 const sp<IBinder>& token) {
5602 for (const auto& it : mGestureMonitorsByDisplay) {
5603 const std::vector<Monitor>& monitors = it.second;
5604 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005605 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005606 return it.first;
5607 }
5608 }
5609 }
5610 return std::nullopt;
5611}
5612
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005613std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5614 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5615 if (gesturePid.has_value()) {
5616 return gesturePid;
5617 }
5618 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5619}
5620
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005621sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005622 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005623 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005624 }
5625
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005626 for (const auto& [token, connection] : mConnectionsByToken) {
5627 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005628 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005629 }
5630 }
Robert Carr4e670e52018-08-15 13:26:12 -07005631
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005632 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005633}
5634
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005635std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5636 sp<Connection> connection = getConnectionLocked(connectionToken);
5637 if (connection == nullptr) {
5638 return "<nullptr>";
5639 }
5640 return connection->getInputChannelName();
5641}
5642
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005643void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005644 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005645 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005646}
5647
Prabir Pradhancef936d2021-07-21 16:17:52 +00005648void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5649 const sp<Connection>& connection, uint32_t seq,
5650 bool handled, nsecs_t consumeTime) {
5651 // Handle post-event policy actions.
5652 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5653 if (dispatchEntryIt == connection->waitQueue.end()) {
5654 return;
5655 }
5656 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5657 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5658 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5659 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5660 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5661 }
5662 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5663 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5664 connection->inputChannel->getConnectionToken(),
5665 dispatchEntry->deliveryTime, consumeTime, finishTime);
5666 }
5667
5668 bool restartEvent;
5669 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5670 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5671 restartEvent =
5672 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5673 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5674 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5675 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5676 handled);
5677 } else {
5678 restartEvent = false;
5679 }
5680
5681 // Dequeue the event and start the next cycle.
5682 // Because the lock might have been released, it is possible that the
5683 // contents of the wait queue to have been drained, so we need to double-check
5684 // a few things.
5685 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5686 if (dispatchEntryIt != connection->waitQueue.end()) {
5687 dispatchEntry = *dispatchEntryIt;
5688 connection->waitQueue.erase(dispatchEntryIt);
5689 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5690 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5691 if (!connection->responsive) {
5692 connection->responsive = isConnectionResponsive(*connection);
5693 if (connection->responsive) {
5694 // The connection was unresponsive, and now it's responsive.
5695 processConnectionResponsiveLocked(*connection);
5696 }
5697 }
5698 traceWaitQueueLength(*connection);
5699 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5700 connection->outboundQueue.push_front(dispatchEntry);
5701 traceOutboundQueueLength(*connection);
5702 } else {
5703 releaseDispatchEntry(dispatchEntry);
5704 }
5705 }
5706
5707 // Start the next dispatch cycle for this connection.
5708 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005709}
5710
Prabir Pradhancef936d2021-07-21 16:17:52 +00005711void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5712 const sp<IBinder>& newToken) {
5713 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5714 scoped_unlock unlock(mLock);
5715 mPolicy->notifyFocusChanged(oldToken, newToken);
5716 };
5717 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005718}
5719
Prabir Pradhancef936d2021-07-21 16:17:52 +00005720void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5721 auto command = [this, token, x, y]() REQUIRES(mLock) {
5722 scoped_unlock unlock(mLock);
5723 mPolicy->notifyDropWindow(token, x, y);
5724 };
5725 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005726}
5727
Prabir Pradhancef936d2021-07-21 16:17:52 +00005728void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5729 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5730 scoped_unlock unlock(mLock);
5731 mPolicy->notifyUntrustedTouch(obscuringPackage);
5732 };
5733 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005734}
5735
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005736void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5737 if (connection == nullptr) {
5738 LOG_ALWAYS_FATAL("Caller must check for nullness");
5739 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005740 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5741 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005742 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005743 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005744 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005745 return;
5746 }
5747 /**
5748 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5749 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5750 * has changed. This could cause newer entries to time out before the already dispatched
5751 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5752 * processes the events linearly. So providing information about the oldest entry seems to be
5753 * most useful.
5754 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005755 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005756 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5757 std::string reason =
5758 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005759 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005760 ns2ms(currentWait),
5761 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005762 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005763 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005764
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005765 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5766
5767 // Stop waking up for events on this connection, it is already unresponsive
5768 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005769}
5770
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005771void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5772 std::string reason =
5773 StringPrintf("%s does not have a focused window", application->getName().c_str());
5774 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005775
Prabir Pradhancef936d2021-07-21 16:17:52 +00005776 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5777 scoped_unlock unlock(mLock);
5778 mPolicy->notifyNoFocusedWindowAnr(application);
5779 };
5780 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005781}
5782
chaviw98318de2021-05-19 16:45:23 -05005783void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005784 const std::string& reason) {
5785 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5786 updateLastAnrStateLocked(windowLabel, reason);
5787}
5788
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005789void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5790 const std::string& reason) {
5791 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005792 updateLastAnrStateLocked(windowLabel, reason);
5793}
5794
5795void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5796 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005797 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005798 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005799 struct tm tm;
5800 localtime_r(&t, &tm);
5801 char timestr[64];
5802 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005803 mLastAnrState.clear();
5804 mLastAnrState += INDENT "ANR:\n";
5805 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005806 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5807 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005808 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005809}
5810
Prabir Pradhancef936d2021-07-21 16:17:52 +00005811void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5812 KeyEntry& entry) {
5813 const KeyEvent event = createKeyEvent(entry);
5814 nsecs_t delay = 0;
5815 { // release lock
5816 scoped_unlock unlock(mLock);
5817 android::base::Timer t;
5818 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5819 entry.policyFlags);
5820 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5821 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5822 std::to_string(t.duration().count()).c_str());
5823 }
5824 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005825
5826 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005827 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005828 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005829 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005830 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005831 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5832 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005834}
5835
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005836void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005837 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5838 scoped_unlock unlock(mLock);
5839 mPolicy->notifyMonitorUnresponsive(pid, reason);
5840 };
5841 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005842}
5843
Prabir Pradhancef936d2021-07-21 16:17:52 +00005844void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005845 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005846 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5847 scoped_unlock unlock(mLock);
5848 mPolicy->notifyWindowUnresponsive(token, reason);
5849 };
5850 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005851}
5852
5853void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005854 auto command = [this, pid]() REQUIRES(mLock) {
5855 scoped_unlock unlock(mLock);
5856 mPolicy->notifyMonitorResponsive(pid);
5857 };
5858 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005859}
5860
Prabir Pradhancef936d2021-07-21 16:17:52 +00005861void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5862 auto command = [this, connectionToken]() REQUIRES(mLock) {
5863 scoped_unlock unlock(mLock);
5864 mPolicy->notifyWindowResponsive(connectionToken);
5865 };
5866 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005867}
5868
5869/**
5870 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5871 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5872 * command entry to the command queue.
5873 */
5874void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5875 std::string reason) {
5876 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5877 if (connection.monitor) {
5878 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5879 reason.c_str());
5880 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5881 if (!pid.has_value()) {
5882 ALOGE("Could not find unresponsive monitor for connection %s",
5883 connection.inputChannel->getName().c_str());
5884 return;
5885 }
5886 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5887 return;
5888 }
5889 // If not a monitor, must be a window
5890 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5891 reason.c_str());
5892 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5893}
5894
5895/**
5896 * Tell the policy that a connection has become responsive so that it can stop ANR.
5897 */
5898void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5899 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5900 if (connection.monitor) {
5901 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5902 if (!pid.has_value()) {
5903 ALOGE("Could not find responsive monitor for connection %s",
5904 connection.inputChannel->getName().c_str());
5905 return;
5906 }
5907 sendMonitorResponsiveCommandLocked(pid.value());
5908 return;
5909 }
5910 // If not a monitor, must be a window
5911 sendWindowResponsiveCommandLocked(connectionToken);
5912}
5913
Prabir Pradhancef936d2021-07-21 16:17:52 +00005914bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005915 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005916 KeyEntry& keyEntry, bool handled) {
5917 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005918 if (!handled) {
5919 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005920 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005921 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005922 return false;
5923 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005924
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005925 // Get the fallback key state.
5926 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005927 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005928 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005929 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005930 connection->inputState.removeFallbackKey(originalKeyCode);
5931 }
5932
5933 if (handled || !dispatchEntry->hasForegroundTarget()) {
5934 // If the application handles the original key for which we previously
5935 // generated a fallback or if the window is not a foreground window,
5936 // then cancel the associated fallback key, if any.
5937 if (fallbackKeyCode != -1) {
5938 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005939 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5940 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5941 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5942 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5943 keyEntry.policyFlags);
5944 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005945 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005946 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005947
5948 mLock.unlock();
5949
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005950 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005951 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005952
5953 mLock.lock();
5954
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005955 // Cancel the fallback key.
5956 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005957 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005958 "application handled the original non-fallback key "
5959 "or is no longer a foreground target, "
5960 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005961 options.keyCode = fallbackKeyCode;
5962 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005963 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005964 connection->inputState.removeFallbackKey(originalKeyCode);
5965 }
5966 } else {
5967 // If the application did not handle a non-fallback key, first check
5968 // that we are in a good state to perform unhandled key event processing
5969 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005970 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005971 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005972 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5973 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5974 "since this is not an initial down. "
5975 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5976 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5977 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005978 return false;
5979 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005980
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005981 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005982 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5983 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5984 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5985 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5986 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005987 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005988
5989 mLock.unlock();
5990
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005991 bool fallback =
5992 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005993 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005994
5995 mLock.lock();
5996
5997 if (connection->status != Connection::STATUS_NORMAL) {
5998 connection->inputState.removeFallbackKey(originalKeyCode);
5999 return false;
6000 }
6001
6002 // Latch the fallback keycode for this key on an initial down.
6003 // The fallback keycode cannot change at any other point in the lifecycle.
6004 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006005 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006006 fallbackKeyCode = event.getKeyCode();
6007 } else {
6008 fallbackKeyCode = AKEYCODE_UNKNOWN;
6009 }
6010 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
6011 }
6012
6013 ALOG_ASSERT(fallbackKeyCode != -1);
6014
6015 // Cancel the fallback key if the policy decides not to send it anymore.
6016 // We will continue to dispatch the key to the policy but we will no
6017 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006018 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
6019 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006020 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6021 if (fallback) {
6022 ALOGD("Unhandled key event: Policy requested to send key %d"
6023 "as a fallback for %d, but on the DOWN it had requested "
6024 "to send %d instead. Fallback canceled.",
6025 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
6026 } else {
6027 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6028 "but on the DOWN it had requested to send %d. "
6029 "Fallback canceled.",
6030 originalKeyCode, fallbackKeyCode);
6031 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006032 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006033
6034 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
6035 "canceling fallback, policy no longer desires it");
6036 options.keyCode = fallbackKeyCode;
6037 synthesizeCancelationEventsForConnectionLocked(connection, options);
6038
6039 fallback = false;
6040 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006041 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006042 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006043 }
6044 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08006045
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006046 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6047 {
6048 std::string msg;
6049 const KeyedVector<int32_t, int32_t>& fallbackKeys =
6050 connection->inputState.getFallbackKeys();
6051 for (size_t i = 0; i < fallbackKeys.size(); i++) {
6052 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
6053 }
6054 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6055 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006056 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006057 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006058
6059 if (fallback) {
6060 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006061 keyEntry.eventTime = event.getEventTime();
6062 keyEntry.deviceId = event.getDeviceId();
6063 keyEntry.source = event.getSource();
6064 keyEntry.displayId = event.getDisplayId();
6065 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
6066 keyEntry.keyCode = fallbackKeyCode;
6067 keyEntry.scanCode = event.getScanCode();
6068 keyEntry.metaState = event.getMetaState();
6069 keyEntry.repeatCount = event.getRepeatCount();
6070 keyEntry.downTime = event.getDownTime();
6071 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006072
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006073 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6074 ALOGD("Unhandled key event: Dispatching fallback key. "
6075 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6076 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
6077 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08006078 return true; // restart the event
6079 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00006080 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6081 ALOGD("Unhandled key event: No fallback key.");
6082 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08006083
6084 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006085 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006086 }
6087 }
6088 return false;
6089}
6090
Prabir Pradhancef936d2021-07-21 16:17:52 +00006091bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07006092 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07006093 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006094 return false;
6095}
6096
Michael Wrightd02c5b62014-02-10 15:10:22 -08006097void InputDispatcher::traceInboundQueueLengthLocked() {
6098 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07006099 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006100 }
6101}
6102
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006103void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006104 if (ATRACE_ENABLED()) {
6105 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006106 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
6107 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006108 }
6109}
6110
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006111void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08006112 if (ATRACE_ENABLED()) {
6113 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00006114 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
6115 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08006116 }
6117}
6118
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006119void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006120 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006121
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006122 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08006123 dumpDispatchStateLocked(dump);
6124
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006125 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08006126 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07006127 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08006128 }
6129}
6130
6131void InputDispatcher::monitor() {
6132 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006133 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006134 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08006135 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08006136}
6137
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08006138/**
6139 * Wake up the dispatcher and wait until it processes all events and commands.
6140 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6141 * this method can be safely called from any thread, as long as you've ensured that
6142 * the work you are interested in completing has already been queued.
6143 */
6144bool InputDispatcher::waitForIdle() {
6145 /**
6146 * Timeout should represent the longest possible time that a device might spend processing
6147 * events and commands.
6148 */
6149 constexpr std::chrono::duration TIMEOUT = 100ms;
6150 std::unique_lock lock(mLock);
6151 mLooper->wake();
6152 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6153 return result == std::cv_status::no_timeout;
6154}
6155
Vishnu Naire798b472020-07-23 13:52:21 -07006156/**
6157 * Sets focus to the window identified by the token. This must be called
6158 * after updating any input window handles.
6159 *
6160 * Params:
6161 * request.token - input channel token used to identify the window that should gain focus.
6162 * request.focusedToken - the token that the caller expects currently to be focused. If the
6163 * specified token does not match the currently focused window, this request will be dropped.
6164 * If the specified focused token matches the currently focused window, the call will succeed.
6165 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6166 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6167 * when requesting the focus change. This determines which request gets
6168 * precedence if there is a focus change request from another source such as pointer down.
6169 */
Vishnu Nair958da932020-08-21 17:12:37 -07006170void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6171 { // acquire lock
6172 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006173 std::optional<FocusResolver::FocusChanges> changes =
6174 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6175 if (changes) {
6176 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006177 }
6178 } // release lock
6179 // Wake up poll loop since it may need to make new input dispatching choices.
6180 mLooper->wake();
6181}
6182
Vishnu Nairc519ff72021-01-21 08:23:08 -08006183void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6184 if (changes.oldFocus) {
6185 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006186 if (focusedInputChannel) {
6187 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6188 "focus left window");
6189 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006190 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006191 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006192 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006193 if (changes.newFocus) {
6194 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006195 }
6196
Prabir Pradhan99987712020-11-10 18:43:05 -08006197 // If a window has pointer capture, then it must have focus. We need to ensure that this
6198 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6199 // If the window loses focus before it loses pointer capture, then the window can be in a state
6200 // where it has pointer capture but not focus, violating the contract. Therefore we must
6201 // dispatch the pointer capture event before the focus event. Since focus events are added to
6202 // the front of the queue (above), we add the pointer capture event to the front of the queue
6203 // after the focus events are added. This ensures the pointer capture event ends up at the
6204 // front.
6205 disablePointerCaptureForcedLocked();
6206
Vishnu Nairc519ff72021-01-21 08:23:08 -08006207 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006208 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006209 }
6210}
Vishnu Nair958da932020-08-21 17:12:37 -07006211
Prabir Pradhan99987712020-11-10 18:43:05 -08006212void InputDispatcher::disablePointerCaptureForcedLocked() {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006213 if (!mCurrentPointerCaptureRequest.enable && !mWindowTokenWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006214 return;
6215 }
6216
6217 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6218
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006219 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08006220 setPointerCaptureLocked(false);
6221 }
6222
6223 if (!mWindowTokenWithPointerCapture) {
6224 // No need to send capture changes because no window has capture.
6225 return;
6226 }
6227
6228 if (mPendingEvent != nullptr) {
6229 // Move the pending event to the front of the queue. This will give the chance
6230 // for the pending event to be dropped if it is a captured event.
6231 mInboundQueue.push_front(mPendingEvent);
6232 mPendingEvent = nullptr;
6233 }
6234
6235 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006236 mCurrentPointerCaptureRequest);
Prabir Pradhan99987712020-11-10 18:43:05 -08006237 mInboundQueue.push_front(std::move(entry));
6238}
6239
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006240void InputDispatcher::setPointerCaptureLocked(bool enable) {
6241 mCurrentPointerCaptureRequest.enable = enable;
6242 mCurrentPointerCaptureRequest.seq++;
6243 auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006244 scoped_unlock unlock(mLock);
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00006245 mPolicy->setPointerCapture(request);
Prabir Pradhancef936d2021-07-21 16:17:52 +00006246 };
6247 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006248}
6249
Vishnu Nair599f1412021-06-21 10:39:58 -07006250void InputDispatcher::displayRemoved(int32_t displayId) {
6251 { // acquire lock
6252 std::scoped_lock _l(mLock);
6253 // Set an empty list to remove all handles from the specific display.
6254 setInputWindowsLocked(/* window handles */ {}, displayId);
6255 setFocusedApplicationLocked(displayId, nullptr);
6256 // Call focus resolver to clean up stale requests. This must be called after input windows
6257 // have been removed for the removed display.
6258 mFocusResolver.displayRemoved(displayId);
6259 } // release lock
6260
6261 // Wake up poll loop since it may need to make new input dispatching choices.
6262 mLooper->wake();
6263}
6264
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006265void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6266 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006267 // The listener sends the windows as a flattened array. Separate the windows by display for
6268 // more convenient parsing.
6269 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006270 for (const auto& info : windowInfos) {
6271 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6272 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6273 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006274
6275 { // acquire lock
6276 std::scoped_lock _l(mLock);
6277 mDisplayInfos.clear();
6278 for (const auto& displayInfo : displayInfos) {
6279 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6280 }
6281
6282 for (const auto& [displayId, handles] : handlesPerDisplay) {
6283 setInputWindowsLocked(handles, displayId);
6284 }
6285 }
6286 // Wake up poll loop since it may need to make new input dispatching choices.
6287 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006288}
6289
Vishnu Nair062a8672021-09-03 16:07:44 -07006290bool InputDispatcher::shouldDropInput(
6291 const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
6292 if (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT) ||
6293 (windowHandle->getInfo()->inputFeatures.test(WindowInfo::Feature::DROP_INPUT_IF_OBSCURED) &&
6294 isWindowObscuredLocked(windowHandle))) {
6295 ALOGW("Dropping %s event targeting %s as requested by input feature %s on display "
6296 "%" PRId32 ".",
6297 ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
6298 windowHandle->getInfo()->inputFeatures.string().c_str(),
6299 windowHandle->getInfo()->displayId);
6300 return true;
6301 }
6302 return false;
6303}
6304
Siarhei Vishniakou18050092021-09-01 13:32:49 -07006305void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
6306 const std::vector<gui::WindowInfo>& windowInfos,
6307 const std::vector<DisplayInfo>& displayInfos) {
6308 mDispatcher.onWindowInfosChanged(windowInfos, displayInfos);
6309}
6310
Garfield Tane84e6f92019-08-29 17:28:41 -07006311} // namespace android::inputdispatcher