blob: 1b19311b2fd396ed6506a9897aac606922c7b5de [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;
Arthur Hungb3307ee2021-10-14 10:57:37 +0000156constexpr int LOGTAG_INPUT_CANCEL = 62003;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000157
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000158inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800159 return systemTime(SYSTEM_TIME_MONOTONIC);
160}
161
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000162inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800163 return value ? "true" : "false";
164}
165
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000166inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000167 if (binder == nullptr) {
168 return "<null>";
169 }
170 return StringPrintf("%p", binder.get());
171}
172
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000173inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700174 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
175 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800176}
177
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000178bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800179 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700180 case AKEY_EVENT_ACTION_DOWN:
181 case AKEY_EVENT_ACTION_UP:
182 return true;
183 default:
184 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 }
186}
187
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000188bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700189 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800190 ALOGE("Key event has invalid action code 0x%x", action);
191 return false;
192 }
193 return true;
194}
195
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000196bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800197 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700198 case AMOTION_EVENT_ACTION_DOWN:
199 case AMOTION_EVENT_ACTION_UP:
200 case AMOTION_EVENT_ACTION_CANCEL:
201 case AMOTION_EVENT_ACTION_MOVE:
202 case AMOTION_EVENT_ACTION_OUTSIDE:
203 case AMOTION_EVENT_ACTION_HOVER_ENTER:
204 case AMOTION_EVENT_ACTION_HOVER_MOVE:
205 case AMOTION_EVENT_ACTION_HOVER_EXIT:
206 case AMOTION_EVENT_ACTION_SCROLL:
207 return true;
208 case AMOTION_EVENT_ACTION_POINTER_DOWN:
209 case AMOTION_EVENT_ACTION_POINTER_UP: {
210 int32_t index = getMotionEventActionPointerIndex(action);
211 return index >= 0 && index < pointerCount;
212 }
213 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
214 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
215 return actionButton != 0;
216 default:
217 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800218 }
219}
220
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000221int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500222 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
223}
224
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000225bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
226 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700227 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800228 ALOGE("Motion event has invalid action code 0x%x", action);
229 return false;
230 }
231 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000232 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700233 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800234 return false;
235 }
236 BitSet32 pointerIdBits;
237 for (size_t i = 0; i < pointerCount; i++) {
238 int32_t id = pointerProperties[i].id;
239 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700240 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
241 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800242 return false;
243 }
244 if (pointerIdBits.hasBit(id)) {
245 ALOGE("Motion event has duplicate pointer id %d", id);
246 return false;
247 }
248 pointerIdBits.markBit(id);
249 }
250 return true;
251}
252
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000253std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000255 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800256 }
257
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000258 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800259 bool first = true;
260 Region::const_iterator cur = region.begin();
261 Region::const_iterator const tail = region.end();
262 while (cur != tail) {
263 if (first) {
264 first = false;
265 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800266 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800268 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800269 cur++;
270 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000271 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800272}
273
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000274std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500275 constexpr size_t maxEntries = 50; // max events to print
276 constexpr size_t skipBegin = maxEntries / 2;
277 const size_t skipEnd = queue.size() - maxEntries / 2;
278 // skip from maxEntries / 2 ... size() - maxEntries/2
279 // only print from 0 .. skipBegin and then from skipEnd .. size()
280
281 std::string dump;
282 for (size_t i = 0; i < queue.size(); i++) {
283 const DispatchEntry& entry = *queue[i];
284 if (i >= skipBegin && i < skipEnd) {
285 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
286 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
287 continue;
288 }
289 dump.append(INDENT4);
290 dump += entry.eventEntry->getDescription();
291 dump += StringPrintf(", seq=%" PRIu32
292 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
293 entry.seq, entry.targetFlags, entry.resolvedAction,
294 ns2ms(currentTime - entry.eventEntry->eventTime));
295 if (entry.deliveryTime != 0) {
296 // This entry was delivered, so add information on how long we've been waiting
297 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
298 }
299 dump.append("\n");
300 }
301 return dump;
302}
303
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700304/**
305 * Find the entry in std::unordered_map by key, and return it.
306 * If the entry is not found, return a default constructed entry.
307 *
308 * Useful when the entries are vectors, since an empty vector will be returned
309 * if the entry is not found.
310 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
311 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700312template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000313V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700314 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700315 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800316}
317
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000318bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700319 if (first == second) {
320 return true;
321 }
322
323 if (first == nullptr || second == nullptr) {
324 return false;
325 }
326
327 return first->getToken() == second->getToken();
328}
329
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000330bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000331 if (first == nullptr || second == nullptr) {
332 return false;
333 }
334 return first->applicationInfo.token != nullptr &&
335 first->applicationInfo.token == second->applicationInfo.token;
336}
337
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000338bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800339 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
340}
341
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000342std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
343 std::shared_ptr<EventEntry> eventEntry,
344 int32_t inputTargetFlags) {
chaviw1ff3d1e2020-07-01 15:53:47 -0700345 if (inputTarget.useDefaultPointerTransform()) {
346 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700347 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700348 inputTarget.displayTransform,
349 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000350 }
351
352 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
353 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
354
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700355 std::vector<PointerCoords> pointerCoords;
356 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000357
358 // Use the first pointer information to normalize all other pointers. This could be any pointer
359 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700360 // uses the transform for the normalized pointer.
361 const ui::Transform& firstPointerTransform =
362 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
363 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000364
365 // Iterate through all pointers in the event to normalize against the first.
366 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
367 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
368 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700369 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000370
371 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700372 // First, apply the current pointer's transform to update the coordinates into
373 // window space.
374 pointerCoords[pointerIndex].transform(currTransform);
375 // Next, apply the inverse transform of the normalized coordinates so the
376 // current coordinates are transformed into the normalized coordinate space.
377 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000378 }
379
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700380 std::unique_ptr<MotionEntry> combinedMotionEntry =
381 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
382 motionEntry.deviceId, motionEntry.source,
383 motionEntry.displayId, motionEntry.policyFlags,
384 motionEntry.action, motionEntry.actionButton,
385 motionEntry.flags, motionEntry.metaState,
386 motionEntry.buttonState, motionEntry.classification,
387 motionEntry.edgeFlags, motionEntry.xPrecision,
388 motionEntry.yPrecision, motionEntry.xCursorPosition,
389 motionEntry.yCursorPosition, motionEntry.downTime,
390 motionEntry.pointerCount, motionEntry.pointerProperties,
391 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000392
393 if (motionEntry.injectionState) {
394 combinedMotionEntry->injectionState = motionEntry.injectionState;
395 combinedMotionEntry->injectionState->refCount += 1;
396 }
397
398 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700399 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700400 firstPointerTransform, inputTarget.displayTransform,
401 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000402 return dispatchEntry;
403}
404
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000405status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
406 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700407 std::unique_ptr<InputChannel> uniqueServerChannel;
408 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
409
410 serverChannel = std::move(uniqueServerChannel);
411 return result;
412}
413
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500414template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000415bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500416 if (lhs == nullptr && rhs == nullptr) {
417 return true;
418 }
419 if (lhs == nullptr || rhs == nullptr) {
420 return false;
421 }
422 return *lhs == *rhs;
423}
424
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000425sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000426 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
427 if (service == nullptr) {
428 ALOGE("Failed to link to compat service");
429 return nullptr;
430 }
431 return interface_cast<IPlatformCompatNative>(service);
432}
433
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000434KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000435 KeyEvent event;
436 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
437 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
438 entry.repeatCount, entry.downTime, entry.eventTime);
439 return event;
440}
441
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000442std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000443 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
444 const sp<IBinder>& token) {
445 for (const auto& it : monitorsByDisplay) {
446 const std::vector<Monitor>& monitors = it.second;
447 for (const Monitor& monitor : monitors) {
448 if (monitor.inputChannel->getConnectionToken() == token) {
449 return monitor.pid;
450 }
451 }
452 }
453 return std::nullopt;
454}
455
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000456bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000457 // Do not keep track of gesture monitors. They receive every event and would disproportionately
458 // affect the statistics.
459 if (connection.monitor) {
460 return false;
461 }
462 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
463 if (!connection.responsive) {
464 return false;
465 }
466 return true;
467}
468
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000469bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000470 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
471 const int32_t& inputEventId = eventEntry.id;
472 if (inputEventId != dispatchEntry.resolvedEventId) {
473 // Event was transmuted
474 return false;
475 }
476 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
477 return false;
478 }
479 // Only track latency for events that originated from hardware
480 if (eventEntry.isSynthesized()) {
481 return false;
482 }
483 const EventEntry::Type& inputEventEntryType = eventEntry.type;
484 if (inputEventEntryType == EventEntry::Type::KEY) {
485 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
486 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
487 return false;
488 }
489 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
490 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
491 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
492 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
493 return false;
494 }
495 } else {
496 // Not a key or a motion
497 return false;
498 }
499 if (!shouldReportMetricsForConnection(connection)) {
500 return false;
501 }
502 return true;
503}
504
Prabir Pradhancef936d2021-07-21 16:17:52 +0000505/**
506 * Connection is responsive if it has no events in the waitQueue that are older than the
507 * current time.
508 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000509bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000510 const nsecs_t currentTime = now();
511 for (const DispatchEntry* entry : connection.waitQueue) {
512 if (entry->timeoutTime < currentTime) {
513 return false;
514 }
515 }
516 return true;
517}
518
Prabir Pradhan81420cc2021-09-06 10:28:50 -0700519bool isFromSource(uint32_t source, uint32_t test) {
520 return (source & test) == test;
521}
522
523vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float y) {
524 const vec2 transformedXy = transform.transform(x, y);
525 const vec2 transformedOrigin = transform.transform(0, 0);
526 return transformedXy - transformedOrigin;
527}
528
Antonio Kantekf16f2832021-09-28 04:39:20 +0000529// Returns true if the event type passed as argument represents a user activity.
530bool isUserActivityEvent(const EventEntry& eventEntry) {
531 switch (eventEntry.type) {
532 case EventEntry::Type::FOCUS:
533 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
534 case EventEntry::Type::DRAG:
535 case EventEntry::Type::TOUCH_MODE_CHANGED:
536 case EventEntry::Type::SENSOR:
537 case EventEntry::Type::CONFIGURATION_CHANGED:
538 return false;
539 case EventEntry::Type::DEVICE_RESET:
540 case EventEntry::Type::KEY:
541 case EventEntry::Type::MOTION:
542 return true;
543 }
544}
545
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000546} // namespace
547
Michael Wrightd02c5b62014-02-10 15:10:22 -0800548// --- InputDispatcher ---
549
Garfield Tan00f511d2019-06-12 16:55:40 -0700550InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
551 : mPolicy(policy),
552 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700553 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800554 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700555 mAppSwitchSawKeyDown(false),
556 mAppSwitchDueTime(LONG_LONG_MAX),
557 mNextUnblockedEvent(nullptr),
558 mDispatchEnabled(false),
559 mDispatchFrozen(false),
560 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800561 // mInTouchMode will be initialized by the WindowManager to the default device config.
562 // To avoid leaking stack in case that call never comes, and for tests,
563 // initialize it here anyways.
Antonio Kantekf16f2832021-09-28 04:39:20 +0000564 mInTouchMode(kDefaultInTouchMode),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100565 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000566 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800567 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000568 mLatencyAggregator(),
569 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000570 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800571 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800572 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800573
Siarhei Vishniakou18050092021-09-01 13:32:49 -0700574 mWindowInfoListener = new DispatcherWindowListener(*this);
575 SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
576
Yi Kong9b14ac62018-07-17 13:48:38 -0700577 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800578
579 policy->getDispatcherConfiguration(&mConfig);
580}
581
582InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000583 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800584
Prabir Pradhancef936d2021-07-21 16:17:52 +0000585 resetKeyRepeatLocked();
586 releasePendingEventLocked();
587 drainInboundQueueLocked();
588 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800589
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000590 while (!mConnectionsByToken.empty()) {
591 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000592 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
593 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800594 }
595}
596
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700597status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700598 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700599 return ALREADY_EXISTS;
600 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700601 mThread = std::make_unique<InputThread>(
602 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
603 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700604}
605
606status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700607 if (mThread && mThread->isCallingThread()) {
608 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700609 return INVALID_OPERATION;
610 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700611 mThread.reset();
612 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700613}
614
Michael Wrightd02c5b62014-02-10 15:10:22 -0800615void InputDispatcher::dispatchOnce() {
616 nsecs_t nextWakeupTime = LONG_LONG_MAX;
617 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800618 std::scoped_lock _l(mLock);
619 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800620
621 // Run a dispatch loop if there are no pending commands.
622 // The dispatch loop might enqueue commands to run afterwards.
623 if (!haveCommandsLocked()) {
624 dispatchOnceInnerLocked(&nextWakeupTime);
625 }
626
627 // Run all pending commands if there are any.
628 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000629 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800630 nextWakeupTime = LONG_LONG_MIN;
631 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800632
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700633 // If we are still waiting for ack on some events,
634 // we might have to wake up earlier to check if an app is anr'ing.
635 const nsecs_t nextAnrCheck = processAnrsLocked();
636 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
637
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800638 // We are about to enter an infinitely long sleep, because we have no commands or
639 // pending or queued events
640 if (nextWakeupTime == LONG_LONG_MAX) {
641 mDispatcherEnteredIdle.notify_all();
642 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800643 } // release lock
644
645 // Wait for callback or timeout or wake. (make sure we round up, not down)
646 nsecs_t currentTime = now();
647 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
648 mLooper->pollOnce(timeoutMillis);
649}
650
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700651/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500652 * Raise ANR if there is no focused window.
653 * Before the ANR is raised, do a final state check:
654 * 1. The currently focused application must be the same one we are waiting for.
655 * 2. Ensure we still don't have a focused window.
656 */
657void InputDispatcher::processNoFocusedWindowAnrLocked() {
658 // Check if the application that we are waiting for is still focused.
659 std::shared_ptr<InputApplicationHandle> focusedApplication =
660 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
661 if (focusedApplication == nullptr ||
662 focusedApplication->getApplicationToken() !=
663 mAwaitedFocusedApplication->getApplicationToken()) {
664 // Unexpected because we should have reset the ANR timer when focused application changed
665 ALOGE("Waited for a focused window, but focused application has already changed to %s",
666 focusedApplication->getName().c_str());
667 return; // The focused application has changed.
668 }
669
chaviw98318de2021-05-19 16:45:23 -0500670 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500671 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
672 if (focusedWindowHandle != nullptr) {
673 return; // We now have a focused window. No need for ANR.
674 }
675 onAnrLocked(mAwaitedFocusedApplication);
676}
677
678/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700679 * Check if any of the connections' wait queues have events that are too old.
680 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
681 * Return the time at which we should wake up next.
682 */
683nsecs_t InputDispatcher::processAnrsLocked() {
684 const nsecs_t currentTime = now();
685 nsecs_t nextAnrCheck = LONG_LONG_MAX;
686 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
687 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
688 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500689 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700690 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500691 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700692 return LONG_LONG_MIN;
693 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500694 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700695 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
696 }
697 }
698
699 // Check if any connection ANRs are due
700 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
701 if (currentTime < nextAnrCheck) { // most likely scenario
702 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
703 }
704
705 // If we reached here, we have an unresponsive connection.
706 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
707 if (connection == nullptr) {
708 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
709 return nextAnrCheck;
710 }
711 connection->responsive = false;
712 // Stop waking up for this unresponsive connection
713 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000714 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700715 return LONG_LONG_MIN;
716}
717
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500718std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500719 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700720 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500721 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700722 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500723 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700724}
725
Michael Wrightd02c5b62014-02-10 15:10:22 -0800726void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
727 nsecs_t currentTime = now();
728
Jeff Browndc5992e2014-04-11 01:27:26 -0700729 // Reset the key repeat timer whenever normal dispatch is suspended while the
730 // device is in a non-interactive state. This is to ensure that we abort a key
731 // repeat if the device is just coming out of sleep.
732 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733 resetKeyRepeatLocked();
734 }
735
736 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
737 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100738 if (DEBUG_FOCUS) {
739 ALOGD("Dispatch frozen. Waiting some more.");
740 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800741 return;
742 }
743
744 // Optimize latency of app switches.
745 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
746 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
747 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
748 if (mAppSwitchDueTime < *nextWakeupTime) {
749 *nextWakeupTime = mAppSwitchDueTime;
750 }
751
752 // Ready to start a new event.
753 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700754 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700755 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800756 if (isAppSwitchDue) {
757 // The inbound queue is empty so the app switch key we were waiting
758 // for will never arrive. Stop waiting for it.
759 resetPendingAppSwitchLocked(false);
760 isAppSwitchDue = false;
761 }
762
763 // Synthesize a key repeat if appropriate.
764 if (mKeyRepeatState.lastKeyEntry) {
765 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
766 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
767 } else {
768 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
769 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
770 }
771 }
772 }
773
774 // Nothing to do if there is no pending event.
775 if (!mPendingEvent) {
776 return;
777 }
778 } else {
779 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700780 mPendingEvent = mInboundQueue.front();
781 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800782 traceInboundQueueLengthLocked();
783 }
784
785 // Poke user activity for this event.
786 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700787 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800789 }
790
791 // Now we have an event to dispatch.
792 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700793 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800794 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700795 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800796 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700797 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700799 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800800 }
801
802 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700803 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800804 }
805
806 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700807 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700808 const ConfigurationChangedEntry& typedEntry =
809 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700810 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700811 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700812 break;
813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800814
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700815 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700816 const DeviceResetEntry& typedEntry =
817 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700818 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700819 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700820 break;
821 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800822
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100823 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700824 std::shared_ptr<FocusEntry> typedEntry =
825 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100826 dispatchFocusLocked(currentTime, typedEntry);
827 done = true;
828 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
829 break;
830 }
831
Antonio Kantek7242d8b2021-08-05 16:07:20 -0700832 case EventEntry::Type::TOUCH_MODE_CHANGED: {
833 const auto typedEntry = std::static_pointer_cast<TouchModeEntry>(mPendingEvent);
834 dispatchTouchModeChangeLocked(currentTime, typedEntry);
835 done = true;
836 dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
837 break;
838 }
839
Prabir Pradhan99987712020-11-10 18:43:05 -0800840 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
841 const auto typedEntry =
842 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
843 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
844 done = true;
845 break;
846 }
847
arthurhungb89ccb02020-12-30 16:19:01 +0800848 case EventEntry::Type::DRAG: {
849 std::shared_ptr<DragEntry> typedEntry =
850 std::static_pointer_cast<DragEntry>(mPendingEvent);
851 dispatchDragLocked(currentTime, typedEntry);
852 done = true;
853 break;
854 }
855
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700856 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700857 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700858 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700859 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700860 resetPendingAppSwitchLocked(true);
861 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700862 } else if (dropReason == DropReason::NOT_DROPPED) {
863 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700864 }
865 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700866 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700867 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700868 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700869 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
870 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700871 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700872 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700873 break;
874 }
875
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700876 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700877 std::shared_ptr<MotionEntry> motionEntry =
878 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700879 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
880 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800881 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700882 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700883 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700884 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700885 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
886 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700887 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700888 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700889 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800890 }
Chris Yef59a2f42020-10-16 12:55:26 -0700891
892 case EventEntry::Type::SENSOR: {
893 std::shared_ptr<SensorEntry> sensorEntry =
894 std::static_pointer_cast<SensorEntry>(mPendingEvent);
895 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
896 dropReason = DropReason::APP_SWITCH;
897 }
898 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
899 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
900 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
901 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
902 dropReason = DropReason::STALE;
903 }
904 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
905 done = true;
906 break;
907 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800908 }
909
910 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700911 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700912 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800913 }
Michael Wright3a981722015-06-10 15:26:13 +0100914 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800915
916 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700917 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800918 }
919}
920
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700921/**
922 * Return true if the events preceding this incoming motion event should be dropped
923 * Return false otherwise (the default behaviour)
924 */
925bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700926 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Prabir Pradhanaa561d12021-09-24 06:57:33 -0700927 isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700928
929 // Optimize case where the current application is unresponsive and the user
930 // decides to touch a window in a different application.
931 // If the application takes too long to catch up then we drop all events preceding
932 // the touch into the other window.
933 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700934 int32_t displayId = motionEntry.displayId;
935 int32_t x = static_cast<int32_t>(
936 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
937 int32_t y = static_cast<int32_t>(
938 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500939 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700940 findTouchedWindowAtLocked(displayId, x, y, nullptr);
941 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700942 touchedWindowHandle->getApplicationToken() !=
943 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700944 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700945 ALOGI("Pruning input queue because user touched a different application while waiting "
946 "for %s",
947 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700948 return true;
949 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700950
951 // Alternatively, maybe there's a gesture monitor that could handle this event
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700952 for (const auto& monitor : getValueByKey(mGestureMonitorsByDisplay, displayId)) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700953 sp<Connection> connection =
Prabir Pradhan0a99c922021-09-03 08:27:53 -0700954 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000955 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700956 // This monitor could take more input. Drop all events preceding this
957 // event, so that gesture monitor could get a chance to receive the stream
958 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
959 "responsive gesture monitor that may handle the event",
960 mAwaitedFocusedApplication->getName().c_str());
961 return true;
962 }
963 }
964 }
965
966 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
967 // yet been processed by some connections, the dispatcher will wait for these motion
968 // events to be processed before dispatching the key event. This is because these motion events
969 // may cause a new window to be launched, which the user might expect to receive focus.
970 // To prevent waiting forever for such events, just send the key to the currently focused window
971 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
972 ALOGD("Received a new pointer down event, stop waiting for events to process and "
973 "just send the pending key event to the focused window.");
974 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700975 }
976 return false;
977}
978
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700979bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700980 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700981 mInboundQueue.push_back(std::move(newEntry));
982 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800983 traceInboundQueueLengthLocked();
984
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700985 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700986 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700987 // Optimize app switch latency.
988 // If the application takes too long to catch up then we drop all events preceding
989 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700990 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700991 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700992 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700993 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700994 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700995 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000996 if (DEBUG_APP_SWITCH) {
997 ALOGD("App switch is pending!");
998 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700999 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001000 mAppSwitchSawKeyDown = false;
1001 needWake = true;
1002 }
1003 }
1004 }
1005 break;
1006 }
1007
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001008 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001009 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1010 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001011 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001012 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001013 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001014 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001015 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001016 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1017 break;
1018 }
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001019 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001020 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001021 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001022 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001023 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1024 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001025 // nothing to do
1026 break;
1027 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001028 }
1029
1030 return needWake;
1031}
1032
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001033void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001034 // Do not store sensor event in recent queue to avoid flooding the queue.
1035 if (entry->type != EventEntry::Type::SENSOR) {
1036 mRecentQueue.push_back(entry);
1037 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001038 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001039 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 }
1041}
1042
chaviw98318de2021-05-19 16:45:23 -05001043sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1044 int32_t y, TouchState* touchState,
1045 bool addOutsideTargets,
1046 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001047 if (addOutsideTargets && touchState == nullptr) {
1048 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001049 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001051 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1052 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001053 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001054 continue;
1055 }
chaviw98318de2021-05-19 16:45:23 -05001056 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001057 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001058 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001059
1060 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001061 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1062 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1063 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001064 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1065 // Found window.
1066 return windowHandle;
1067 }
1068 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001069
chaviw98318de2021-05-19 16:45:23 -05001070 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001071 touchState->addOrUpdateWindow(windowHandle,
1072 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1073 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001074 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001075 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001076 }
1077 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001078 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001079}
1080
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001081void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082 const char* reason;
1083 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001084 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001085 if (DEBUG_INBOUND_EVENT_DETAILS) {
1086 ALOGD("Dropped event because policy consumed it.");
1087 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001088 reason = "inbound event was dropped because the policy consumed it";
1089 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001090 case DropReason::DISABLED:
1091 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001092 ALOGI("Dropped event because input dispatch is disabled.");
1093 }
1094 reason = "inbound event was dropped because input dispatch is disabled";
1095 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001096 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001097 ALOGI("Dropped event because of pending overdue app switch.");
1098 reason = "inbound event was dropped because of pending overdue app switch";
1099 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001100 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001101 ALOGI("Dropped event because the current application is not responding and the user "
1102 "has started interacting with a different application.");
1103 reason = "inbound event was dropped because the current application is not responding "
1104 "and the user has started interacting with a different application";
1105 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001106 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001107 ALOGI("Dropped event because it is stale.");
1108 reason = "inbound event was dropped because it is stale";
1109 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001110 case DropReason::NO_POINTER_CAPTURE:
1111 ALOGI("Dropped event because there is no window with Pointer Capture.");
1112 reason = "inbound event was dropped because there is no window with Pointer Capture";
1113 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001114 case DropReason::NOT_DROPPED: {
1115 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001116 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001117 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118 }
1119
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001120 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001121 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001122 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1123 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001124 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001125 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001126 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001127 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1128 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001129 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1130 synthesizeCancelationEventsForAllConnectionsLocked(options);
1131 } else {
1132 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1133 synthesizeCancelationEventsForAllConnectionsLocked(options);
1134 }
1135 break;
1136 }
Chris Yef59a2f42020-10-16 12:55:26 -07001137 case EventEntry::Type::SENSOR: {
1138 break;
1139 }
arthurhungb89ccb02020-12-30 16:19:01 +08001140 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1141 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001142 break;
1143 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001144 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001145 case EventEntry::Type::TOUCH_MODE_CHANGED:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001146 case EventEntry::Type::CONFIGURATION_CHANGED:
1147 case EventEntry::Type::DEVICE_RESET: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001148 LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001149 break;
1150 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001151 }
1152}
1153
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001154static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001155 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1156 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001157}
1158
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001159bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1160 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1161 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1162 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001163}
1164
1165bool InputDispatcher::isAppSwitchPendingLocked() {
1166 return mAppSwitchDueTime != LONG_LONG_MAX;
1167}
1168
1169void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1170 mAppSwitchDueTime = LONG_LONG_MAX;
1171
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001172 if (DEBUG_APP_SWITCH) {
1173 if (handled) {
1174 ALOGD("App switch has arrived.");
1175 } else {
1176 ALOGD("App switch was abandoned.");
1177 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001178 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179}
1180
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001182 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001183}
1184
Prabir Pradhancef936d2021-07-21 16:17:52 +00001185bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001186 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001187 return false;
1188 }
1189
1190 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001191 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001192 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001193 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1194 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001195 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001196 return true;
1197}
1198
Prabir Pradhancef936d2021-07-21 16:17:52 +00001199void InputDispatcher::postCommandLocked(Command&& command) {
1200 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201}
1202
1203void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001204 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001205 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001206 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001207 releaseInboundEventLocked(entry);
1208 }
1209 traceInboundQueueLengthLocked();
1210}
1211
1212void InputDispatcher::releasePendingEventLocked() {
1213 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001214 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001215 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001216 }
1217}
1218
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001219void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001220 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001221 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001222 if (DEBUG_DISPATCH_CYCLE) {
1223 ALOGD("Injected inbound event was dropped.");
1224 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001225 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001226 }
1227 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001228 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001229 }
1230 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001231}
1232
1233void InputDispatcher::resetKeyRepeatLocked() {
1234 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001235 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001236 }
1237}
1238
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001239std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1240 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001241
Michael Wright2e732952014-09-24 13:26:59 -07001242 uint32_t policyFlags = entry->policyFlags &
1243 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001244
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001245 std::shared_ptr<KeyEntry> newEntry =
1246 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1247 entry->source, entry->displayId, policyFlags, entry->action,
1248 entry->flags, entry->keyCode, entry->scanCode,
1249 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001250
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001251 newEntry->syntheticRepeat = true;
1252 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001254 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001255}
1256
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001257bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001258 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001259 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1260 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1261 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001262
1263 // Reset key repeating in case a keyboard device was added or removed or something.
1264 resetKeyRepeatLocked();
1265
1266 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001267 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1268 scoped_unlock unlock(mLock);
1269 mPolicy->notifyConfigurationChanged(eventTime);
1270 };
1271 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001272 return true;
1273}
1274
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001275bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1276 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001277 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1278 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1279 entry.deviceId);
1280 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281
liushenxiang42232912021-05-21 20:24:09 +08001282 // Reset key repeating in case a keyboard device was disabled or enabled.
1283 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1284 resetKeyRepeatLocked();
1285 }
1286
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001287 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001288 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001289 synthesizeCancelationEventsForAllConnectionsLocked(options);
1290 return true;
1291}
1292
Vishnu Nairad321cd2020-08-20 16:40:21 -07001293void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001294 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001295 if (mPendingEvent != nullptr) {
1296 // Move the pending event to the front of the queue. This will give the chance
1297 // for the pending event to get dispatched to the newly focused window
1298 mInboundQueue.push_front(mPendingEvent);
1299 mPendingEvent = nullptr;
1300 }
1301
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001302 std::unique_ptr<FocusEntry> focusEntry =
1303 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1304 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001305
1306 // This event should go to the front of the queue, but behind all other focus events
1307 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001308 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001309 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001310 [](const std::shared_ptr<EventEntry>& event) {
1311 return event->type == EventEntry::Type::FOCUS;
1312 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001313
1314 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001315 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001316}
1317
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001318void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001319 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001320 if (channel == nullptr) {
1321 return; // Window has gone away
1322 }
1323 InputTarget target;
1324 target.inputChannel = channel;
1325 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1326 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001327 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1328 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001329 std::string reason = std::string("reason=").append(entry->reason);
1330 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001331 dispatchEventLocked(currentTime, entry, {target});
1332}
1333
Prabir Pradhan99987712020-11-10 18:43:05 -08001334void InputDispatcher::dispatchPointerCaptureChangedLocked(
1335 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1336 DropReason& dropReason) {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001337 dropReason = DropReason::NOT_DROPPED;
1338
Prabir Pradhan99987712020-11-10 18:43:05 -08001339 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan99987712020-11-10 18:43:05 -08001340 sp<IBinder> token;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001341
1342 if (entry->pointerCaptureRequest.enable) {
1343 // Enable Pointer Capture.
1344 if (haveWindowWithPointerCapture &&
1345 (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1346 LOG_ALWAYS_FATAL("This request to enable Pointer Capture has already been dispatched "
1347 "to the window.");
1348 }
1349 if (!mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001350 // This can happen if a window requests capture and immediately releases capture.
1351 ALOGW("No window requested Pointer Capture.");
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001352 dropReason = DropReason::NO_POINTER_CAPTURE;
Prabir Pradhan99987712020-11-10 18:43:05 -08001353 return;
1354 }
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001355 if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1356 ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1357 return;
1358 }
1359
Vishnu Nairc519ff72021-01-21 08:23:08 -08001360 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001361 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1362 mWindowTokenWithPointerCapture = token;
1363 } else {
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001364 // Disable Pointer Capture.
1365 // We do not check if the sequence number matches for requests to disable Pointer Capture
1366 // for two reasons:
1367 // 1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1368 // to disable capture with the same sequence number: one generated by
1369 // disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1370 // Capture being disabled in InputReader.
1371 // 2. We respect any request to disable Pointer Capture generated by InputReader, since the
1372 // actual Pointer Capture state that affects events being generated by input devices is
1373 // in InputReader.
1374 if (!haveWindowWithPointerCapture) {
1375 // Pointer capture was already forcefully disabled because of focus change.
1376 dropReason = DropReason::NOT_DROPPED;
1377 return;
1378 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001379 token = mWindowTokenWithPointerCapture;
1380 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001381 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001382 setPointerCaptureLocked(false);
1383 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001384 }
1385
1386 auto channel = getInputChannelLocked(token);
1387 if (channel == nullptr) {
1388 // Window has gone away, clean up Pointer Capture state.
1389 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00001390 if (mCurrentPointerCaptureRequest.enable) {
Prabir Pradhan7d030382020-12-21 07:58:35 -08001391 setPointerCaptureLocked(false);
1392 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001393 return;
1394 }
1395 InputTarget target;
1396 target.inputChannel = channel;
1397 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1398 entry->dispatchInProgress = true;
1399 dispatchEventLocked(currentTime, entry, {target});
1400
1401 dropReason = DropReason::NOT_DROPPED;
1402}
1403
Antonio Kantek7242d8b2021-08-05 16:07:20 -07001404void InputDispatcher::dispatchTouchModeChangeLocked(nsecs_t currentTime,
1405 const std::shared_ptr<TouchModeEntry>& entry) {
1406 const std::vector<sp<WindowInfoHandle>>& windowHandles =
1407 getWindowHandlesLocked(mFocusedDisplayId);
1408 if (windowHandles.empty()) {
1409 return;
1410 }
1411 const std::vector<InputTarget> inputTargets =
1412 getInputTargetsFromWindowHandlesLocked(windowHandles);
1413 if (inputTargets.empty()) {
1414 return;
1415 }
1416 entry->dispatchInProgress = true;
1417 dispatchEventLocked(currentTime, entry, inputTargets);
1418}
1419
1420std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1421 const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1422 std::vector<InputTarget> inputTargets;
1423 for (const sp<WindowInfoHandle>& handle : windowHandles) {
1424 // TODO(b/193718270): Due to performance concerns, consider notifying visible windows only.
1425 const sp<IBinder>& token = handle->getToken();
1426 if (token == nullptr) {
1427 continue;
1428 }
1429 std::shared_ptr<InputChannel> channel = getInputChannelLocked(token);
1430 if (channel == nullptr) {
1431 continue; // Window has gone away
1432 }
1433 InputTarget target;
1434 target.inputChannel = channel;
1435 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1436 inputTargets.push_back(target);
1437 }
1438 return inputTargets;
1439}
1440
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001441bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001442 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001443 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001444 if (!entry->dispatchInProgress) {
1445 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1446 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1447 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1448 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001449 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001450 // We have seen two identical key downs in a row which indicates that the device
1451 // driver is automatically generating key repeats itself. We take note of the
1452 // repeat here, but we disable our own next key repeat timer since it is clear that
1453 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001454 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1455 // Make sure we don't get key down from a different device. If a different
1456 // device Id has same key pressed down, the new device Id will replace the
1457 // current one to hold the key repeat with repeat count reset.
1458 // In the future when got a KEY_UP on the device id, drop it and do not
1459 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001460 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1461 resetKeyRepeatLocked();
1462 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1463 } else {
1464 // Not a repeat. Save key down state in case we do see a repeat later.
1465 resetKeyRepeatLocked();
1466 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1467 }
1468 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001469 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1470 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001471 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001472 if (DEBUG_INBOUND_EVENT_DETAILS) {
1473 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1474 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001475 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001476 resetKeyRepeatLocked();
1477 }
1478
1479 if (entry->repeatCount == 1) {
1480 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1481 } else {
1482 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1483 }
1484
1485 entry->dispatchInProgress = true;
1486
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001487 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001488 }
1489
1490 // Handle case where the policy asked us to try again later last time.
1491 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1492 if (currentTime < entry->interceptKeyWakeupTime) {
1493 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1494 *nextWakeupTime = entry->interceptKeyWakeupTime;
1495 }
1496 return false; // wait until next wakeup
1497 }
1498 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1499 entry->interceptKeyWakeupTime = 0;
1500 }
1501
1502 // Give the policy a chance to intercept the key.
1503 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1504 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001505 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001506 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001507
1508 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1509 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1510 };
1511 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001512 return false; // wait for the command to run
1513 } else {
1514 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1515 }
1516 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001517 if (*dropReason == DropReason::NOT_DROPPED) {
1518 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001519 }
1520 }
1521
1522 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001523 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001524 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001525 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1526 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001527 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001528 return true;
1529 }
1530
1531 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001532 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001533 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001534 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001535 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001536 return false;
1537 }
1538
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001539 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001540 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001541 return true;
1542 }
1543
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001544 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001545 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001546
1547 // Dispatch the key.
1548 dispatchEventLocked(currentTime, entry, inputTargets);
1549 return true;
1550}
1551
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001552void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001553 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1554 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1555 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1556 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1557 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1558 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1559 entry.metaState, entry.repeatCount, entry.downTime);
1560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001561}
1562
Prabir Pradhancef936d2021-07-21 16:17:52 +00001563void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1564 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001565 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001566 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1567 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1568 "source=0x%x, sensorType=%s",
1569 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
Dominik Laskowski75788452021-02-09 18:51:25 -08001570 ftl::enum_string(entry->sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001571 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001572 auto command = [this, entry]() REQUIRES(mLock) {
1573 scoped_unlock unlock(mLock);
1574
1575 if (entry->accuracyChanged) {
1576 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1577 }
1578 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1579 entry->hwTimestamp, entry->values);
1580 };
1581 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001582}
1583
1584bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001585 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1586 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
Dominik Laskowski75788452021-02-09 18:51:25 -08001587 ftl::enum_string(sensorType).c_str());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001588 }
Chris Yef59a2f42020-10-16 12:55:26 -07001589 { // acquire lock
1590 std::scoped_lock _l(mLock);
1591
1592 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1593 std::shared_ptr<EventEntry> entry = *it;
1594 if (entry->type == EventEntry::Type::SENSOR) {
1595 it = mInboundQueue.erase(it);
1596 releaseInboundEventLocked(entry);
1597 }
1598 }
1599 }
1600 return true;
1601}
1602
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001603bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001604 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001605 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001606 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001607 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001608 entry->dispatchInProgress = true;
1609
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001610 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001611 }
1612
1613 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001614 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001615 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001616 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1617 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001618 return true;
1619 }
1620
Prabir Pradhanaa561d12021-09-24 06:57:33 -07001621 const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001622
1623 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001624 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001625
1626 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001627 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001628 if (isPointerEvent) {
1629 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001630 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001631 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001632 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001633 } else {
1634 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001635 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001636 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001637 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001638 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001639 return false;
1640 }
1641
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001642 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001643 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001644 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1645 return true;
1646 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001647 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001648 CancelationOptions::Mode mode(isPointerEvent
1649 ? CancelationOptions::CANCEL_POINTER_EVENTS
1650 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1651 CancelationOptions options(mode, "input event injection failed");
1652 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001653 return true;
1654 }
1655
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001656 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001657 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001658
1659 // Dispatch the motion.
1660 if (conflictingPointerActions) {
1661 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001662 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001663 synthesizeCancelationEventsForAllConnectionsLocked(options);
1664 }
1665 dispatchEventLocked(currentTime, entry, inputTargets);
1666 return true;
1667}
1668
chaviw98318de2021-05-19 16:45:23 -05001669void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001670 bool isExiting, const MotionEntry& motionEntry) {
1671 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1672 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1673 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1674 PointerCoords pointerCoords;
1675 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1676 pointerCoords.transform(windowHandle->getInfo()->transform);
1677
1678 std::unique_ptr<DragEntry> dragEntry =
1679 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1680 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1681 pointerCoords.getY());
1682
1683 enqueueInboundEventLocked(std::move(dragEntry));
1684}
1685
1686void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1687 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1688 if (channel == nullptr) {
1689 return; // Window has gone away
1690 }
1691 InputTarget target;
1692 target.inputChannel = channel;
1693 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1694 entry->dispatchInProgress = true;
1695 dispatchEventLocked(currentTime, entry, {target});
1696}
1697
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001698void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001699 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1700 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1701 ", policyFlags=0x%x, "
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001702 "action=%s, actionButton=0x%x, flags=0x%x, "
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001703 "metaState=0x%x, buttonState=0x%x,"
1704 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1705 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
Siarhei Vishniakouca205502021-07-16 21:31:58 +00001706 entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
1707 entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
1708 entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001709
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001710 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1711 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1712 "x=%f, y=%f, pressure=%f, size=%f, "
1713 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1714 "orientation=%f",
1715 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1716 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1717 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1718 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1719 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1720 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1721 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1722 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1723 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1724 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1725 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001726 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001727}
1728
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001729void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1730 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001731 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001732 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001733 if (DEBUG_DISPATCH_CYCLE) {
1734 ALOGD("dispatchEventToCurrentInputTargets");
1735 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001736
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001737 updateInteractionTokensLocked(*eventEntry, inputTargets);
1738
Michael Wrightd02c5b62014-02-10 15:10:22 -08001739 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1740
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001741 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001742
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001743 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001744 sp<Connection> connection =
1745 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001746 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001747 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001748 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001749 if (DEBUG_FOCUS) {
1750 ALOGD("Dropping event delivery to target with channel '%s' because it "
1751 "is no longer registered with the input dispatcher.",
1752 inputTarget.inputChannel->getName().c_str());
1753 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001754 }
1755 }
1756}
1757
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001758void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1759 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1760 // If the policy decides to close the app, we will get a channel removal event via
1761 // unregisterInputChannel, and will clean up the connection that way. We are already not
1762 // sending new pointers to the connection when it blocked, but focused events will continue to
1763 // pile up.
1764 ALOGW("Canceling events for %s because it is unresponsive",
1765 connection->inputChannel->getName().c_str());
1766 if (connection->status == Connection::STATUS_NORMAL) {
1767 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1768 "application not responding");
1769 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001770 }
1771}
1772
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001773void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001774 if (DEBUG_FOCUS) {
1775 ALOGD("Resetting ANR timeouts.");
1776 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001777
1778 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001779 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001780 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001781}
1782
Tiger Huang721e26f2018-07-24 22:26:19 +08001783/**
1784 * Get the display id that the given event should go to. If this event specifies a valid display id,
1785 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1786 * Focused display is the display that the user most recently interacted with.
1787 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001788int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001789 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001790 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001791 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001792 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1793 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001794 break;
1795 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001796 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001797 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1798 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001799 break;
1800 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00001801 case EventEntry::Type::TOUCH_MODE_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001802 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001803 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001804 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001805 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001806 case EventEntry::Type::SENSOR:
1807 case EventEntry::Type::DRAG: {
Dominik Laskowski75788452021-02-09 18:51:25 -08001808 ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001809 return ADISPLAY_ID_NONE;
1810 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001811 }
1812 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1813}
1814
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001815bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1816 const char* focusedWindowName) {
1817 if (mAnrTracker.empty()) {
1818 // already processed all events that we waited for
1819 mKeyIsWaitingForEventsTimeout = std::nullopt;
1820 return false;
1821 }
1822
1823 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1824 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001825 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001826 mKeyIsWaitingForEventsTimeout = currentTime +
1827 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1828 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001829 return true;
1830 }
1831
1832 // We still have pending events, and already started the timer
1833 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1834 return true; // Still waiting
1835 }
1836
1837 // Waited too long, and some connection still hasn't processed all motions
1838 // Just send the key to the focused window
1839 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1840 focusedWindowName);
1841 mKeyIsWaitingForEventsTimeout = std::nullopt;
1842 return false;
1843}
1844
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001845InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1846 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1847 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001848 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001849
Tiger Huang721e26f2018-07-24 22:26:19 +08001850 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001851 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001852 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001853 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1854
Michael Wrightd02c5b62014-02-10 15:10:22 -08001855 // If there is no currently focused window and no focused application
1856 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001857 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1858 ALOGI("Dropping %s event because there is no focused window or focused application in "
1859 "display %" PRId32 ".",
Dominik Laskowski75788452021-02-09 18:51:25 -08001860 ftl::enum_string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001861 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862 }
1863
Vishnu Nair062a8672021-09-03 16:07:44 -07001864 // Drop key events if requested by input feature
1865 if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
1866 return InputEventInjectionResult::FAILED;
1867 }
1868
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001869 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1870 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1871 // start interacting with another application via touch (app switch). This code can be removed
1872 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1873 // an app is expected to have a focused window.
1874 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1875 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1876 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001877 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1878 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1879 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001880 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001881 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001882 ALOGW("Waiting because no window has focus but %s may eventually add a "
1883 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001884 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001885 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001886 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001887 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1888 // Already raised ANR. Drop the event
1889 ALOGE("Dropping %s event because there is no focused window",
Dominik Laskowski75788452021-02-09 18:51:25 -08001890 ftl::enum_string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001891 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001892 } else {
1893 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001894 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001895 }
1896 }
1897
1898 // we have a valid, non-null focused window
1899 resetNoFocusedWindowTimeoutLocked();
1900
Michael Wrightd02c5b62014-02-10 15:10:22 -08001901 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001902 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001903 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001904 }
1905
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001906 if (focusedWindowHandle->getInfo()->paused) {
1907 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001908 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001909 }
1910
1911 // If the event is a key event, then we must wait for all previous events to
1912 // complete before delivering it because previous events may have the
1913 // side-effect of transferring focus to a different window and we want to
1914 // ensure that the following keys are sent to the new window.
1915 //
1916 // Suppose the user touches a button in a window then immediately presses "A".
1917 // If the button causes a pop-up window to appear then we want to ensure that
1918 // the "A" key is delivered to the new pop-up window. This is because users
1919 // often anticipate pending UI changes when typing on a keyboard.
1920 // To obtain this behavior, we must serialize key events with respect to all
1921 // prior input events.
1922 if (entry.type == EventEntry::Type::KEY) {
1923 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1924 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001925 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001926 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001927 }
1928
1929 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001930 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001931 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1932 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001933
1934 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001935 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001936}
1937
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001938/**
1939 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1940 * that are currently unresponsive.
1941 */
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001942std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
1943 const std::vector<Monitor>& monitors) const {
1944 std::vector<Monitor> responsiveMonitors;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001945 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001946 [this](const Monitor& monitor) REQUIRES(mLock) {
1947 sp<Connection> connection =
1948 getConnectionLocked(monitor.inputChannel->getConnectionToken());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001949 if (connection == nullptr) {
1950 ALOGE("Could not find connection for monitor %s",
Prabir Pradhan0a99c922021-09-03 08:27:53 -07001951 monitor.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001952 return false;
1953 }
1954 if (!connection->responsive) {
1955 ALOGW("Unresponsive monitor %s will not get the new gesture",
1956 connection->inputChannel->getName().c_str());
1957 return false;
1958 }
1959 return true;
1960 });
1961 return responsiveMonitors;
1962}
1963
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001964InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1965 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1966 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001967 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001968 enum InjectionPermission {
1969 INJECTION_PERMISSION_UNKNOWN,
1970 INJECTION_PERMISSION_GRANTED,
1971 INJECTION_PERMISSION_DENIED
1972 };
1973
Michael Wrightd02c5b62014-02-10 15:10:22 -08001974 // For security reasons, we defer updating the touch state until we are sure that
1975 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001976 int32_t displayId = entry.displayId;
1977 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1979
1980 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001981 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001982 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001983 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1984 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001985
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001986 // Copy current touch state into tempTouchState.
1987 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1988 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001989 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001990 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001991 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1992 mTouchStatesByDisplay.find(displayId);
1993 if (oldStateIt != mTouchStatesByDisplay.end()) {
1994 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001995 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001996 }
1997
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001998 bool isSplit = tempTouchState.split;
1999 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
2000 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
2001 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002002 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2003 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2004 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2005 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2006 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Prabir Pradhanaa561d12021-09-24 06:57:33 -07002007 const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008 bool wrongDevice = false;
2009 if (newGesture) {
2010 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002011 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002012 ALOGI("Dropping event because a pointer for a different device is already down "
2013 "in display %" PRId32,
2014 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002015 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002016 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002017 switchedDevice = false;
2018 wrongDevice = true;
2019 goto Failed;
2020 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002021 tempTouchState.reset();
2022 tempTouchState.down = down;
2023 tempTouchState.deviceId = entry.deviceId;
2024 tempTouchState.source = entry.source;
2025 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002026 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002027 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002028 ALOGI("Dropping move event because a pointer for a different device is already active "
2029 "in display %" PRId32,
2030 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002031 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002032 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04002033 switchedDevice = false;
2034 wrongDevice = true;
2035 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002036 }
2037
2038 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2039 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2040
Garfield Tan00f511d2019-06-12 16:55:40 -07002041 int32_t x;
2042 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002043 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07002044 // Always dispatch mouse events to cursor position.
2045 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002046 x = int32_t(entry.xCursorPosition);
2047 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07002048 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002049 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
2050 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07002051 }
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002052 const bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002053 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
2054 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00002055
Michael Wrightd02c5b62014-02-10 15:10:22 -08002056 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002057 if (newTouchedWindowHandle != nullptr &&
2058 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07002059 // New window supports splitting, but we should never split mouse events.
2060 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002061 } else if (isSplit) {
2062 // New window does not support splitting but we have already split events.
2063 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002064 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002065 }
2066
2067 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002068 if (newTouchedWindowHandle == nullptr) {
Arthur Hungb3307ee2021-10-14 10:57:37 +00002069 ALOGD("No new touched window at (%" PRId32 ", %" PRId32 ") in display %" PRId32, x, y,
2070 displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002071 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002072 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002073 }
2074
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002075 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2076 ALOGI("Not sending touch event to %s because it is paused",
2077 newTouchedWindowHandle->getName().c_str());
2078 newTouchedWindowHandle = nullptr;
2079 }
2080
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002081 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002082 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002083 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2084 if (!isResponsive) {
2085 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002086 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2087 newTouchedWindowHandle = nullptr;
2088 }
2089 }
2090
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002091 // Drop events that can't be trusted due to occlusion
2092 if (newTouchedWindowHandle != nullptr &&
2093 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2094 TouchOcclusionInfo occlusionInfo =
2095 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002096 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002097 if (DEBUG_TOUCH_OCCLUSION) {
2098 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2099 for (const auto& log : occlusionInfo.debugInfo) {
2100 ALOGD("%s", log.c_str());
2101 }
2102 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002103 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002104 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2105 ALOGW("Dropping untrusted touch event due to %s/%d",
2106 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2107 newTouchedWindowHandle = nullptr;
2108 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002109 }
2110 }
2111
Vishnu Nair062a8672021-09-03 16:07:44 -07002112 // Drop touch events if requested by input feature
2113 if (newTouchedWindowHandle != nullptr && shouldDropInput(entry, newTouchedWindowHandle)) {
2114 newTouchedWindowHandle = nullptr;
2115 }
2116
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002117 const std::vector<Monitor> newGestureMonitors = isDown
2118 ? selectResponsiveMonitorsLocked(
2119 getValueByKey(mGestureMonitorsByDisplay, displayId))
2120 : std::vector<Monitor>{};
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002121
Michael Wright3dd60e22019-03-27 22:06:44 +00002122 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2123 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002124 "(%d, %d) in display %" PRId32 ".",
2125 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002126 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002127 goto Failed;
2128 }
2129
2130 if (newTouchedWindowHandle != nullptr) {
2131 // Set target flags.
2132 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2133 if (isSplit) {
2134 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002135 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002136 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2137 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2138 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2139 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2140 }
2141
2142 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002143 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2144 newHoverWindowHandle = nullptr;
2145 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002146 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002147 }
2148
2149 // Update the temporary touch state.
2150 BitSet32 pointerIds;
2151 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002152 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002153 pointerIds.markBit(pointerId);
2154 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002155 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002156 }
2157
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002158 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002159 } else {
2160 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2161
2162 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002163 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002164 if (DEBUG_FOCUS) {
2165 ALOGD("Dropping event because the pointer is not down or we previously "
2166 "dropped the pointer down event in display %" PRId32,
2167 displayId);
2168 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002169 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002170 goto Failed;
2171 }
2172
arthurhung6d4bed92021-03-17 11:59:33 +08002173 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002174
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002176 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002177 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002178 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2179 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180
chaviw98318de2021-05-19 16:45:23 -05002181 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002182 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002183 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Vishnu Nair062a8672021-09-03 16:07:44 -07002184
2185 // Drop touch events if requested by input feature
2186 if (newTouchedWindowHandle != nullptr &&
2187 shouldDropInput(entry, newTouchedWindowHandle)) {
2188 newTouchedWindowHandle = nullptr;
2189 }
2190
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002191 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2192 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002193 if (DEBUG_FOCUS) {
2194 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2195 oldTouchedWindowHandle->getName().c_str(),
2196 newTouchedWindowHandle->getName().c_str(), displayId);
2197 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002198 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002199 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2200 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2201 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002202
2203 // Make a slippery entrance into the new window.
2204 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2205 isSplit = true;
2206 }
2207
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002208 int32_t targetFlags =
2209 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002210 if (isSplit) {
2211 targetFlags |= InputTarget::FLAG_SPLIT;
2212 }
2213 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2214 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002215 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2216 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002217 }
2218
2219 BitSet32 pointerIds;
2220 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002221 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002222 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002223 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002224 }
2225 }
2226 }
2227
2228 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002229 // Let the previous window know that the hover sequence is over, unless we already did it
2230 // when dispatching it as is to newTouchedWindowHandle.
2231 if (mLastHoverWindowHandle != nullptr &&
2232 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2233 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002234 if (DEBUG_HOVER) {
2235 ALOGD("Sending hover exit event to window %s.",
2236 mLastHoverWindowHandle->getName().c_str());
2237 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002238 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2239 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240 }
2241
Garfield Tandf26e862020-07-01 20:18:19 -07002242 // Let the new window know that the hover sequence is starting, unless we already did it
2243 // when dispatching it as is to newTouchedWindowHandle.
2244 if (newHoverWindowHandle != nullptr &&
2245 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2246 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002247 if (DEBUG_HOVER) {
2248 ALOGD("Sending hover enter event to window %s.",
2249 newHoverWindowHandle->getName().c_str());
2250 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002251 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2252 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2253 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002254 }
2255 }
2256
2257 // Check permission to inject into all touched foreground windows and ensure there
2258 // is at least one touched foreground window.
2259 {
2260 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002261 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002262 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2263 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002264 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002265 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002266 injectionPermission = INJECTION_PERMISSION_DENIED;
2267 goto Failed;
2268 }
2269 }
2270 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002271 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002272 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002273 ALOGI("Dropping event because there is no touched foreground window in display "
2274 "%" PRId32 " or gesture monitor to receive it.",
2275 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002276 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002277 goto Failed;
2278 }
2279
2280 // Permission granted to injection into all touched foreground windows.
2281 injectionPermission = INJECTION_PERMISSION_GRANTED;
2282 }
2283
2284 // Check whether windows listening for outside touches are owned by the same UID. If it is
2285 // set the policy flag that we will not reveal coordinate information to this window.
2286 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002287 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002288 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002289 if (foregroundWindowHandle) {
2290 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002291 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002292 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002293 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2294 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2295 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002296 InputTarget::FLAG_ZERO_COORDS,
2297 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002298 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002299 }
2300 }
2301 }
2302 }
2303
Michael Wrightd02c5b62014-02-10 15:10:22 -08002304 // If this is the first pointer going down and the touched window has a wallpaper
2305 // then also add the touched wallpaper windows so they are locked in for the duration
2306 // of the touch gesture.
2307 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2308 // engine only supports touch events. We would need to add a mechanism similar
2309 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2310 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002311 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002312 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002313 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002314 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002315 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002316 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2317 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002318 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002319 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002320 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002321 .addOrUpdateWindow(windowHandle,
2322 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2323 InputTarget::
2324 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2325 InputTarget::FLAG_DISPATCH_AS_IS,
2326 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002327 }
2328 }
2329 }
2330 }
2331
2332 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002333 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002334
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002335 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002336 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002337 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338 }
2339
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002340 for (const auto& monitor : tempTouchState.gestureMonitors) {
2341 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002342 }
2343
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 // Drop the outside or hover touch windows since we will not care about them
2345 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002346 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002347
2348Failed:
2349 // Check injection permission once and for all.
2350 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002351 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352 injectionPermission = INJECTION_PERMISSION_GRANTED;
2353 } else {
2354 injectionPermission = INJECTION_PERMISSION_DENIED;
2355 }
2356 }
2357
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002358 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2359 return injectionResult;
2360 }
2361
Michael Wrightd02c5b62014-02-10 15:10:22 -08002362 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002363 if (!wrongDevice) {
2364 if (switchedDevice) {
2365 if (DEBUG_FOCUS) {
2366 ALOGD("Conflicting pointer actions: Switched to a different device.");
2367 }
2368 *outConflictingPointerActions = true;
2369 }
2370
2371 if (isHoverAction) {
2372 // Started hovering, therefore no longer down.
2373 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002374 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002375 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2376 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002377 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002378 *outConflictingPointerActions = true;
2379 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002380 tempTouchState.reset();
2381 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2382 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2383 tempTouchState.deviceId = entry.deviceId;
2384 tempTouchState.source = entry.source;
2385 tempTouchState.displayId = displayId;
2386 }
2387 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2388 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2389 // All pointers up or canceled.
2390 tempTouchState.reset();
2391 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2392 // First pointer went down.
2393 if (oldState && oldState->down) {
2394 if (DEBUG_FOCUS) {
2395 ALOGD("Conflicting pointer actions: Down received while already down.");
2396 }
2397 *outConflictingPointerActions = true;
2398 }
2399 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2400 // One pointer went up.
2401 if (isSplit) {
2402 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2403 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002404
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002405 for (size_t i = 0; i < tempTouchState.windows.size();) {
2406 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2407 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2408 touchedWindow.pointerIds.clearBit(pointerId);
2409 if (touchedWindow.pointerIds.isEmpty()) {
2410 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2411 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002412 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002413 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002414 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002415 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002416 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002417 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002418
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002419 // Save changes unless the action was scroll in which case the temporary touch
2420 // state was only valid for this one action.
2421 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2422 if (tempTouchState.displayId >= 0) {
2423 mTouchStatesByDisplay[displayId] = tempTouchState;
2424 } else {
2425 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002426 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002427 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002428
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002429 // Update hover state.
2430 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002431 }
2432
Michael Wrightd02c5b62014-02-10 15:10:22 -08002433 return injectionResult;
2434}
2435
arthurhung6d4bed92021-03-17 11:59:33 +08002436void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002437 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002438 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002439 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002440 if (dropWindow) {
2441 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002442 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002443 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002444 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002445 }
2446 mDragState.reset();
2447}
2448
2449void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2450 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002451 return;
2452 }
2453
arthurhung6d4bed92021-03-17 11:59:33 +08002454 if (!mDragState->isStartDrag) {
2455 mDragState->isStartDrag = true;
2456 mDragState->isStylusButtonDownAtStart =
2457 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2458 }
2459
arthurhungb89ccb02020-12-30 16:19:01 +08002460 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2461 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2462 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2463 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002464 // Handle the special case : stylus button no longer pressed.
2465 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2466 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2467 finishDragAndDrop(entry.displayId, x, y);
2468 return;
2469 }
2470
chaviw98318de2021-05-19 16:45:23 -05002471 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002472 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002473 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002474 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002475 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2476 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2477 if (mDragState->dragHoverWindowHandle != nullptr) {
2478 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2479 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002480 }
arthurhung6d4bed92021-03-17 11:59:33 +08002481 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002482 }
2483 // enqueue drag location if needed.
2484 if (hoverWindowHandle != nullptr) {
2485 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2486 }
arthurhung6d4bed92021-03-17 11:59:33 +08002487 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2488 finishDragAndDrop(entry.displayId, x, y);
2489 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002490 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002491 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002492 }
2493}
2494
chaviw98318de2021-05-19 16:45:23 -05002495void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002496 int32_t targetFlags, BitSet32 pointerIds,
2497 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002498 std::vector<InputTarget>::iterator it =
2499 std::find_if(inputTargets.begin(), inputTargets.end(),
2500 [&windowHandle](const InputTarget& inputTarget) {
2501 return inputTarget.inputChannel->getConnectionToken() ==
2502 windowHandle->getToken();
2503 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002504
chaviw98318de2021-05-19 16:45:23 -05002505 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002506
2507 if (it == inputTargets.end()) {
2508 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002509 std::shared_ptr<InputChannel> inputChannel =
2510 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002511 if (inputChannel == nullptr) {
2512 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2513 return;
2514 }
2515 inputTarget.inputChannel = inputChannel;
2516 inputTarget.flags = targetFlags;
2517 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002518 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2519 if (displayInfoIt != mDisplayInfos.end()) {
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002520 inputTarget.displayTransform = displayInfoIt->second.transform;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002521 } else {
2522 ALOGI_IF(isPerWindowInputRotationEnabled(),
2523 "DisplayInfo not found for window on display: %d", windowInfo->displayId);
2524 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002525 inputTargets.push_back(inputTarget);
2526 it = inputTargets.end() - 1;
2527 }
2528
2529 ALOG_ASSERT(it->flags == targetFlags);
2530 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2531
chaviw1ff3d1e2020-07-01 15:53:47 -07002532 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002533}
2534
Michael Wright3dd60e22019-03-27 22:06:44 +00002535void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002536 int32_t displayId) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002537 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2538 mGlobalMonitorsByDisplay.find(displayId);
2539
2540 if (it != mGlobalMonitorsByDisplay.end()) {
2541 const std::vector<Monitor>& monitors = it->second;
2542 for (const Monitor& monitor : monitors) {
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002543 addMonitoringTargetLocked(monitor, displayId, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002544 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002545 }
2546}
2547
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002548void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002549 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002550 InputTarget target;
2551 target.inputChannel = monitor.inputChannel;
2552 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
Prabir Pradhan0a99c922021-09-03 08:27:53 -07002553 ui::Transform t;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002554 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
Prabir Pradhanb5402b22021-10-04 05:52:50 -07002555 const auto& displayTransform = it->second.transform;
2556 target.displayTransform = displayTransform;
2557 t = displayTransform;
Prabir Pradhanb9b18502021-08-26 12:30:32 -07002558 }
chaviw1ff3d1e2020-07-01 15:53:47 -07002559 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002560 inputTargets.push_back(target);
2561}
2562
chaviw98318de2021-05-19 16:45:23 -05002563bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002564 const InjectionState* injectionState) {
2565 if (injectionState &&
2566 (windowHandle == nullptr ||
2567 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2568 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002569 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002570 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002571 "owned by uid %d",
2572 injectionState->injectorPid, injectionState->injectorUid,
2573 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574 } else {
2575 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002576 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002577 }
2578 return false;
2579 }
2580 return true;
2581}
2582
Robert Carrc9bf1d32020-04-13 17:21:08 -07002583/**
2584 * Indicate whether one window handle should be considered as obscuring
2585 * another window handle. We only check a few preconditions. Actually
2586 * checking the bounds is left to the caller.
2587 */
chaviw98318de2021-05-19 16:45:23 -05002588static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2589 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002590 // Compare by token so cloned layers aren't counted
2591 if (haveSameToken(windowHandle, otherHandle)) {
2592 return false;
2593 }
2594 auto info = windowHandle->getInfo();
2595 auto otherInfo = otherHandle->getInfo();
2596 if (!otherInfo->visible) {
2597 return false;
chaviw98318de2021-05-19 16:45:23 -05002598 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002599 // Those act as if they were invisible, so we don't need to flag them.
2600 // We do want to potentially flag touchable windows even if they have 0
2601 // opacity, since they can consume touches and alter the effects of the
2602 // user interaction (eg. apps that rely on
2603 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2604 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2605 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002606 } else if (info->ownerUid == otherInfo->ownerUid) {
2607 // If ownerUid is the same we don't generate occlusion events as there
2608 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002609 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002610 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002611 return false;
2612 } else if (otherInfo->displayId != info->displayId) {
2613 return false;
2614 }
2615 return true;
2616}
2617
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002618/**
2619 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2620 * untrusted, one should check:
2621 *
2622 * 1. If result.hasBlockingOcclusion is true.
2623 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2624 * BLOCK_UNTRUSTED.
2625 *
2626 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2627 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2628 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2629 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2630 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2631 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2632 *
2633 * If neither of those is true, then it means the touch can be allowed.
2634 */
2635InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002636 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2637 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002638 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002639 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002640 TouchOcclusionInfo info;
2641 info.hasBlockingOcclusion = false;
2642 info.obscuringOpacity = 0;
2643 info.obscuringUid = -1;
2644 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002645 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002646 if (windowHandle == otherHandle) {
2647 break; // All future windows are below us. Exit early.
2648 }
chaviw98318de2021-05-19 16:45:23 -05002649 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002650 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2651 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002652 if (DEBUG_TOUCH_OCCLUSION) {
2653 info.debugInfo.push_back(
2654 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2655 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002656 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2657 // we perform the checks below to see if the touch can be propagated or not based on the
2658 // window's touch occlusion mode
2659 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2660 info.hasBlockingOcclusion = true;
2661 info.obscuringUid = otherInfo->ownerUid;
2662 info.obscuringPackage = otherInfo->packageName;
2663 break;
2664 }
2665 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2666 uint32_t uid = otherInfo->ownerUid;
2667 float opacity =
2668 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2669 // Given windows A and B:
2670 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2671 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2672 opacityByUid[uid] = opacity;
2673 if (opacity > info.obscuringOpacity) {
2674 info.obscuringOpacity = opacity;
2675 info.obscuringUid = uid;
2676 info.obscuringPackage = otherInfo->packageName;
2677 }
2678 }
2679 }
2680 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002681 if (DEBUG_TOUCH_OCCLUSION) {
2682 info.debugInfo.push_back(
2683 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2684 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002685 return info;
2686}
2687
chaviw98318de2021-05-19 16:45:23 -05002688std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002689 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002690 return StringPrintf(INDENT2
2691 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2692 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2693 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2694 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Dominik Laskowski75788452021-02-09 18:51:25 -08002695 isTouchedWindow ? "[TOUCHED] " : "", ftl::enum_string(info->type).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002696 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002697 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2698 info->frameTop, info->frameRight, info->frameBottom,
2699 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002700 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2701 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2702 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002703}
2704
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002705bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2706 if (occlusionInfo.hasBlockingOcclusion) {
2707 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2708 occlusionInfo.obscuringUid);
2709 return false;
2710 }
2711 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2712 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2713 "%.2f, maximum allowed = %.2f)",
2714 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2715 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2716 return false;
2717 }
2718 return true;
2719}
2720
chaviw98318de2021-05-19 16:45:23 -05002721bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002722 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002723 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002724 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2725 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002726 if (windowHandle == otherHandle) {
2727 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728 }
chaviw98318de2021-05-19 16:45:23 -05002729 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002730 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002731 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732 return true;
2733 }
2734 }
2735 return false;
2736}
2737
chaviw98318de2021-05-19 16:45:23 -05002738bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002739 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002740 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2741 const WindowInfo* windowInfo = windowHandle->getInfo();
2742 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002743 if (windowHandle == otherHandle) {
2744 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002745 }
chaviw98318de2021-05-19 16:45:23 -05002746 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002747 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002748 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002749 return true;
2750 }
2751 }
2752 return false;
2753}
2754
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002755std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002756 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002757 if (applicationHandle != nullptr) {
2758 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002759 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002760 } else {
2761 return applicationHandle->getName();
2762 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002763 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002764 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002765 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002766 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002767 }
2768}
2769
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002770void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Antonio Kantekf16f2832021-09-28 04:39:20 +00002771 if (!isUserActivityEvent(eventEntry)) {
2772 // Not poking user activity if the event type does not represent a user activity
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002773 return;
2774 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002775 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002776 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002777 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002778 const WindowInfo* info = focusedWindowHandle->getInfo();
2779 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002780 if (DEBUG_DISPATCH_CYCLE) {
2781 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002783 return;
2784 }
2785 }
2786
2787 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002788 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002789 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002790 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2791 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002792 return;
2793 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002794
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002795 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002796 eventType = USER_ACTIVITY_EVENT_TOUCH;
2797 }
2798 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002799 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002800 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002801 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2802 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002803 return;
2804 }
2805 eventType = USER_ACTIVITY_EVENT_BUTTON;
2806 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002807 }
Antonio Kantekf16f2832021-09-28 04:39:20 +00002808 default: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002809 LOG_ALWAYS_FATAL("%s events are not user activity",
Dominik Laskowski75788452021-02-09 18:51:25 -08002810 ftl::enum_string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002811 break;
2812 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002813 }
2814
Prabir Pradhancef936d2021-07-21 16:17:52 +00002815 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2816 REQUIRES(mLock) {
2817 scoped_unlock unlock(mLock);
2818 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2819 };
2820 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002821}
2822
2823void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002824 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002825 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002826 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002827 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002828 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002829 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002830 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002831 ATRACE_NAME(message.c_str());
2832 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002833 if (DEBUG_DISPATCH_CYCLE) {
2834 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2835 "globalScaleFactor=%f, pointerIds=0x%x %s",
2836 connection->getInputChannelName().c_str(), inputTarget.flags,
2837 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2838 inputTarget.getPointerInfoString().c_str());
2839 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002840
2841 // Skip this event if the connection status is not normal.
2842 // We don't want to enqueue additional outbound events if the connection is broken.
2843 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002844 if (DEBUG_DISPATCH_CYCLE) {
2845 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2846 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2847 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002848 return;
2849 }
2850
2851 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002852 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2853 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2854 "Entry type %s should not have FLAG_SPLIT",
Dominik Laskowski75788452021-02-09 18:51:25 -08002855 ftl::enum_string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002856
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002857 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002858 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002859 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002860 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002861 if (!splitMotionEntry) {
2862 return; // split event was dropped
2863 }
Arthur Hungb3307ee2021-10-14 10:57:37 +00002864 if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
2865 std::string reason = std::string("reason=pointer cancel on split window");
2866 android_log_event_list(LOGTAG_INPUT_CANCEL)
2867 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
2868 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002869 if (DEBUG_FOCUS) {
2870 ALOGD("channel '%s' ~ Split motion event.",
2871 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002872 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002873 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002874 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2875 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002876 return;
2877 }
2878 }
2879
2880 // Not splitting. Enqueue dispatch entries for the event as is.
2881 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2882}
2883
2884void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002885 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002886 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002887 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002888 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002889 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002890 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002891 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002892 ATRACE_NAME(message.c_str());
2893 }
2894
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002895 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002896
2897 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002898 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002899 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002900 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002901 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002902 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002903 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002904 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002905 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002906 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002907 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002908 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002909 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002910
2911 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002912 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002913 startDispatchCycleLocked(currentTime, connection);
2914 }
2915}
2916
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002917void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002918 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002919 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002920 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002921 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002922 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2923 connection->getInputChannelName().c_str(),
2924 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002925 ATRACE_NAME(message.c_str());
2926 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002927 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002928 if (!(inputTargetFlags & dispatchMode)) {
2929 return;
2930 }
2931 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2932
2933 // This is a new event.
2934 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002935 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002936 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002937
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002938 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2939 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002940 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002941 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002942 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002943 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002944 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002945 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002946 dispatchEntry->resolvedAction = keyEntry.action;
2947 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002949 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2950 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002951 if (DEBUG_DISPATCH_CYCLE) {
2952 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2953 "event",
2954 connection->getInputChannelName().c_str());
2955 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002956 return; // skip the inconsistent event
2957 }
2958 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002959 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002960
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002961 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002962 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002963 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2964 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2965 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2966 static_cast<int32_t>(IdGenerator::Source::OTHER);
2967 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002968 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2969 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2970 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2971 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2972 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2973 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2974 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2975 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2976 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2977 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2978 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002979 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002980 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002981 }
2982 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002983 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2984 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002985 if (DEBUG_DISPATCH_CYCLE) {
2986 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
2987 "enter event",
2988 connection->getInputChannelName().c_str());
2989 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002990 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2991 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002992 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2993 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002994
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002995 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002996 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2997 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2998 }
2999 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
3000 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3001 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003002
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003003 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
3004 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003005 if (DEBUG_DISPATCH_CYCLE) {
3006 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
3007 "event",
3008 connection->getInputChannelName().c_str());
3009 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003010 return; // skip the inconsistent event
3011 }
3012
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003013 dispatchEntry->resolvedEventId =
3014 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
3015 ? mIdGenerator.nextId()
3016 : motionEntry.id;
3017 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
3018 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3019 ") to MotionEvent(id=0x%" PRIx32 ").",
3020 motionEntry.id, dispatchEntry->resolvedEventId);
3021 ATRACE_NAME(message.c_str());
3022 }
3023
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08003024 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3025 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
3026 // Skip reporting pointer down outside focus to the policy.
3027 break;
3028 }
3029
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003030 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003031 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003032
3033 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003034 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003035 case EventEntry::Type::FOCUS:
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003036 case EventEntry::Type::TOUCH_MODE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003037 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3038 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003039 break;
3040 }
Chris Yef59a2f42020-10-16 12:55:26 -07003041 case EventEntry::Type::SENSOR: {
3042 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3043 break;
3044 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003045 case EventEntry::Type::CONFIGURATION_CHANGED:
3046 case EventEntry::Type::DEVICE_RESET: {
3047 LOG_ALWAYS_FATAL("%s events should not go to apps",
Dominik Laskowski75788452021-02-09 18:51:25 -08003048 ftl::enum_string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003049 break;
3050 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051 }
3052
3053 // Remember that we are waiting for this dispatch to complete.
3054 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00003055 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003056 }
3057
3058 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08003059 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003060 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07003061}
3062
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003063/**
3064 * This function is purely for debugging. It helps us understand where the user interaction
3065 * was taking place. For example, if user is touching launcher, we will see a log that user
3066 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3067 * We will see both launcher and wallpaper in that list.
3068 * Once the interaction with a particular set of connections starts, no new logs will be printed
3069 * until the set of interacted connections changes.
3070 *
3071 * The following items are skipped, to reduce the logspam:
3072 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3073 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3074 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3075 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3076 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003077 */
3078void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3079 const std::vector<InputTarget>& targets) {
3080 // Skip ACTION_UP events, and all events other than keys and motions
3081 if (entry.type == EventEntry::Type::KEY) {
3082 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3083 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3084 return;
3085 }
3086 } else if (entry.type == EventEntry::Type::MOTION) {
3087 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3088 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3089 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3090 return;
3091 }
3092 } else {
3093 return; // Not a key or a motion
3094 }
3095
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003096 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003097 std::vector<sp<Connection>> newConnections;
3098 for (const InputTarget& target : targets) {
3099 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3100 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3101 continue; // Skip windows that receive ACTION_OUTSIDE
3102 }
3103
3104 sp<IBinder> token = target.inputChannel->getConnectionToken();
3105 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003106 if (connection == nullptr) {
3107 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003108 }
3109 newConnectionTokens.insert(std::move(token));
3110 newConnections.emplace_back(connection);
3111 }
3112 if (newConnectionTokens == mInteractionConnectionTokens) {
3113 return; // no change
3114 }
3115 mInteractionConnectionTokens = newConnectionTokens;
3116
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003117 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003118 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003119 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003120 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003121 std::string message = "Interaction with: " + targetList;
3122 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003123 message += "<none>";
3124 }
3125 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3126}
3127
chaviwfd6d3512019-03-25 13:23:49 -07003128void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003129 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003130 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003131 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3132 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003133 return;
3134 }
3135
Vishnu Nairc519ff72021-01-21 08:23:08 -08003136 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003137 if (focusedToken == token) {
3138 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003139 return;
3140 }
3141
Prabir Pradhancef936d2021-07-21 16:17:52 +00003142 auto command = [this, token]() REQUIRES(mLock) {
3143 scoped_unlock unlock(mLock);
3144 mPolicy->onPointerDownOutsideFocus(token);
3145 };
3146 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003147}
3148
3149void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003150 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003151 if (ATRACE_ENABLED()) {
3152 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003153 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003154 ATRACE_NAME(message.c_str());
3155 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003156 if (DEBUG_DISPATCH_CYCLE) {
3157 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3158 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003159
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003160 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3161 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003162 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003163 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003164 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003165 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003166
3167 // Publish the event.
3168 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003169 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3170 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003171 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003172 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3173 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003174
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003175 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003176 status = connection->inputPublisher
3177 .publishKeyEvent(dispatchEntry->seq,
3178 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3179 keyEntry.source, keyEntry.displayId,
3180 std::move(hmac), dispatchEntry->resolvedAction,
3181 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3182 keyEntry.scanCode, keyEntry.metaState,
3183 keyEntry.repeatCount, keyEntry.downTime,
3184 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003185 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003186 }
3187
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003188 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003189 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003190
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003191 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003192 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003193
chaviw82357092020-01-28 13:13:06 -08003194 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003195 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003196 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3197 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003198 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003199 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3200 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003201 // Don't apply window scale here since we don't want scale to affect raw
3202 // coordinates. The scale will be sent back to the client and applied
3203 // later when requesting relative coordinates.
3204 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3205 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003206 }
3207 usingCoords = scaledCoords;
3208 }
3209 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003210 // We don't want the dispatch target to know.
3211 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003212 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003213 scaledCoords[i].clear();
3214 }
3215 usingCoords = scaledCoords;
3216 }
3217 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003218
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003219 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003220
3221 // Publish the motion event.
3222 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003223 .publishMotionEvent(dispatchEntry->seq,
3224 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003225 motionEntry.deviceId, motionEntry.source,
3226 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003227 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003228 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003229 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003230 motionEntry.edgeFlags, motionEntry.metaState,
3231 motionEntry.buttonState,
3232 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003233 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003234 motionEntry.xPrecision, motionEntry.yPrecision,
3235 motionEntry.xCursorPosition,
3236 motionEntry.yCursorPosition,
Prabir Pradhanb9b18502021-08-26 12:30:32 -07003237 dispatchEntry->rawTransform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003238 motionEntry.downTime, motionEntry.eventTime,
3239 motionEntry.pointerCount,
3240 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003241 break;
3242 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003243
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003244 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003245 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003246 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003247 focusEntry.id,
3248 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003249 mInTouchMode);
3250 break;
3251 }
3252
Antonio Kantek7242d8b2021-08-05 16:07:20 -07003253 case EventEntry::Type::TOUCH_MODE_CHANGED: {
3254 const TouchModeEntry& touchModeEntry =
3255 static_cast<const TouchModeEntry&>(eventEntry);
3256 status = connection->inputPublisher
3257 .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3258 touchModeEntry.inTouchMode);
3259
3260 break;
3261 }
3262
Prabir Pradhan99987712020-11-10 18:43:05 -08003263 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3264 const auto& captureEntry =
3265 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3266 status = connection->inputPublisher
3267 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
Prabir Pradhan5cc1a692021-08-06 14:01:18 +00003268 captureEntry.pointerCaptureRequest.enable);
Prabir Pradhan99987712020-11-10 18:43:05 -08003269 break;
3270 }
3271
arthurhungb89ccb02020-12-30 16:19:01 +08003272 case EventEntry::Type::DRAG: {
3273 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3274 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3275 dragEntry.id, dragEntry.x,
3276 dragEntry.y,
3277 dragEntry.isExiting);
3278 break;
3279 }
3280
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003281 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003282 case EventEntry::Type::DEVICE_RESET:
3283 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003284 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Dominik Laskowski75788452021-02-09 18:51:25 -08003285 ftl::enum_string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003286 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003288 }
3289
3290 // Check the result.
3291 if (status) {
3292 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003293 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003295 "This is unexpected because the wait queue is empty, so the pipe "
3296 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003297 "event to it, status=%s(%d)",
3298 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3299 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003300 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3301 } else {
3302 // Pipe is full and we are waiting for the app to finish process some events
3303 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003304 if (DEBUG_DISPATCH_CYCLE) {
3305 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3306 "waiting for the application to catch up",
3307 connection->getInputChannelName().c_str());
3308 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003309 }
3310 } else {
3311 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003312 "status=%s(%d)",
3313 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3314 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003315 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3316 }
3317 return;
3318 }
3319
3320 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003321 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3322 connection->outboundQueue.end(),
3323 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003324 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003325 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003326 if (connection->responsive) {
3327 mAnrTracker.insert(dispatchEntry->timeoutTime,
3328 connection->inputChannel->getConnectionToken());
3329 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003330 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003331 }
3332}
3333
chaviw09c8d2d2020-08-24 15:48:26 -07003334std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3335 size_t size;
3336 switch (event.type) {
3337 case VerifiedInputEvent::Type::KEY: {
3338 size = sizeof(VerifiedKeyEvent);
3339 break;
3340 }
3341 case VerifiedInputEvent::Type::MOTION: {
3342 size = sizeof(VerifiedMotionEvent);
3343 break;
3344 }
3345 }
3346 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3347 return mHmacKeyManager.sign(start, size);
3348}
3349
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003350const std::array<uint8_t, 32> InputDispatcher::getSignature(
3351 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003352 const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3353 if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003354 // Only sign events up and down events as the purely move events
3355 // are tied to their up/down counterparts so signing would be redundant.
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003356 return INVALID_HMAC;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003357 }
Prabir Pradhanb5cb9572021-09-24 06:35:16 -07003358
3359 VerifiedMotionEvent verifiedEvent =
3360 verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3361 verifiedEvent.actionMasked = actionMasked;
3362 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3363 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003364}
3365
3366const std::array<uint8_t, 32> InputDispatcher::getSignature(
3367 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3368 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3369 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3370 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003371 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003372}
3373
Michael Wrightd02c5b62014-02-10 15:10:22 -08003374void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003375 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003376 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003377 if (DEBUG_DISPATCH_CYCLE) {
3378 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3379 connection->getInputChannelName().c_str(), seq, toString(handled));
3380 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003381
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003382 if (connection->status == Connection::STATUS_BROKEN ||
3383 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003384 return;
3385 }
3386
3387 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003388 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3389 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3390 };
3391 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003392}
3393
3394void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003395 const sp<Connection>& connection,
3396 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003397 if (DEBUG_DISPATCH_CYCLE) {
3398 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3399 connection->getInputChannelName().c_str(), toString(notify));
3400 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401
3402 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003403 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003404 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003405 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003406 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003407
3408 // The connection appears to be unrecoverably broken.
3409 // Ignore already broken or zombie connections.
3410 if (connection->status == Connection::STATUS_NORMAL) {
3411 connection->status = Connection::STATUS_BROKEN;
3412
3413 if (notify) {
3414 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003415 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3416 connection->getInputChannelName().c_str());
3417
3418 auto command = [this, connection]() REQUIRES(mLock) {
3419 if (connection->status == Connection::STATUS_ZOMBIE) return;
3420 scoped_unlock unlock(mLock);
3421 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3422 };
3423 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003424 }
3425 }
3426}
3427
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003428void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3429 while (!queue.empty()) {
3430 DispatchEntry* dispatchEntry = queue.front();
3431 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003432 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003433 }
3434}
3435
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003436void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003437 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003438 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003439 }
3440 delete dispatchEntry;
3441}
3442
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003443int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3444 std::scoped_lock _l(mLock);
3445 sp<Connection> connection = getConnectionLocked(connectionToken);
3446 if (connection == nullptr) {
3447 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3448 connectionToken.get(), events);
3449 return 0; // remove the callback
3450 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003451
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003452 bool notify;
3453 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3454 if (!(events & ALOOPER_EVENT_INPUT)) {
3455 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3456 "events=0x%x",
3457 connection->getInputChannelName().c_str(), events);
3458 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003459 }
3460
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003461 nsecs_t currentTime = now();
3462 bool gotOne = false;
3463 status_t status = OK;
3464 for (;;) {
3465 Result<InputPublisher::ConsumerResponse> result =
3466 connection->inputPublisher.receiveConsumerResponse();
3467 if (!result.ok()) {
3468 status = result.error().code();
3469 break;
3470 }
3471
3472 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3473 const InputPublisher::Finished& finish =
3474 std::get<InputPublisher::Finished>(*result);
3475 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3476 finish.consumeTime);
3477 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003478 if (shouldReportMetricsForConnection(*connection)) {
3479 const InputPublisher::Timeline& timeline =
3480 std::get<InputPublisher::Timeline>(*result);
3481 mLatencyTracker
3482 .trackGraphicsLatency(timeline.inputEventId,
3483 connection->inputChannel->getConnectionToken(),
3484 std::move(timeline.graphicsTimeline));
3485 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003486 }
3487 gotOne = true;
3488 }
3489 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003490 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003491 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003492 return 1;
3493 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494 }
3495
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003496 notify = status != DEAD_OBJECT || !connection->monitor;
3497 if (notify) {
3498 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3499 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3500 status);
3501 }
3502 } else {
3503 // Monitor channels are never explicitly unregistered.
3504 // We do it automatically when the remote endpoint is closed so don't warn about them.
3505 const bool stillHaveWindowHandle =
3506 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3507 notify = !connection->monitor && stillHaveWindowHandle;
3508 if (notify) {
3509 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3510 connection->getInputChannelName().c_str(), events);
3511 }
3512 }
3513
3514 // Remove the channel.
3515 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3516 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003517}
3518
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003519void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003521 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003522 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003523 }
3524}
3525
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003526void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003527 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003528 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3529 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3530}
3531
3532void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3533 const CancelationOptions& options,
3534 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3535 for (const auto& it : monitorsByDisplay) {
3536 const std::vector<Monitor>& monitors = it.second;
3537 for (const Monitor& monitor : monitors) {
3538 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003539 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003540 }
3541}
3542
Michael Wrightd02c5b62014-02-10 15:10:22 -08003543void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003544 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003545 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003546 if (connection == nullptr) {
3547 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003548 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003549
3550 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003551}
3552
3553void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3554 const sp<Connection>& connection, const CancelationOptions& options) {
3555 if (connection->status == Connection::STATUS_BROKEN) {
3556 return;
3557 }
3558
3559 nsecs_t currentTime = now();
3560
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003561 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003562 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003563
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003564 if (cancelationEvents.empty()) {
3565 return;
3566 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003567 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3568 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3569 "with reality: %s, mode=%d.",
3570 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3571 options.mode);
3572 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003573
Arthur Hungb3307ee2021-10-14 10:57:37 +00003574 std::string reason = std::string("reason=").append(options.reason);
3575 android_log_event_list(LOGTAG_INPUT_CANCEL)
3576 << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3577
Svet Ganov5d3bc372020-01-26 23:11:07 -08003578 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