blob: c86e0928bd8be9f95749625c36bb761ce3fe3e9c [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>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080030#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070031#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000032#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070033#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010034#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070035#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080036
Michael Wright44753b12020-07-08 13:48:11 +010037#include <cerrno>
38#include <cinttypes>
39#include <climits>
40#include <cstddef>
41#include <ctime>
42#include <queue>
43#include <sstream>
44
45#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070046#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010047
Michael Wrightd02c5b62014-02-10 15:10:22 -080048#define INDENT " "
49#define INDENT2 " "
50#define INDENT3 " "
51#define INDENT4 " "
52
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080053using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000054using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080055using android::base::StringPrintf;
chaviw98318de2021-05-19 16:45:23 -050056using android::gui::FocusRequest;
57using android::gui::TouchOcclusionMode;
58using android::gui::WindowInfo;
59using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080060using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100061using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080062using android::os::InputEventInjectionResult;
63using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100064using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080065
Garfield Tane84e6f92019-08-29 17:28:41 -070066namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080067
Prabir Pradhancef936d2021-07-21 16:17:52 +000068namespace {
69
Prabir Pradhan61a5d242021-07-26 16:41:09 +000070// Log detailed debug messages about each inbound event notification to the dispatcher.
71constexpr bool DEBUG_INBOUND_EVENT_DETAILS = false;
72
73// Log detailed debug messages about each outbound event processed by the dispatcher.
74constexpr bool DEBUG_OUTBOUND_EVENT_DETAILS = false;
75
76// Log debug messages about the dispatch cycle.
77constexpr bool DEBUG_DISPATCH_CYCLE = false;
78
79// Log debug messages about channel creation
80constexpr bool DEBUG_CHANNEL_CREATION = false;
81
82// Log debug messages about input event injection.
83constexpr bool DEBUG_INJECTION = false;
84
85// Log debug messages about input focus tracking.
86constexpr bool DEBUG_FOCUS = false;
87
88// Log debug messages about touch occlusion
89// STOPSHIP(b/169067926): Set to false
90constexpr bool DEBUG_TOUCH_OCCLUSION = true;
91
92// Log debug messages about the app switch latency optimization.
93constexpr bool DEBUG_APP_SWITCH = false;
94
95// Log debug messages about hover events.
96constexpr bool DEBUG_HOVER = false;
97
Prabir Pradhancef936d2021-07-21 16:17:52 +000098// Temporarily releases a held mutex for the lifetime of the instance.
99// Named to match std::scoped_lock
100class scoped_unlock {
101public:
102 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
103 ~scoped_unlock() { mMutex.lock(); }
104
105private:
106 std::mutex& mMutex;
107};
108
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700109// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
110// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000111bool isPerWindowInputRotationEnabled() {
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700112 static const bool PER_WINDOW_INPUT_ROTATION =
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -0700113 sysprop::InputFlingerProperties::per_window_input_rotation().value_or(false);
114
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700115 return PER_WINDOW_INPUT_ROTATION;
116}
117
Michael Wrightd02c5b62014-02-10 15:10:22 -0800118// Default input dispatching timeout if there is no focused application or paused window
119// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800120const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
121 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
122 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800123
124// Amount of time to allow for all pending events to be processed when an app switch
125// key is on the way. This is used to preempt input dispatch and drop input events
126// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000127constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800128
129// Amount of time to allow for an event to be dispatched (measured since its eventTime)
130// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000131constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800132
Michael Wrightd02c5b62014-02-10 15:10:22 -0800133// 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 +0000134constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
135
136// Log a warning when an interception call takes longer than this to process.
137constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800138
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700139// Additional key latency in case a connection is still processing some motion events.
140// This will help with the case when a user touched a button that opens a new window,
141// and gives us the chance to dispatch the key to this new window.
142constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
143
Michael Wrightd02c5b62014-02-10 15:10:22 -0800144// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000145constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
146
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000147// Event log tags. See EventLogTags.logtags for reference
148constexpr int LOGTAG_INPUT_INTERACTION = 62000;
149constexpr int LOGTAG_INPUT_FOCUS = 62001;
150
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000151inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800152 return systemTime(SYSTEM_TIME_MONOTONIC);
153}
154
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000155inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800156 return value ? "true" : "false";
157}
158
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000159inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000160 if (binder == nullptr) {
161 return "<null>";
162 }
163 return StringPrintf("%p", binder.get());
164}
165
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000166inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700167 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
168 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800169}
170
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000171bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800172 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700173 case AKEY_EVENT_ACTION_DOWN:
174 case AKEY_EVENT_ACTION_UP:
175 return true;
176 default:
177 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800178 }
179}
180
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000181bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700182 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800183 ALOGE("Key event has invalid action code 0x%x", action);
184 return false;
185 }
186 return true;
187}
188
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000189bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800190 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700191 case AMOTION_EVENT_ACTION_DOWN:
192 case AMOTION_EVENT_ACTION_UP:
193 case AMOTION_EVENT_ACTION_CANCEL:
194 case AMOTION_EVENT_ACTION_MOVE:
195 case AMOTION_EVENT_ACTION_OUTSIDE:
196 case AMOTION_EVENT_ACTION_HOVER_ENTER:
197 case AMOTION_EVENT_ACTION_HOVER_MOVE:
198 case AMOTION_EVENT_ACTION_HOVER_EXIT:
199 case AMOTION_EVENT_ACTION_SCROLL:
200 return true;
201 case AMOTION_EVENT_ACTION_POINTER_DOWN:
202 case AMOTION_EVENT_ACTION_POINTER_UP: {
203 int32_t index = getMotionEventActionPointerIndex(action);
204 return index >= 0 && index < pointerCount;
205 }
206 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
207 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
208 return actionButton != 0;
209 default:
210 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 }
212}
213
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000214int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500215 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
216}
217
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000218bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
219 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700220 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800221 ALOGE("Motion event has invalid action code 0x%x", action);
222 return false;
223 }
224 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000225 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700226 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800227 return false;
228 }
229 BitSet32 pointerIdBits;
230 for (size_t i = 0; i < pointerCount; i++) {
231 int32_t id = pointerProperties[i].id;
232 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700233 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
234 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800235 return false;
236 }
237 if (pointerIdBits.hasBit(id)) {
238 ALOGE("Motion event has duplicate pointer id %d", id);
239 return false;
240 }
241 pointerIdBits.markBit(id);
242 }
243 return true;
244}
245
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000246std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800247 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000248 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800249 }
250
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000251 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800252 bool first = true;
253 Region::const_iterator cur = region.begin();
254 Region::const_iterator const tail = region.end();
255 while (cur != tail) {
256 if (first) {
257 first = false;
258 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800259 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800260 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800261 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 cur++;
263 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000264 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800265}
266
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000267std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500268 constexpr size_t maxEntries = 50; // max events to print
269 constexpr size_t skipBegin = maxEntries / 2;
270 const size_t skipEnd = queue.size() - maxEntries / 2;
271 // skip from maxEntries / 2 ... size() - maxEntries/2
272 // only print from 0 .. skipBegin and then from skipEnd .. size()
273
274 std::string dump;
275 for (size_t i = 0; i < queue.size(); i++) {
276 const DispatchEntry& entry = *queue[i];
277 if (i >= skipBegin && i < skipEnd) {
278 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
279 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
280 continue;
281 }
282 dump.append(INDENT4);
283 dump += entry.eventEntry->getDescription();
284 dump += StringPrintf(", seq=%" PRIu32
285 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
286 entry.seq, entry.targetFlags, entry.resolvedAction,
287 ns2ms(currentTime - entry.eventEntry->eventTime));
288 if (entry.deliveryTime != 0) {
289 // This entry was delivered, so add information on how long we've been waiting
290 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
291 }
292 dump.append("\n");
293 }
294 return dump;
295}
296
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700297/**
298 * Find the entry in std::unordered_map by key, and return it.
299 * If the entry is not found, return a default constructed entry.
300 *
301 * Useful when the entries are vectors, since an empty vector will be returned
302 * if the entry is not found.
303 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
304 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700305template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000306V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700307 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700308 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800309}
310
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000311bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700312 if (first == second) {
313 return true;
314 }
315
316 if (first == nullptr || second == nullptr) {
317 return false;
318 }
319
320 return first->getToken() == second->getToken();
321}
322
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000323bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000324 if (first == nullptr || second == nullptr) {
325 return false;
326 }
327 return first->applicationInfo.token != nullptr &&
328 first->applicationInfo.token == second->applicationInfo.token;
329}
330
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000331bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800332 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
333}
334
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000335std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
336 std::shared_ptr<EventEntry> eventEntry,
337 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900338 if (eventEntry->type == EventEntry::Type::MOTION) {
339 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhan664834b2021-05-20 16:00:42 -0700340 if ((motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) ||
341 (motionEntry.source & AINPUT_SOURCE_CLASS_POSITION)) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900342 const ui::Transform identityTransform;
Prabir Pradhan664834b2021-05-20 16:00:42 -0700343 // Use identity transform for joystick and position-based (touchpad) events because they
344 // don't depend on the window transform.
yunho.shinf4a80b82020-11-16 21:13:57 +0900345 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700346 1.0f /*globalScaleFactor*/,
Evan Rosky09576692021-07-01 12:22:09 -0700347 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700348 inputTarget.displaySize);
yunho.shinf4a80b82020-11-16 21:13:57 +0900349 }
350 }
351
chaviw1ff3d1e2020-07-01 15:53:47 -0700352 if (inputTarget.useDefaultPointerTransform()) {
353 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700354 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700355 inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700356 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700357 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000358 }
359
360 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
361 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
362
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700363 std::vector<PointerCoords> pointerCoords;
364 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000365
366 // Use the first pointer information to normalize all other pointers. This could be any pointer
367 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700368 // uses the transform for the normalized pointer.
369 const ui::Transform& firstPointerTransform =
370 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
371 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000372
373 // Iterate through all pointers in the event to normalize against the first.
374 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
375 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
376 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700377 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000378
379 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700380 // First, apply the current pointer's transform to update the coordinates into
381 // window space.
382 pointerCoords[pointerIndex].transform(currTransform);
383 // Next, apply the inverse transform of the normalized coordinates so the
384 // current coordinates are transformed into the normalized coordinate space.
385 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000386 }
387
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700388 std::unique_ptr<MotionEntry> combinedMotionEntry =
389 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
390 motionEntry.deviceId, motionEntry.source,
391 motionEntry.displayId, motionEntry.policyFlags,
392 motionEntry.action, motionEntry.actionButton,
393 motionEntry.flags, motionEntry.metaState,
394 motionEntry.buttonState, motionEntry.classification,
395 motionEntry.edgeFlags, motionEntry.xPrecision,
396 motionEntry.yPrecision, motionEntry.xCursorPosition,
397 motionEntry.yCursorPosition, motionEntry.downTime,
398 motionEntry.pointerCount, motionEntry.pointerProperties,
399 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000400
401 if (motionEntry.injectionState) {
402 combinedMotionEntry->injectionState = motionEntry.injectionState;
403 combinedMotionEntry->injectionState->refCount += 1;
404 }
405
406 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700407 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Evan Rosky84f07f02021-04-16 10:42:42 -0700408 firstPointerTransform, inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700409 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700410 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000411 return dispatchEntry;
412}
413
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000414void addGestureMonitors(const std::vector<Monitor>& monitors,
415 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
416 float yOffset = 0) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700417 if (monitors.empty()) {
418 return;
419 }
420 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
421 for (const Monitor& monitor : monitors) {
422 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
423 }
424}
425
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000426status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
427 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700428 std::unique_ptr<InputChannel> uniqueServerChannel;
429 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
430
431 serverChannel = std::move(uniqueServerChannel);
432 return result;
433}
434
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500435template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000436bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500437 if (lhs == nullptr && rhs == nullptr) {
438 return true;
439 }
440 if (lhs == nullptr || rhs == nullptr) {
441 return false;
442 }
443 return *lhs == *rhs;
444}
445
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000446sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000447 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
448 if (service == nullptr) {
449 ALOGE("Failed to link to compat service");
450 return nullptr;
451 }
452 return interface_cast<IPlatformCompatNative>(service);
453}
454
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000455KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000456 KeyEvent event;
457 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
458 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
459 entry.repeatCount, entry.downTime, entry.eventTime);
460 return event;
461}
462
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000463std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000464 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
465 const sp<IBinder>& token) {
466 for (const auto& it : monitorsByDisplay) {
467 const std::vector<Monitor>& monitors = it.second;
468 for (const Monitor& monitor : monitors) {
469 if (monitor.inputChannel->getConnectionToken() == token) {
470 return monitor.pid;
471 }
472 }
473 }
474 return std::nullopt;
475}
476
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000477bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000478 // Do not keep track of gesture monitors. They receive every event and would disproportionately
479 // affect the statistics.
480 if (connection.monitor) {
481 return false;
482 }
483 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
484 if (!connection.responsive) {
485 return false;
486 }
487 return true;
488}
489
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000490bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000491 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
492 const int32_t& inputEventId = eventEntry.id;
493 if (inputEventId != dispatchEntry.resolvedEventId) {
494 // Event was transmuted
495 return false;
496 }
497 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
498 return false;
499 }
500 // Only track latency for events that originated from hardware
501 if (eventEntry.isSynthesized()) {
502 return false;
503 }
504 const EventEntry::Type& inputEventEntryType = eventEntry.type;
505 if (inputEventEntryType == EventEntry::Type::KEY) {
506 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
507 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
508 return false;
509 }
510 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
511 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
512 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
513 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
514 return false;
515 }
516 } else {
517 // Not a key or a motion
518 return false;
519 }
520 if (!shouldReportMetricsForConnection(connection)) {
521 return false;
522 }
523 return true;
524}
525
Prabir Pradhancef936d2021-07-21 16:17:52 +0000526/**
527 * Connection is responsive if it has no events in the waitQueue that are older than the
528 * current time.
529 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000530bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000531 const nsecs_t currentTime = now();
532 for (const DispatchEntry* entry : connection.waitQueue) {
533 if (entry->timeoutTime < currentTime) {
534 return false;
535 }
536 }
537 return true;
538}
539
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000540} // namespace
541
Michael Wrightd02c5b62014-02-10 15:10:22 -0800542// --- InputDispatcher ---
543
Garfield Tan00f511d2019-06-12 16:55:40 -0700544InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
545 : mPolicy(policy),
546 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700547 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800548 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700549 mAppSwitchSawKeyDown(false),
550 mAppSwitchDueTime(LONG_LONG_MAX),
551 mNextUnblockedEvent(nullptr),
552 mDispatchEnabled(false),
553 mDispatchFrozen(false),
554 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800555 // mInTouchMode will be initialized by the WindowManager to the default device config.
556 // To avoid leaking stack in case that call never comes, and for tests,
557 // initialize it here anyways.
558 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100559 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000560 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800561 mFocusedWindowRequestedPointerCapture(false),
562 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000563 mLatencyAggregator(),
564 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000565 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800566 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800567 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568
Yi Kong9b14ac62018-07-17 13:48:38 -0700569 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800570
571 policy->getDispatcherConfiguration(&mConfig);
572}
573
574InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000575 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800576
Prabir Pradhancef936d2021-07-21 16:17:52 +0000577 resetKeyRepeatLocked();
578 releasePendingEventLocked();
579 drainInboundQueueLocked();
580 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800581
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000582 while (!mConnectionsByToken.empty()) {
583 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000584 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
585 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800586 }
587}
588
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700589status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700590 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700591 return ALREADY_EXISTS;
592 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700593 mThread = std::make_unique<InputThread>(
594 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
595 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700596}
597
598status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700599 if (mThread && mThread->isCallingThread()) {
600 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700601 return INVALID_OPERATION;
602 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700603 mThread.reset();
604 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700605}
606
Michael Wrightd02c5b62014-02-10 15:10:22 -0800607void InputDispatcher::dispatchOnce() {
608 nsecs_t nextWakeupTime = LONG_LONG_MAX;
609 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800610 std::scoped_lock _l(mLock);
611 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800612
613 // Run a dispatch loop if there are no pending commands.
614 // The dispatch loop might enqueue commands to run afterwards.
615 if (!haveCommandsLocked()) {
616 dispatchOnceInnerLocked(&nextWakeupTime);
617 }
618
619 // Run all pending commands if there are any.
620 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000621 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800622 nextWakeupTime = LONG_LONG_MIN;
623 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800624
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700625 // If we are still waiting for ack on some events,
626 // we might have to wake up earlier to check if an app is anr'ing.
627 const nsecs_t nextAnrCheck = processAnrsLocked();
628 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
629
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800630 // We are about to enter an infinitely long sleep, because we have no commands or
631 // pending or queued events
632 if (nextWakeupTime == LONG_LONG_MAX) {
633 mDispatcherEnteredIdle.notify_all();
634 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800635 } // release lock
636
637 // Wait for callback or timeout or wake. (make sure we round up, not down)
638 nsecs_t currentTime = now();
639 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
640 mLooper->pollOnce(timeoutMillis);
641}
642
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700643/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500644 * Raise ANR if there is no focused window.
645 * Before the ANR is raised, do a final state check:
646 * 1. The currently focused application must be the same one we are waiting for.
647 * 2. Ensure we still don't have a focused window.
648 */
649void InputDispatcher::processNoFocusedWindowAnrLocked() {
650 // Check if the application that we are waiting for is still focused.
651 std::shared_ptr<InputApplicationHandle> focusedApplication =
652 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
653 if (focusedApplication == nullptr ||
654 focusedApplication->getApplicationToken() !=
655 mAwaitedFocusedApplication->getApplicationToken()) {
656 // Unexpected because we should have reset the ANR timer when focused application changed
657 ALOGE("Waited for a focused window, but focused application has already changed to %s",
658 focusedApplication->getName().c_str());
659 return; // The focused application has changed.
660 }
661
chaviw98318de2021-05-19 16:45:23 -0500662 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500663 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
664 if (focusedWindowHandle != nullptr) {
665 return; // We now have a focused window. No need for ANR.
666 }
667 onAnrLocked(mAwaitedFocusedApplication);
668}
669
670/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700671 * Check if any of the connections' wait queues have events that are too old.
672 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
673 * Return the time at which we should wake up next.
674 */
675nsecs_t InputDispatcher::processAnrsLocked() {
676 const nsecs_t currentTime = now();
677 nsecs_t nextAnrCheck = LONG_LONG_MAX;
678 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
679 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
680 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500681 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700682 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500683 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700684 return LONG_LONG_MIN;
685 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500686 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700687 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
688 }
689 }
690
691 // Check if any connection ANRs are due
692 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
693 if (currentTime < nextAnrCheck) { // most likely scenario
694 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
695 }
696
697 // If we reached here, we have an unresponsive connection.
698 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
699 if (connection == nullptr) {
700 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
701 return nextAnrCheck;
702 }
703 connection->responsive = false;
704 // Stop waking up for this unresponsive connection
705 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000706 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700707 return LONG_LONG_MIN;
708}
709
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500710std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500711 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700712 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500713 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700714 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500715 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700716}
717
Michael Wrightd02c5b62014-02-10 15:10:22 -0800718void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
719 nsecs_t currentTime = now();
720
Jeff Browndc5992e2014-04-11 01:27:26 -0700721 // Reset the key repeat timer whenever normal dispatch is suspended while the
722 // device is in a non-interactive state. This is to ensure that we abort a key
723 // repeat if the device is just coming out of sleep.
724 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800725 resetKeyRepeatLocked();
726 }
727
728 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
729 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100730 if (DEBUG_FOCUS) {
731 ALOGD("Dispatch frozen. Waiting some more.");
732 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800733 return;
734 }
735
736 // Optimize latency of app switches.
737 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
738 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
739 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
740 if (mAppSwitchDueTime < *nextWakeupTime) {
741 *nextWakeupTime = mAppSwitchDueTime;
742 }
743
744 // Ready to start a new event.
745 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700746 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700747 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800748 if (isAppSwitchDue) {
749 // The inbound queue is empty so the app switch key we were waiting
750 // for will never arrive. Stop waiting for it.
751 resetPendingAppSwitchLocked(false);
752 isAppSwitchDue = false;
753 }
754
755 // Synthesize a key repeat if appropriate.
756 if (mKeyRepeatState.lastKeyEntry) {
757 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
758 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
759 } else {
760 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
761 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
762 }
763 }
764 }
765
766 // Nothing to do if there is no pending event.
767 if (!mPendingEvent) {
768 return;
769 }
770 } else {
771 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700772 mPendingEvent = mInboundQueue.front();
773 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800774 traceInboundQueueLengthLocked();
775 }
776
777 // Poke user activity for this event.
778 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700779 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800781 }
782
783 // Now we have an event to dispatch.
784 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700785 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800786 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700787 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700789 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800790 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700791 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 }
793
794 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700795 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800796 }
797
798 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700799 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700800 const ConfigurationChangedEntry& typedEntry =
801 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700802 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700803 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700804 break;
805 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800806
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700807 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700808 const DeviceResetEntry& typedEntry =
809 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700810 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700811 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700812 break;
813 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800814
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100815 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700816 std::shared_ptr<FocusEntry> typedEntry =
817 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100818 dispatchFocusLocked(currentTime, typedEntry);
819 done = true;
820 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
821 break;
822 }
823
Prabir Pradhan99987712020-11-10 18:43:05 -0800824 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
825 const auto typedEntry =
826 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
827 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
828 done = true;
829 break;
830 }
831
arthurhungb89ccb02020-12-30 16:19:01 +0800832 case EventEntry::Type::DRAG: {
833 std::shared_ptr<DragEntry> typedEntry =
834 std::static_pointer_cast<DragEntry>(mPendingEvent);
835 dispatchDragLocked(currentTime, typedEntry);
836 done = true;
837 break;
838 }
839
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700840 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700841 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700842 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700843 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700844 resetPendingAppSwitchLocked(true);
845 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700846 } else if (dropReason == DropReason::NOT_DROPPED) {
847 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700848 }
849 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700850 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700851 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700852 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700853 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
854 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700855 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700856 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700857 break;
858 }
859
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700860 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700861 std::shared_ptr<MotionEntry> motionEntry =
862 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700863 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
864 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800865 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700866 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700867 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700868 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700869 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
870 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700871 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700872 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700873 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800874 }
Chris Yef59a2f42020-10-16 12:55:26 -0700875
876 case EventEntry::Type::SENSOR: {
877 std::shared_ptr<SensorEntry> sensorEntry =
878 std::static_pointer_cast<SensorEntry>(mPendingEvent);
879 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
880 dropReason = DropReason::APP_SWITCH;
881 }
882 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
883 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
884 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
885 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
886 dropReason = DropReason::STALE;
887 }
888 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
889 done = true;
890 break;
891 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800892 }
893
894 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700895 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700896 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800897 }
Michael Wright3a981722015-06-10 15:26:13 +0100898 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800899
900 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800902 }
903}
904
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700905/**
906 * Return true if the events preceding this incoming motion event should be dropped
907 * Return false otherwise (the default behaviour)
908 */
909bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700910 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700911 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700912
913 // Optimize case where the current application is unresponsive and the user
914 // decides to touch a window in a different application.
915 // If the application takes too long to catch up then we drop all events preceding
916 // the touch into the other window.
917 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700918 int32_t displayId = motionEntry.displayId;
919 int32_t x = static_cast<int32_t>(
920 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
921 int32_t y = static_cast<int32_t>(
922 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500923 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700924 findTouchedWindowAtLocked(displayId, x, y, nullptr);
925 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700926 touchedWindowHandle->getApplicationToken() !=
927 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700928 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700929 ALOGI("Pruning input queue because user touched a different application while waiting "
930 "for %s",
931 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700932 return true;
933 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700934
935 // Alternatively, maybe there's a gesture monitor that could handle this event
Siarhei Vishniakou64452932020-11-06 17:51:32 -0600936 std::vector<TouchedMonitor> gestureMonitors = findTouchedGestureMonitorsLocked(displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700937 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
938 sp<Connection> connection =
939 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000940 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700941 // This monitor could take more input. Drop all events preceding this
942 // event, so that gesture monitor could get a chance to receive the stream
943 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
944 "responsive gesture monitor that may handle the event",
945 mAwaitedFocusedApplication->getName().c_str());
946 return true;
947 }
948 }
949 }
950
951 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
952 // yet been processed by some connections, the dispatcher will wait for these motion
953 // events to be processed before dispatching the key event. This is because these motion events
954 // may cause a new window to be launched, which the user might expect to receive focus.
955 // To prevent waiting forever for such events, just send the key to the currently focused window
956 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
957 ALOGD("Received a new pointer down event, stop waiting for events to process and "
958 "just send the pending key event to the focused window.");
959 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700960 }
961 return false;
962}
963
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700964bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700965 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700966 mInboundQueue.push_back(std::move(newEntry));
967 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800968 traceInboundQueueLengthLocked();
969
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700970 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700971 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700972 // Optimize app switch latency.
973 // If the application takes too long to catch up then we drop all events preceding
974 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700975 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700976 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700977 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700978 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700979 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700980 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000981 if (DEBUG_APP_SWITCH) {
982 ALOGD("App switch is pending!");
983 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700984 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700985 mAppSwitchSawKeyDown = false;
986 needWake = true;
987 }
988 }
989 }
990 break;
991 }
992
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700993 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700994 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
995 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700996 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800997 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700998 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800999 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001000 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001001 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1002 break;
1003 }
1004 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001005 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001006 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001007 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1008 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001009 // nothing to do
1010 break;
1011 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001012 }
1013
1014 return needWake;
1015}
1016
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001017void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001018 // Do not store sensor event in recent queue to avoid flooding the queue.
1019 if (entry->type != EventEntry::Type::SENSOR) {
1020 mRecentQueue.push_back(entry);
1021 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001022 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001023 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001024 }
1025}
1026
chaviw98318de2021-05-19 16:45:23 -05001027sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1028 int32_t y, TouchState* touchState,
1029 bool addOutsideTargets,
1030 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001031 if (addOutsideTargets && touchState == nullptr) {
1032 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001033 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001034 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001035 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1036 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001037 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001038 continue;
1039 }
chaviw98318de2021-05-19 16:45:23 -05001040 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001041 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001042 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043
1044 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001045 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1046 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1047 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001048 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1049 // Found window.
1050 return windowHandle;
1051 }
1052 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001053
chaviw98318de2021-05-19 16:45:23 -05001054 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001055 touchState->addOrUpdateWindow(windowHandle,
1056 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1057 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001058 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001059 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001060 }
1061 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001062 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001063}
1064
Garfield Tane84e6f92019-08-29 17:28:41 -07001065std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001066 int32_t displayId) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001067 std::vector<TouchedMonitor> touchedMonitors;
1068
1069 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1070 addGestureMonitors(monitors, touchedMonitors);
Michael Wright3dd60e22019-03-27 22:06:44 +00001071 return touchedMonitors;
1072}
1073
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001074void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001075 const char* reason;
1076 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001077 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001078 if (DEBUG_INBOUND_EVENT_DETAILS) {
1079 ALOGD("Dropped event because policy consumed it.");
1080 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001081 reason = "inbound event was dropped because the policy consumed it";
1082 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001083 case DropReason::DISABLED:
1084 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001085 ALOGI("Dropped event because input dispatch is disabled.");
1086 }
1087 reason = "inbound event was dropped because input dispatch is disabled";
1088 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001089 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001090 ALOGI("Dropped event because of pending overdue app switch.");
1091 reason = "inbound event was dropped because of pending overdue app switch";
1092 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001093 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001094 ALOGI("Dropped event because the current application is not responding and the user "
1095 "has started interacting with a different application.");
1096 reason = "inbound event was dropped because the current application is not responding "
1097 "and the user has started interacting with a different application";
1098 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001099 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001100 ALOGI("Dropped event because it is stale.");
1101 reason = "inbound event was dropped because it is stale";
1102 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001103 case DropReason::NO_POINTER_CAPTURE:
1104 ALOGI("Dropped event because there is no window with Pointer Capture.");
1105 reason = "inbound event was dropped because there is no window with Pointer Capture";
1106 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001107 case DropReason::NOT_DROPPED: {
1108 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001109 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001110 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001111 }
1112
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001113 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001114 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001115 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1116 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001117 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001119 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001120 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1121 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001122 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1123 synthesizeCancelationEventsForAllConnectionsLocked(options);
1124 } else {
1125 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1126 synthesizeCancelationEventsForAllConnectionsLocked(options);
1127 }
1128 break;
1129 }
Chris Yef59a2f42020-10-16 12:55:26 -07001130 case EventEntry::Type::SENSOR: {
1131 break;
1132 }
arthurhungb89ccb02020-12-30 16:19:01 +08001133 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1134 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001135 break;
1136 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001137 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001138 case EventEntry::Type::CONFIGURATION_CHANGED:
1139 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001140 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001141 break;
1142 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001143 }
1144}
1145
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001146static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001147 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1148 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001149}
1150
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001151bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1152 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1153 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1154 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155}
1156
1157bool InputDispatcher::isAppSwitchPendingLocked() {
1158 return mAppSwitchDueTime != LONG_LONG_MAX;
1159}
1160
1161void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1162 mAppSwitchDueTime = LONG_LONG_MAX;
1163
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001164 if (DEBUG_APP_SWITCH) {
1165 if (handled) {
1166 ALOGD("App switch has arrived.");
1167 } else {
1168 ALOGD("App switch was abandoned.");
1169 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001170 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001171}
1172
Michael Wrightd02c5b62014-02-10 15:10:22 -08001173bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001174 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001175}
1176
Prabir Pradhancef936d2021-07-21 16:17:52 +00001177bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001178 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179 return false;
1180 }
1181
1182 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001183 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001184 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001185 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1186 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001187 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001188 return true;
1189}
1190
Prabir Pradhancef936d2021-07-21 16:17:52 +00001191void InputDispatcher::postCommandLocked(Command&& command) {
1192 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001193}
1194
1195void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001196 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001197 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001198 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001199 releaseInboundEventLocked(entry);
1200 }
1201 traceInboundQueueLengthLocked();
1202}
1203
1204void InputDispatcher::releasePendingEventLocked() {
1205 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001206 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001207 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208 }
1209}
1210
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001211void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001212 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001213 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001214 if (DEBUG_DISPATCH_CYCLE) {
1215 ALOGD("Injected inbound event was dropped.");
1216 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001217 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001218 }
1219 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001220 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001221 }
1222 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001223}
1224
1225void InputDispatcher::resetKeyRepeatLocked() {
1226 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001227 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001228 }
1229}
1230
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001231std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1232 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001233
Michael Wright2e732952014-09-24 13:26:59 -07001234 uint32_t policyFlags = entry->policyFlags &
1235 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001236
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001237 std::shared_ptr<KeyEntry> newEntry =
1238 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1239 entry->source, entry->displayId, policyFlags, entry->action,
1240 entry->flags, entry->keyCode, entry->scanCode,
1241 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001243 newEntry->syntheticRepeat = true;
1244 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001245 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001246 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001247}
1248
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001249bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001250 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001251 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1252 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1253 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001254
1255 // Reset key repeating in case a keyboard device was added or removed or something.
1256 resetKeyRepeatLocked();
1257
1258 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001259 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1260 scoped_unlock unlock(mLock);
1261 mPolicy->notifyConfigurationChanged(eventTime);
1262 };
1263 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001264 return true;
1265}
1266
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001267bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1268 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001269 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1270 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1271 entry.deviceId);
1272 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001273
liushenxiang42232912021-05-21 20:24:09 +08001274 // Reset key repeating in case a keyboard device was disabled or enabled.
1275 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1276 resetKeyRepeatLocked();
1277 }
1278
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001279 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001280 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001281 synthesizeCancelationEventsForAllConnectionsLocked(options);
1282 return true;
1283}
1284
Vishnu Nairad321cd2020-08-20 16:40:21 -07001285void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001286 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001287 if (mPendingEvent != nullptr) {
1288 // Move the pending event to the front of the queue. This will give the chance
1289 // for the pending event to get dispatched to the newly focused window
1290 mInboundQueue.push_front(mPendingEvent);
1291 mPendingEvent = nullptr;
1292 }
1293
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001294 std::unique_ptr<FocusEntry> focusEntry =
1295 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1296 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001297
1298 // This event should go to the front of the queue, but behind all other focus events
1299 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001300 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001301 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001302 [](const std::shared_ptr<EventEntry>& event) {
1303 return event->type == EventEntry::Type::FOCUS;
1304 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001305
1306 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001307 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001308}
1309
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001310void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001311 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001312 if (channel == nullptr) {
1313 return; // Window has gone away
1314 }
1315 InputTarget target;
1316 target.inputChannel = channel;
1317 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1318 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001319 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1320 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001321 std::string reason = std::string("reason=").append(entry->reason);
1322 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001323 dispatchEventLocked(currentTime, entry, {target});
1324}
1325
Prabir Pradhan99987712020-11-10 18:43:05 -08001326void InputDispatcher::dispatchPointerCaptureChangedLocked(
1327 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1328 DropReason& dropReason) {
1329 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan167e6d92021-02-04 16:18:17 -08001330 if (entry->pointerCaptureEnabled && haveWindowWithPointerCapture) {
1331 LOG_ALWAYS_FATAL("Pointer Capture has already been enabled for the window.");
1332 }
1333 if (!entry->pointerCaptureEnabled && !haveWindowWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001334 // Pointer capture was already forcefully disabled because of focus change.
1335 dropReason = DropReason::NOT_DROPPED;
1336 return;
1337 }
1338
1339 // Set drop reason for early returns
1340 dropReason = DropReason::NO_POINTER_CAPTURE;
1341
1342 sp<IBinder> token;
1343 if (entry->pointerCaptureEnabled) {
1344 // Enable Pointer Capture
1345 if (!mFocusedWindowRequestedPointerCapture) {
1346 // This can happen if a window requests capture and immediately releases capture.
1347 ALOGW("No window requested Pointer Capture.");
1348 return;
1349 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001350 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001351 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1352 mWindowTokenWithPointerCapture = token;
1353 } else {
1354 // Disable Pointer Capture
1355 token = mWindowTokenWithPointerCapture;
1356 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001357 if (mFocusedWindowRequestedPointerCapture) {
1358 mFocusedWindowRequestedPointerCapture = false;
1359 setPointerCaptureLocked(false);
1360 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001361 }
1362
1363 auto channel = getInputChannelLocked(token);
1364 if (channel == nullptr) {
1365 // Window has gone away, clean up Pointer Capture state.
1366 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001367 if (mFocusedWindowRequestedPointerCapture) {
1368 mFocusedWindowRequestedPointerCapture = false;
1369 setPointerCaptureLocked(false);
1370 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001371 return;
1372 }
1373 InputTarget target;
1374 target.inputChannel = channel;
1375 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1376 entry->dispatchInProgress = true;
1377 dispatchEventLocked(currentTime, entry, {target});
1378
1379 dropReason = DropReason::NOT_DROPPED;
1380}
1381
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001382bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001383 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001384 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001385 if (!entry->dispatchInProgress) {
1386 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1387 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1388 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1389 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001390 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001391 // We have seen two identical key downs in a row which indicates that the device
1392 // driver is automatically generating key repeats itself. We take note of the
1393 // repeat here, but we disable our own next key repeat timer since it is clear that
1394 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001395 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1396 // Make sure we don't get key down from a different device. If a different
1397 // device Id has same key pressed down, the new device Id will replace the
1398 // current one to hold the key repeat with repeat count reset.
1399 // In the future when got a KEY_UP on the device id, drop it and do not
1400 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001401 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1402 resetKeyRepeatLocked();
1403 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1404 } else {
1405 // Not a repeat. Save key down state in case we do see a repeat later.
1406 resetKeyRepeatLocked();
1407 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1408 }
1409 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001410 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1411 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001412 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001413 if (DEBUG_INBOUND_EVENT_DETAILS) {
1414 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1415 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001416 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001417 resetKeyRepeatLocked();
1418 }
1419
1420 if (entry->repeatCount == 1) {
1421 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1422 } else {
1423 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1424 }
1425
1426 entry->dispatchInProgress = true;
1427
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001428 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001429 }
1430
1431 // Handle case where the policy asked us to try again later last time.
1432 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1433 if (currentTime < entry->interceptKeyWakeupTime) {
1434 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1435 *nextWakeupTime = entry->interceptKeyWakeupTime;
1436 }
1437 return false; // wait until next wakeup
1438 }
1439 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1440 entry->interceptKeyWakeupTime = 0;
1441 }
1442
1443 // Give the policy a chance to intercept the key.
1444 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1445 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001446 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001447 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001448
1449 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1450 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1451 };
1452 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001453 return false; // wait for the command to run
1454 } else {
1455 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1456 }
1457 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001458 if (*dropReason == DropReason::NOT_DROPPED) {
1459 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001460 }
1461 }
1462
1463 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001464 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001465 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001466 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1467 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001468 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001469 return true;
1470 }
1471
1472 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001473 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001474 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001475 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001476 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 return false;
1478 }
1479
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001480 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001481 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001482 return true;
1483 }
1484
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001485 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001486 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001487
1488 // Dispatch the key.
1489 dispatchEventLocked(currentTime, entry, inputTargets);
1490 return true;
1491}
1492
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001493void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001494 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1495 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1496 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1497 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1498 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1499 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1500 entry.metaState, entry.repeatCount, entry.downTime);
1501 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502}
1503
Prabir Pradhancef936d2021-07-21 16:17:52 +00001504void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1505 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001506 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001507 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1508 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1509 "source=0x%x, sensorType=%s",
1510 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
1511 NamedEnum::string(entry->sensorType).c_str());
1512 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001513 auto command = [this, entry]() REQUIRES(mLock) {
1514 scoped_unlock unlock(mLock);
1515
1516 if (entry->accuracyChanged) {
1517 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1518 }
1519 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1520 entry->hwTimestamp, entry->values);
1521 };
1522 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001523}
1524
1525bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001526 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1527 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1528 NamedEnum::string(sensorType).c_str());
1529 }
Chris Yef59a2f42020-10-16 12:55:26 -07001530 { // acquire lock
1531 std::scoped_lock _l(mLock);
1532
1533 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1534 std::shared_ptr<EventEntry> entry = *it;
1535 if (entry->type == EventEntry::Type::SENSOR) {
1536 it = mInboundQueue.erase(it);
1537 releaseInboundEventLocked(entry);
1538 }
1539 }
1540 }
1541 return true;
1542}
1543
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001544bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001545 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001546 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001547 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001548 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001549 entry->dispatchInProgress = true;
1550
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001551 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552 }
1553
1554 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001555 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001556 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001557 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1558 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001559 return true;
1560 }
1561
1562 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1563
1564 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001565 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001566
1567 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001568 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001569 if (isPointerEvent) {
1570 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001571 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001572 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001573 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001574 } else {
1575 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001576 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001577 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001578 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001579 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001580 return false;
1581 }
1582
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001583 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001584 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001585 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1586 return true;
1587 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001588 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001589 CancelationOptions::Mode mode(isPointerEvent
1590 ? CancelationOptions::CANCEL_POINTER_EVENTS
1591 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1592 CancelationOptions options(mode, "input event injection failed");
1593 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001594 return true;
1595 }
1596
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001597 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001598 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001599
1600 // Dispatch the motion.
1601 if (conflictingPointerActions) {
1602 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001603 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001604 synthesizeCancelationEventsForAllConnectionsLocked(options);
1605 }
1606 dispatchEventLocked(currentTime, entry, inputTargets);
1607 return true;
1608}
1609
chaviw98318de2021-05-19 16:45:23 -05001610void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001611 bool isExiting, const MotionEntry& motionEntry) {
1612 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1613 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1614 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1615 PointerCoords pointerCoords;
1616 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1617 pointerCoords.transform(windowHandle->getInfo()->transform);
1618
1619 std::unique_ptr<DragEntry> dragEntry =
1620 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1621 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1622 pointerCoords.getY());
1623
1624 enqueueInboundEventLocked(std::move(dragEntry));
1625}
1626
1627void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1628 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1629 if (channel == nullptr) {
1630 return; // Window has gone away
1631 }
1632 InputTarget target;
1633 target.inputChannel = channel;
1634 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1635 entry->dispatchInProgress = true;
1636 dispatchEventLocked(currentTime, entry, {target});
1637}
1638
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001639void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001640 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1641 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1642 ", policyFlags=0x%x, "
1643 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1644 "metaState=0x%x, buttonState=0x%x,"
1645 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1646 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1647 entry.policyFlags, entry.action, entry.actionButton, entry.flags, entry.metaState,
1648 entry.buttonState, entry.edgeFlags, entry.xPrecision, entry.yPrecision,
1649 entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001650
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001651 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1652 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1653 "x=%f, y=%f, pressure=%f, size=%f, "
1654 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1655 "orientation=%f",
1656 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1657 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1658 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1659 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1660 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1661 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1662 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1663 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1664 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1665 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1666 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001667 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001668}
1669
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001670void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1671 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001672 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001673 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001674 if (DEBUG_DISPATCH_CYCLE) {
1675 ALOGD("dispatchEventToCurrentInputTargets");
1676 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001677
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001678 updateInteractionTokensLocked(*eventEntry, inputTargets);
1679
Michael Wrightd02c5b62014-02-10 15:10:22 -08001680 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1681
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001682 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001683
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001684 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001685 sp<Connection> connection =
1686 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001687 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001688 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001690 if (DEBUG_FOCUS) {
1691 ALOGD("Dropping event delivery to target with channel '%s' because it "
1692 "is no longer registered with the input dispatcher.",
1693 inputTarget.inputChannel->getName().c_str());
1694 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001695 }
1696 }
1697}
1698
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001699void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1700 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1701 // If the policy decides to close the app, we will get a channel removal event via
1702 // unregisterInputChannel, and will clean up the connection that way. We are already not
1703 // sending new pointers to the connection when it blocked, but focused events will continue to
1704 // pile up.
1705 ALOGW("Canceling events for %s because it is unresponsive",
1706 connection->inputChannel->getName().c_str());
1707 if (connection->status == Connection::STATUS_NORMAL) {
1708 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1709 "application not responding");
1710 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001711 }
1712}
1713
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001714void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001715 if (DEBUG_FOCUS) {
1716 ALOGD("Resetting ANR timeouts.");
1717 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001718
1719 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001720 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001721 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001722}
1723
Tiger Huang721e26f2018-07-24 22:26:19 +08001724/**
1725 * Get the display id that the given event should go to. If this event specifies a valid display id,
1726 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1727 * Focused display is the display that the user most recently interacted with.
1728 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001729int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001730 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001731 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001732 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001733 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1734 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001735 break;
1736 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001737 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001738 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1739 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001740 break;
1741 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001742 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001743 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001744 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001745 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001746 case EventEntry::Type::SENSOR:
1747 case EventEntry::Type::DRAG: {
Chris Yef59a2f42020-10-16 12:55:26 -07001748 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001749 return ADISPLAY_ID_NONE;
1750 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001751 }
1752 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1753}
1754
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001755bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1756 const char* focusedWindowName) {
1757 if (mAnrTracker.empty()) {
1758 // already processed all events that we waited for
1759 mKeyIsWaitingForEventsTimeout = std::nullopt;
1760 return false;
1761 }
1762
1763 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1764 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001765 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001766 mKeyIsWaitingForEventsTimeout = currentTime +
1767 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1768 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001769 return true;
1770 }
1771
1772 // We still have pending events, and already started the timer
1773 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1774 return true; // Still waiting
1775 }
1776
1777 // Waited too long, and some connection still hasn't processed all motions
1778 // Just send the key to the focused window
1779 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1780 focusedWindowName);
1781 mKeyIsWaitingForEventsTimeout = std::nullopt;
1782 return false;
1783}
1784
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001785InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1786 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1787 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001788 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001789
Tiger Huang721e26f2018-07-24 22:26:19 +08001790 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001791 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001792 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001793 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1794
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795 // If there is no currently focused window and no focused application
1796 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001797 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1798 ALOGI("Dropping %s event because there is no focused window or focused application in "
1799 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001800 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001801 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001802 }
1803
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001804 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1805 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1806 // start interacting with another application via touch (app switch). This code can be removed
1807 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1808 // an app is expected to have a focused window.
1809 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1810 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1811 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001812 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1813 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1814 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001815 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001816 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001817 ALOGW("Waiting because no window has focus but %s may eventually add a "
1818 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001819 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001820 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001821 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001822 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1823 // Already raised ANR. Drop the event
1824 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001825 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001826 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001827 } else {
1828 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001829 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001830 }
1831 }
1832
1833 // we have a valid, non-null focused window
1834 resetNoFocusedWindowTimeoutLocked();
1835
Michael Wrightd02c5b62014-02-10 15:10:22 -08001836 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001837 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001838 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001839 }
1840
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001841 if (focusedWindowHandle->getInfo()->paused) {
1842 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001843 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001844 }
1845
1846 // If the event is a key event, then we must wait for all previous events to
1847 // complete before delivering it because previous events may have the
1848 // side-effect of transferring focus to a different window and we want to
1849 // ensure that the following keys are sent to the new window.
1850 //
1851 // Suppose the user touches a button in a window then immediately presses "A".
1852 // If the button causes a pop-up window to appear then we want to ensure that
1853 // the "A" key is delivered to the new pop-up window. This is because users
1854 // often anticipate pending UI changes when typing on a keyboard.
1855 // To obtain this behavior, we must serialize key events with respect to all
1856 // prior input events.
1857 if (entry.type == EventEntry::Type::KEY) {
1858 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1859 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001860 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001861 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862 }
1863
1864 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001865 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001866 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1867 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001868
1869 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001870 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001871}
1872
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001873/**
1874 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1875 * that are currently unresponsive.
1876 */
1877std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1878 const std::vector<TouchedMonitor>& monitors) const {
1879 std::vector<TouchedMonitor> responsiveMonitors;
1880 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1881 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1882 sp<Connection> connection = getConnectionLocked(
1883 monitor.monitor.inputChannel->getConnectionToken());
1884 if (connection == nullptr) {
1885 ALOGE("Could not find connection for monitor %s",
1886 monitor.monitor.inputChannel->getName().c_str());
1887 return false;
1888 }
1889 if (!connection->responsive) {
1890 ALOGW("Unresponsive monitor %s will not get the new gesture",
1891 connection->inputChannel->getName().c_str());
1892 return false;
1893 }
1894 return true;
1895 });
1896 return responsiveMonitors;
1897}
1898
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001899InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1900 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1901 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001902 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001903 enum InjectionPermission {
1904 INJECTION_PERMISSION_UNKNOWN,
1905 INJECTION_PERMISSION_GRANTED,
1906 INJECTION_PERMISSION_DENIED
1907 };
1908
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 // For security reasons, we defer updating the touch state until we are sure that
1910 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001911 int32_t displayId = entry.displayId;
1912 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001913 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1914
1915 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001916 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001917 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001918 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1919 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001921 // Copy current touch state into tempTouchState.
1922 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1923 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001924 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001925 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001926 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1927 mTouchStatesByDisplay.find(displayId);
1928 if (oldStateIt != mTouchStatesByDisplay.end()) {
1929 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001930 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001931 }
1932
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001933 bool isSplit = tempTouchState.split;
1934 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1935 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1936 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001937 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1938 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1939 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1940 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1941 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001942 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001943 bool wrongDevice = false;
1944 if (newGesture) {
1945 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001946 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001947 ALOGI("Dropping event because a pointer for a different device is already down "
1948 "in display %" PRId32,
1949 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001950 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001951 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001952 switchedDevice = false;
1953 wrongDevice = true;
1954 goto Failed;
1955 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001956 tempTouchState.reset();
1957 tempTouchState.down = down;
1958 tempTouchState.deviceId = entry.deviceId;
1959 tempTouchState.source = entry.source;
1960 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001961 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001962 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001963 ALOGI("Dropping move event because a pointer for a different device is already active "
1964 "in display %" PRId32,
1965 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001966 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001967 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001968 switchedDevice = false;
1969 wrongDevice = true;
1970 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001971 }
1972
1973 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1974 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1975
Garfield Tan00f511d2019-06-12 16:55:40 -07001976 int32_t x;
1977 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001979 // Always dispatch mouse events to cursor position.
1980 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001981 x = int32_t(entry.xCursorPosition);
1982 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001983 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001984 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1985 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001986 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001987 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001988 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1989 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001990
1991 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001992 ? findTouchedGestureMonitorsLocked(displayId)
Michael Wright3dd60e22019-03-27 22:06:44 +00001993 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001994
Michael Wrightd02c5b62014-02-10 15:10:22 -08001995 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001996 if (newTouchedWindowHandle != nullptr &&
1997 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001998 // New window supports splitting, but we should never split mouse events.
1999 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002000 } else if (isSplit) {
2001 // New window does not support splitting but we have already split events.
2002 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002003 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002004 }
2005
2006 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002007 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002008 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002009 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002010 }
2011
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002012 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2013 ALOGI("Not sending touch event to %s because it is paused",
2014 newTouchedWindowHandle->getName().c_str());
2015 newTouchedWindowHandle = nullptr;
2016 }
2017
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002018 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002019 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002020 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2021 if (!isResponsive) {
2022 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002023 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2024 newTouchedWindowHandle = nullptr;
2025 }
2026 }
2027
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002028 // Drop events that can't be trusted due to occlusion
2029 if (newTouchedWindowHandle != nullptr &&
2030 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2031 TouchOcclusionInfo occlusionInfo =
2032 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002033 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002034 if (DEBUG_TOUCH_OCCLUSION) {
2035 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2036 for (const auto& log : occlusionInfo.debugInfo) {
2037 ALOGD("%s", log.c_str());
2038 }
2039 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002040 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002041 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2042 ALOGW("Dropping untrusted touch event due to %s/%d",
2043 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2044 newTouchedWindowHandle = nullptr;
2045 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002046 }
2047 }
2048
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002049 // Also don't send the new touch event to unresponsive gesture monitors
2050 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2051
Michael Wright3dd60e22019-03-27 22:06:44 +00002052 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2053 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002054 "(%d, %d) in display %" PRId32 ".",
2055 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002056 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002057 goto Failed;
2058 }
2059
2060 if (newTouchedWindowHandle != nullptr) {
2061 // Set target flags.
2062 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2063 if (isSplit) {
2064 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002065 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002066 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2067 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2068 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2069 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2070 }
2071
2072 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002073 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2074 newHoverWindowHandle = nullptr;
2075 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002076 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002077 }
2078
2079 // Update the temporary touch state.
2080 BitSet32 pointerIds;
2081 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002082 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002083 pointerIds.markBit(pointerId);
2084 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002085 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002086 }
2087
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002088 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002089 } else {
2090 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2091
2092 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002093 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002094 if (DEBUG_FOCUS) {
2095 ALOGD("Dropping event because the pointer is not down or we previously "
2096 "dropped the pointer down event in display %" PRId32,
2097 displayId);
2098 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002099 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002100 goto Failed;
2101 }
2102
arthurhung6d4bed92021-03-17 11:59:33 +08002103 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002104
Michael Wrightd02c5b62014-02-10 15:10:22 -08002105 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002106 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002107 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002108 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2109 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002110
chaviw98318de2021-05-19 16:45:23 -05002111 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002112 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002113 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002114 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2115 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002116 if (DEBUG_FOCUS) {
2117 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2118 oldTouchedWindowHandle->getName().c_str(),
2119 newTouchedWindowHandle->getName().c_str(), displayId);
2120 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002121 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002122 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2123 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2124 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002125
2126 // Make a slippery entrance into the new window.
2127 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2128 isSplit = true;
2129 }
2130
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002131 int32_t targetFlags =
2132 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002133 if (isSplit) {
2134 targetFlags |= InputTarget::FLAG_SPLIT;
2135 }
2136 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2137 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002138 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2139 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002140 }
2141
2142 BitSet32 pointerIds;
2143 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002144 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002146 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147 }
2148 }
2149 }
2150
2151 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002152 // Let the previous window know that the hover sequence is over, unless we already did it
2153 // when dispatching it as is to newTouchedWindowHandle.
2154 if (mLastHoverWindowHandle != nullptr &&
2155 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2156 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002157 if (DEBUG_HOVER) {
2158 ALOGD("Sending hover exit event to window %s.",
2159 mLastHoverWindowHandle->getName().c_str());
2160 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002161 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2162 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002163 }
2164
Garfield Tandf26e862020-07-01 20:18:19 -07002165 // Let the new window know that the hover sequence is starting, unless we already did it
2166 // when dispatching it as is to newTouchedWindowHandle.
2167 if (newHoverWindowHandle != nullptr &&
2168 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2169 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002170 if (DEBUG_HOVER) {
2171 ALOGD("Sending hover enter event to window %s.",
2172 newHoverWindowHandle->getName().c_str());
2173 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002174 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2175 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2176 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002177 }
2178 }
2179
2180 // Check permission to inject into all touched foreground windows and ensure there
2181 // is at least one touched foreground window.
2182 {
2183 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002184 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002185 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2186 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002187 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002188 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002189 injectionPermission = INJECTION_PERMISSION_DENIED;
2190 goto Failed;
2191 }
2192 }
2193 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002194 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002195 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002196 ALOGI("Dropping event because there is no touched foreground window in display "
2197 "%" PRId32 " or gesture monitor to receive it.",
2198 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002199 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002200 goto Failed;
2201 }
2202
2203 // Permission granted to injection into all touched foreground windows.
2204 injectionPermission = INJECTION_PERMISSION_GRANTED;
2205 }
2206
2207 // Check whether windows listening for outside touches are owned by the same UID. If it is
2208 // set the policy flag that we will not reveal coordinate information to this window.
2209 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002210 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002211 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002212 if (foregroundWindowHandle) {
2213 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002214 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002215 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002216 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2217 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2218 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002219 InputTarget::FLAG_ZERO_COORDS,
2220 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002221 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002222 }
2223 }
2224 }
2225 }
2226
Michael Wrightd02c5b62014-02-10 15:10:22 -08002227 // If this is the first pointer going down and the touched window has a wallpaper
2228 // then also add the touched wallpaper windows so they are locked in for the duration
2229 // of the touch gesture.
2230 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2231 // engine only supports touch events. We would need to add a mechanism similar
2232 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2233 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002234 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002235 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002236 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002237 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002238 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002239 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2240 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002241 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002242 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002243 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002244 .addOrUpdateWindow(windowHandle,
2245 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2246 InputTarget::
2247 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2248 InputTarget::FLAG_DISPATCH_AS_IS,
2249 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002250 }
2251 }
2252 }
2253 }
2254
2255 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002256 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002257
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002258 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002259 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002260 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002261 }
2262
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002263 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002264 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002265 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002266 }
2267
Michael Wrightd02c5b62014-02-10 15:10:22 -08002268 // Drop the outside or hover touch windows since we will not care about them
2269 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002270 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002271
2272Failed:
2273 // Check injection permission once and for all.
2274 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002275 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002276 injectionPermission = INJECTION_PERMISSION_GRANTED;
2277 } else {
2278 injectionPermission = INJECTION_PERMISSION_DENIED;
2279 }
2280 }
2281
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002282 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2283 return injectionResult;
2284 }
2285
Michael Wrightd02c5b62014-02-10 15:10:22 -08002286 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002287 if (!wrongDevice) {
2288 if (switchedDevice) {
2289 if (DEBUG_FOCUS) {
2290 ALOGD("Conflicting pointer actions: Switched to a different device.");
2291 }
2292 *outConflictingPointerActions = true;
2293 }
2294
2295 if (isHoverAction) {
2296 // Started hovering, therefore no longer down.
2297 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002298 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002299 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2300 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002301 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002302 *outConflictingPointerActions = true;
2303 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002304 tempTouchState.reset();
2305 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2306 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2307 tempTouchState.deviceId = entry.deviceId;
2308 tempTouchState.source = entry.source;
2309 tempTouchState.displayId = displayId;
2310 }
2311 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2312 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2313 // All pointers up or canceled.
2314 tempTouchState.reset();
2315 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2316 // First pointer went down.
2317 if (oldState && oldState->down) {
2318 if (DEBUG_FOCUS) {
2319 ALOGD("Conflicting pointer actions: Down received while already down.");
2320 }
2321 *outConflictingPointerActions = true;
2322 }
2323 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2324 // One pointer went up.
2325 if (isSplit) {
2326 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2327 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002328
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002329 for (size_t i = 0; i < tempTouchState.windows.size();) {
2330 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2331 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2332 touchedWindow.pointerIds.clearBit(pointerId);
2333 if (touchedWindow.pointerIds.isEmpty()) {
2334 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2335 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002336 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002338 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002339 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002340 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002341 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002342
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002343 // Save changes unless the action was scroll in which case the temporary touch
2344 // state was only valid for this one action.
2345 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2346 if (tempTouchState.displayId >= 0) {
2347 mTouchStatesByDisplay[displayId] = tempTouchState;
2348 } else {
2349 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002350 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002351 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002352
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002353 // Update hover state.
2354 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002355 }
2356
Michael Wrightd02c5b62014-02-10 15:10:22 -08002357 return injectionResult;
2358}
2359
arthurhung6d4bed92021-03-17 11:59:33 +08002360void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002361 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002362 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002363 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002364 if (dropWindow) {
2365 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002366 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002367 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002368 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002369 }
2370 mDragState.reset();
2371}
2372
2373void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2374 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002375 return;
2376 }
2377
arthurhung6d4bed92021-03-17 11:59:33 +08002378 if (!mDragState->isStartDrag) {
2379 mDragState->isStartDrag = true;
2380 mDragState->isStylusButtonDownAtStart =
2381 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2382 }
2383
arthurhungb89ccb02020-12-30 16:19:01 +08002384 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2385 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2386 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2387 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002388 // Handle the special case : stylus button no longer pressed.
2389 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2390 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2391 finishDragAndDrop(entry.displayId, x, y);
2392 return;
2393 }
2394
chaviw98318de2021-05-19 16:45:23 -05002395 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002396 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002397 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002398 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002399 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2400 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2401 if (mDragState->dragHoverWindowHandle != nullptr) {
2402 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2403 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002404 }
arthurhung6d4bed92021-03-17 11:59:33 +08002405 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002406 }
2407 // enqueue drag location if needed.
2408 if (hoverWindowHandle != nullptr) {
2409 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2410 }
arthurhung6d4bed92021-03-17 11:59:33 +08002411 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2412 finishDragAndDrop(entry.displayId, x, y);
2413 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002414 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002415 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002416 }
2417}
2418
chaviw98318de2021-05-19 16:45:23 -05002419void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002420 int32_t targetFlags, BitSet32 pointerIds,
2421 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002422 std::vector<InputTarget>::iterator it =
2423 std::find_if(inputTargets.begin(), inputTargets.end(),
2424 [&windowHandle](const InputTarget& inputTarget) {
2425 return inputTarget.inputChannel->getConnectionToken() ==
2426 windowHandle->getToken();
2427 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002428
chaviw98318de2021-05-19 16:45:23 -05002429 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002430
2431 if (it == inputTargets.end()) {
2432 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002433 std::shared_ptr<InputChannel> inputChannel =
2434 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002435 if (inputChannel == nullptr) {
2436 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2437 return;
2438 }
2439 inputTarget.inputChannel = inputChannel;
2440 inputTarget.flags = targetFlags;
2441 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Evan Rosky09576692021-07-01 12:22:09 -07002442 inputTarget.displayOrientation = windowInfo->displayOrientation;
Evan Rosky84f07f02021-04-16 10:42:42 -07002443 inputTarget.displaySize =
Evan Rosky44edce92021-05-14 18:09:55 -07002444 int2(windowHandle->getInfo()->displayWidth, windowHandle->getInfo()->displayHeight);
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002445 inputTargets.push_back(inputTarget);
2446 it = inputTargets.end() - 1;
2447 }
2448
2449 ALOG_ASSERT(it->flags == targetFlags);
2450 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2451
chaviw1ff3d1e2020-07-01 15:53:47 -07002452 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002453}
2454
Michael Wright3dd60e22019-03-27 22:06:44 +00002455void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002456 int32_t displayId, float xOffset,
2457 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002458 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2459 mGlobalMonitorsByDisplay.find(displayId);
2460
2461 if (it != mGlobalMonitorsByDisplay.end()) {
2462 const std::vector<Monitor>& monitors = it->second;
2463 for (const Monitor& monitor : monitors) {
2464 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002465 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002466 }
2467}
2468
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002469void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2470 float yOffset,
2471 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002472 InputTarget target;
2473 target.inputChannel = monitor.inputChannel;
2474 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002475 ui::Transform t;
2476 t.set(xOffset, yOffset);
2477 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002478 inputTargets.push_back(target);
2479}
2480
chaviw98318de2021-05-19 16:45:23 -05002481bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002482 const InjectionState* injectionState) {
2483 if (injectionState &&
2484 (windowHandle == nullptr ||
2485 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2486 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002487 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002488 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002489 "owned by uid %d",
2490 injectionState->injectorPid, injectionState->injectorUid,
2491 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002492 } else {
2493 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002494 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002495 }
2496 return false;
2497 }
2498 return true;
2499}
2500
Robert Carrc9bf1d32020-04-13 17:21:08 -07002501/**
2502 * Indicate whether one window handle should be considered as obscuring
2503 * another window handle. We only check a few preconditions. Actually
2504 * checking the bounds is left to the caller.
2505 */
chaviw98318de2021-05-19 16:45:23 -05002506static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2507 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002508 // Compare by token so cloned layers aren't counted
2509 if (haveSameToken(windowHandle, otherHandle)) {
2510 return false;
2511 }
2512 auto info = windowHandle->getInfo();
2513 auto otherInfo = otherHandle->getInfo();
2514 if (!otherInfo->visible) {
2515 return false;
chaviw98318de2021-05-19 16:45:23 -05002516 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002517 // Those act as if they were invisible, so we don't need to flag them.
2518 // We do want to potentially flag touchable windows even if they have 0
2519 // opacity, since they can consume touches and alter the effects of the
2520 // user interaction (eg. apps that rely on
2521 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2522 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2523 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002524 } else if (info->ownerUid == otherInfo->ownerUid) {
2525 // If ownerUid is the same we don't generate occlusion events as there
2526 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002527 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002528 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002529 return false;
2530 } else if (otherInfo->displayId != info->displayId) {
2531 return false;
2532 }
2533 return true;
2534}
2535
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002536/**
2537 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2538 * untrusted, one should check:
2539 *
2540 * 1. If result.hasBlockingOcclusion is true.
2541 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2542 * BLOCK_UNTRUSTED.
2543 *
2544 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2545 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2546 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2547 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2548 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2549 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2550 *
2551 * If neither of those is true, then it means the touch can be allowed.
2552 */
2553InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002554 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2555 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002556 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002557 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002558 TouchOcclusionInfo info;
2559 info.hasBlockingOcclusion = false;
2560 info.obscuringOpacity = 0;
2561 info.obscuringUid = -1;
2562 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002563 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002564 if (windowHandle == otherHandle) {
2565 break; // All future windows are below us. Exit early.
2566 }
chaviw98318de2021-05-19 16:45:23 -05002567 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002568 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2569 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002570 if (DEBUG_TOUCH_OCCLUSION) {
2571 info.debugInfo.push_back(
2572 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2573 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002574 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2575 // we perform the checks below to see if the touch can be propagated or not based on the
2576 // window's touch occlusion mode
2577 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2578 info.hasBlockingOcclusion = true;
2579 info.obscuringUid = otherInfo->ownerUid;
2580 info.obscuringPackage = otherInfo->packageName;
2581 break;
2582 }
2583 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2584 uint32_t uid = otherInfo->ownerUid;
2585 float opacity =
2586 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2587 // Given windows A and B:
2588 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2589 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2590 opacityByUid[uid] = opacity;
2591 if (opacity > info.obscuringOpacity) {
2592 info.obscuringOpacity = opacity;
2593 info.obscuringUid = uid;
2594 info.obscuringPackage = otherInfo->packageName;
2595 }
2596 }
2597 }
2598 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002599 if (DEBUG_TOUCH_OCCLUSION) {
2600 info.debugInfo.push_back(
2601 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2602 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002603 return info;
2604}
2605
chaviw98318de2021-05-19 16:45:23 -05002606std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002607 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002608 return StringPrintf(INDENT2
2609 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2610 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2611 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2612 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002613 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002614 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002615 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002616 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2617 info->frameTop, info->frameRight, info->frameBottom,
2618 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002619 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2620 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2621 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002622}
2623
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002624bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2625 if (occlusionInfo.hasBlockingOcclusion) {
2626 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2627 occlusionInfo.obscuringUid);
2628 return false;
2629 }
2630 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2631 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2632 "%.2f, maximum allowed = %.2f)",
2633 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2634 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2635 return false;
2636 }
2637 return true;
2638}
2639
chaviw98318de2021-05-19 16:45:23 -05002640bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002641 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002642 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002643 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2644 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002645 if (windowHandle == otherHandle) {
2646 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002647 }
chaviw98318de2021-05-19 16:45:23 -05002648 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002649 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002650 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002651 return true;
2652 }
2653 }
2654 return false;
2655}
2656
chaviw98318de2021-05-19 16:45:23 -05002657bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002658 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002659 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2660 const WindowInfo* windowInfo = windowHandle->getInfo();
2661 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002662 if (windowHandle == otherHandle) {
2663 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002664 }
chaviw98318de2021-05-19 16:45:23 -05002665 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002666 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002667 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002668 return true;
2669 }
2670 }
2671 return false;
2672}
2673
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002674std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002675 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002676 if (applicationHandle != nullptr) {
2677 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002678 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002679 } else {
2680 return applicationHandle->getName();
2681 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002682 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002683 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002684 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002685 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002686 }
2687}
2688
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002689void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002690 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002691 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2692 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002693 // Focus or pointer capture changed events are passed to apps, but do not represent user
2694 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002695 return;
2696 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002697 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002698 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002699 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002700 const WindowInfo* info = focusedWindowHandle->getInfo();
2701 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002702 if (DEBUG_DISPATCH_CYCLE) {
2703 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2704 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002705 return;
2706 }
2707 }
2708
2709 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002710 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002711 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002712 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2713 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002714 return;
2715 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002716
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002717 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002718 eventType = USER_ACTIVITY_EVENT_TOUCH;
2719 }
2720 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002722 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002723 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2724 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002725 return;
2726 }
2727 eventType = USER_ACTIVITY_EVENT_BUTTON;
2728 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002730 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002731 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002732 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002733 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002734 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2735 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002736 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002737 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002738 break;
2739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002740 }
2741
Prabir Pradhancef936d2021-07-21 16:17:52 +00002742 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2743 REQUIRES(mLock) {
2744 scoped_unlock unlock(mLock);
2745 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2746 };
2747 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002748}
2749
2750void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002751 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002752 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002753 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002754 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002755 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002756 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002757 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002758 ATRACE_NAME(message.c_str());
2759 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002760 if (DEBUG_DISPATCH_CYCLE) {
2761 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2762 "globalScaleFactor=%f, pointerIds=0x%x %s",
2763 connection->getInputChannelName().c_str(), inputTarget.flags,
2764 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2765 inputTarget.getPointerInfoString().c_str());
2766 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002767
2768 // Skip this event if the connection status is not normal.
2769 // We don't want to enqueue additional outbound events if the connection is broken.
2770 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002771 if (DEBUG_DISPATCH_CYCLE) {
2772 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2773 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775 return;
2776 }
2777
2778 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002779 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2780 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2781 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002782 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002783
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002784 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002785 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002786 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002787 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002788 if (!splitMotionEntry) {
2789 return; // split event was dropped
2790 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002791 if (DEBUG_FOCUS) {
2792 ALOGD("channel '%s' ~ Split motion event.",
2793 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002794 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002795 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002796 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2797 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002798 return;
2799 }
2800 }
2801
2802 // Not splitting. Enqueue dispatch entries for the event as is.
2803 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2804}
2805
2806void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002807 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002808 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002809 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002810 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002811 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002812 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002813 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002814 ATRACE_NAME(message.c_str());
2815 }
2816
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002817 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002818
2819 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002820 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002821 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002822 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002823 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002824 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002825 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002826 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002827 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002828 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002829 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002830 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002831 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002832
2833 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002834 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002835 startDispatchCycleLocked(currentTime, connection);
2836 }
2837}
2838
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002839void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002840 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002841 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002842 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002843 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002844 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2845 connection->getInputChannelName().c_str(),
2846 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002847 ATRACE_NAME(message.c_str());
2848 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002849 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002850 if (!(inputTargetFlags & dispatchMode)) {
2851 return;
2852 }
2853 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2854
2855 // This is a new event.
2856 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002857 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002858 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002859
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002860 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2861 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002862 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002863 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002864 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002865 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002866 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002867 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002868 dispatchEntry->resolvedAction = keyEntry.action;
2869 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002870
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002871 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2872 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002873 if (DEBUG_DISPATCH_CYCLE) {
2874 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2875 "event",
2876 connection->getInputChannelName().c_str());
2877 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002878 return; // skip the inconsistent event
2879 }
2880 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002882
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002883 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002884 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002885 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2886 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2887 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2888 static_cast<int32_t>(IdGenerator::Source::OTHER);
2889 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002890 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2891 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2892 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2893 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2894 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2895 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2896 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2897 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2898 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2899 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2900 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002901 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002902 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002903 }
2904 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002905 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2906 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002907 if (DEBUG_DISPATCH_CYCLE) {
2908 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
2909 "enter event",
2910 connection->getInputChannelName().c_str());
2911 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002912 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2913 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002914 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2915 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002916
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002917 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2919 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2920 }
2921 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2922 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2923 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002925 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2926 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002927 if (DEBUG_DISPATCH_CYCLE) {
2928 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2929 "event",
2930 connection->getInputChannelName().c_str());
2931 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002932 return; // skip the inconsistent event
2933 }
2934
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002935 dispatchEntry->resolvedEventId =
2936 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2937 ? mIdGenerator.nextId()
2938 : motionEntry.id;
2939 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2940 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2941 ") to MotionEvent(id=0x%" PRIx32 ").",
2942 motionEntry.id, dispatchEntry->resolvedEventId);
2943 ATRACE_NAME(message.c_str());
2944 }
2945
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08002946 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
2947 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
2948 // Skip reporting pointer down outside focus to the policy.
2949 break;
2950 }
2951
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002952 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002953 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002954
2955 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002956 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002957 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08002958 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2959 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002960 break;
2961 }
Chris Yef59a2f42020-10-16 12:55:26 -07002962 case EventEntry::Type::SENSOR: {
2963 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2964 break;
2965 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002966 case EventEntry::Type::CONFIGURATION_CHANGED:
2967 case EventEntry::Type::DEVICE_RESET: {
2968 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002969 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002970 break;
2971 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002972 }
2973
2974 // Remember that we are waiting for this dispatch to complete.
2975 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002976 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002977 }
2978
2979 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002980 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00002981 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07002982}
2983
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002984/**
2985 * This function is purely for debugging. It helps us understand where the user interaction
2986 * was taking place. For example, if user is touching launcher, we will see a log that user
2987 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2988 * We will see both launcher and wallpaper in that list.
2989 * Once the interaction with a particular set of connections starts, no new logs will be printed
2990 * until the set of interacted connections changes.
2991 *
2992 * The following items are skipped, to reduce the logspam:
2993 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2994 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2995 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2996 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2997 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002998 */
2999void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3000 const std::vector<InputTarget>& targets) {
3001 // Skip ACTION_UP events, and all events other than keys and motions
3002 if (entry.type == EventEntry::Type::KEY) {
3003 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3004 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3005 return;
3006 }
3007 } else if (entry.type == EventEntry::Type::MOTION) {
3008 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3009 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3010 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3011 return;
3012 }
3013 } else {
3014 return; // Not a key or a motion
3015 }
3016
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003017 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003018 std::vector<sp<Connection>> newConnections;
3019 for (const InputTarget& target : targets) {
3020 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3021 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3022 continue; // Skip windows that receive ACTION_OUTSIDE
3023 }
3024
3025 sp<IBinder> token = target.inputChannel->getConnectionToken();
3026 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003027 if (connection == nullptr) {
3028 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003029 }
3030 newConnectionTokens.insert(std::move(token));
3031 newConnections.emplace_back(connection);
3032 }
3033 if (newConnectionTokens == mInteractionConnectionTokens) {
3034 return; // no change
3035 }
3036 mInteractionConnectionTokens = newConnectionTokens;
3037
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003038 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003039 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003040 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003041 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003042 std::string message = "Interaction with: " + targetList;
3043 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003044 message += "<none>";
3045 }
3046 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3047}
3048
chaviwfd6d3512019-03-25 13:23:49 -07003049void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003050 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003051 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003052 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3053 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003054 return;
3055 }
3056
Vishnu Nairc519ff72021-01-21 08:23:08 -08003057 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003058 if (focusedToken == token) {
3059 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003060 return;
3061 }
3062
Prabir Pradhancef936d2021-07-21 16:17:52 +00003063 auto command = [this, token]() REQUIRES(mLock) {
3064 scoped_unlock unlock(mLock);
3065 mPolicy->onPointerDownOutsideFocus(token);
3066 };
3067 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003068}
3069
3070void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003071 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003072 if (ATRACE_ENABLED()) {
3073 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003074 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003075 ATRACE_NAME(message.c_str());
3076 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003077 if (DEBUG_DISPATCH_CYCLE) {
3078 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3079 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003080
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003081 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3082 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003083 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003084 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003085 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003086 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003087
3088 // Publish the event.
3089 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003090 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3091 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003092 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003093 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3094 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003095
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003096 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003097 status = connection->inputPublisher
3098 .publishKeyEvent(dispatchEntry->seq,
3099 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3100 keyEntry.source, keyEntry.displayId,
3101 std::move(hmac), dispatchEntry->resolvedAction,
3102 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3103 keyEntry.scanCode, keyEntry.metaState,
3104 keyEntry.repeatCount, keyEntry.downTime,
3105 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003106 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003107 }
3108
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003109 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003110 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003111
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003112 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003113 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114
chaviw82357092020-01-28 13:13:06 -08003115 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003116 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003117 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3118 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003119 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003120 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3121 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003122 // Don't apply window scale here since we don't want scale to affect raw
3123 // coordinates. The scale will be sent back to the client and applied
3124 // later when requesting relative coordinates.
3125 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3126 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003127 }
3128 usingCoords = scaledCoords;
3129 }
3130 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003131 // We don't want the dispatch target to know.
3132 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003133 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003134 scaledCoords[i].clear();
3135 }
3136 usingCoords = scaledCoords;
3137 }
3138 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003139
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003140 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003141
3142 // Publish the motion event.
3143 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003144 .publishMotionEvent(dispatchEntry->seq,
3145 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003146 motionEntry.deviceId, motionEntry.source,
3147 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003148 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003149 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003150 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003151 motionEntry.edgeFlags, motionEntry.metaState,
3152 motionEntry.buttonState,
3153 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003154 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003155 motionEntry.xPrecision, motionEntry.yPrecision,
3156 motionEntry.xCursorPosition,
3157 motionEntry.yCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003158 dispatchEntry->displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -07003159 dispatchEntry->displaySize.x,
3160 dispatchEntry->displaySize.y,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003161 motionEntry.downTime, motionEntry.eventTime,
3162 motionEntry.pointerCount,
3163 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003164 break;
3165 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003166
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003167 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003168 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003169 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003170 focusEntry.id,
3171 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003172 mInTouchMode);
3173 break;
3174 }
3175
Prabir Pradhan99987712020-11-10 18:43:05 -08003176 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3177 const auto& captureEntry =
3178 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3179 status = connection->inputPublisher
3180 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3181 captureEntry.pointerCaptureEnabled);
3182 break;
3183 }
3184
arthurhungb89ccb02020-12-30 16:19:01 +08003185 case EventEntry::Type::DRAG: {
3186 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3187 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3188 dragEntry.id, dragEntry.x,
3189 dragEntry.y,
3190 dragEntry.isExiting);
3191 break;
3192 }
3193
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003194 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003195 case EventEntry::Type::DEVICE_RESET:
3196 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003197 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003198 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003199 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003200 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003201 }
3202
3203 // Check the result.
3204 if (status) {
3205 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003206 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003207 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003208 "This is unexpected because the wait queue is empty, so the pipe "
3209 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003210 "event to it, status=%s(%d)",
3211 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3212 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3214 } else {
3215 // Pipe is full and we are waiting for the app to finish process some events
3216 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003217 if (DEBUG_DISPATCH_CYCLE) {
3218 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3219 "waiting for the application to catch up",
3220 connection->getInputChannelName().c_str());
3221 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222 }
3223 } else {
3224 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003225 "status=%s(%d)",
3226 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3227 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003228 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3229 }
3230 return;
3231 }
3232
3233 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003234 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3235 connection->outboundQueue.end(),
3236 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003237 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003238 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003239 if (connection->responsive) {
3240 mAnrTracker.insert(dispatchEntry->timeoutTime,
3241 connection->inputChannel->getConnectionToken());
3242 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003243 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244 }
3245}
3246
chaviw09c8d2d2020-08-24 15:48:26 -07003247std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3248 size_t size;
3249 switch (event.type) {
3250 case VerifiedInputEvent::Type::KEY: {
3251 size = sizeof(VerifiedKeyEvent);
3252 break;
3253 }
3254 case VerifiedInputEvent::Type::MOTION: {
3255 size = sizeof(VerifiedMotionEvent);
3256 break;
3257 }
3258 }
3259 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3260 return mHmacKeyManager.sign(start, size);
3261}
3262
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003263const std::array<uint8_t, 32> InputDispatcher::getSignature(
3264 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3265 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3266 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3267 // Only sign events up and down events as the purely move events
3268 // are tied to their up/down counterparts so signing would be redundant.
3269 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3270 verifiedEvent.actionMasked = actionMasked;
3271 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003272 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003273 }
3274 return INVALID_HMAC;
3275}
3276
3277const std::array<uint8_t, 32> InputDispatcher::getSignature(
3278 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3279 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3280 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3281 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003282 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003283}
3284
Michael Wrightd02c5b62014-02-10 15:10:22 -08003285void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003286 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003287 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003288 if (DEBUG_DISPATCH_CYCLE) {
3289 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3290 connection->getInputChannelName().c_str(), seq, toString(handled));
3291 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003292
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003293 if (connection->status == Connection::STATUS_BROKEN ||
3294 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003295 return;
3296 }
3297
3298 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003299 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3300 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3301 };
3302 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003303}
3304
3305void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003306 const sp<Connection>& connection,
3307 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003308 if (DEBUG_DISPATCH_CYCLE) {
3309 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3310 connection->getInputChannelName().c_str(), toString(notify));
3311 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003312
3313 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003314 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003315 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003316 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003317 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318
3319 // The connection appears to be unrecoverably broken.
3320 // Ignore already broken or zombie connections.
3321 if (connection->status == Connection::STATUS_NORMAL) {
3322 connection->status = Connection::STATUS_BROKEN;
3323
3324 if (notify) {
3325 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003326 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3327 connection->getInputChannelName().c_str());
3328
3329 auto command = [this, connection]() REQUIRES(mLock) {
3330 if (connection->status == Connection::STATUS_ZOMBIE) return;
3331 scoped_unlock unlock(mLock);
3332 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3333 };
3334 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003335 }
3336 }
3337}
3338
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003339void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3340 while (!queue.empty()) {
3341 DispatchEntry* dispatchEntry = queue.front();
3342 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003343 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003344 }
3345}
3346
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003347void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003348 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003349 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003350 }
3351 delete dispatchEntry;
3352}
3353
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003354int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3355 std::scoped_lock _l(mLock);
3356 sp<Connection> connection = getConnectionLocked(connectionToken);
3357 if (connection == nullptr) {
3358 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3359 connectionToken.get(), events);
3360 return 0; // remove the callback
3361 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003363 bool notify;
3364 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3365 if (!(events & ALOOPER_EVENT_INPUT)) {
3366 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3367 "events=0x%x",
3368 connection->getInputChannelName().c_str(), events);
3369 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003370 }
3371
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003372 nsecs_t currentTime = now();
3373 bool gotOne = false;
3374 status_t status = OK;
3375 for (;;) {
3376 Result<InputPublisher::ConsumerResponse> result =
3377 connection->inputPublisher.receiveConsumerResponse();
3378 if (!result.ok()) {
3379 status = result.error().code();
3380 break;
3381 }
3382
3383 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3384 const InputPublisher::Finished& finish =
3385 std::get<InputPublisher::Finished>(*result);
3386 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3387 finish.consumeTime);
3388 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003389 if (shouldReportMetricsForConnection(*connection)) {
3390 const InputPublisher::Timeline& timeline =
3391 std::get<InputPublisher::Timeline>(*result);
3392 mLatencyTracker
3393 .trackGraphicsLatency(timeline.inputEventId,
3394 connection->inputChannel->getConnectionToken(),
3395 std::move(timeline.graphicsTimeline));
3396 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003397 }
3398 gotOne = true;
3399 }
3400 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003401 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003402 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003403 return 1;
3404 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003405 }
3406
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003407 notify = status != DEAD_OBJECT || !connection->monitor;
3408 if (notify) {
3409 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3410 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3411 status);
3412 }
3413 } else {
3414 // Monitor channels are never explicitly unregistered.
3415 // We do it automatically when the remote endpoint is closed so don't warn about them.
3416 const bool stillHaveWindowHandle =
3417 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3418 notify = !connection->monitor && stillHaveWindowHandle;
3419 if (notify) {
3420 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3421 connection->getInputChannelName().c_str(), events);
3422 }
3423 }
3424
3425 // Remove the channel.
3426 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3427 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003428}
3429
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003430void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003431 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003432 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003433 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003434 }
3435}
3436
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003437void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003438 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003439 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3440 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3441}
3442
3443void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3444 const CancelationOptions& options,
3445 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3446 for (const auto& it : monitorsByDisplay) {
3447 const std::vector<Monitor>& monitors = it.second;
3448 for (const Monitor& monitor : monitors) {
3449 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003450 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003451 }
3452}
3453
Michael Wrightd02c5b62014-02-10 15:10:22 -08003454void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003455 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003456 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003457 if (connection == nullptr) {
3458 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003459 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003460
3461 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003462}
3463
3464void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3465 const sp<Connection>& connection, const CancelationOptions& options) {
3466 if (connection->status == Connection::STATUS_BROKEN) {
3467 return;
3468 }
3469
3470 nsecs_t currentTime = now();
3471
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003472 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003473 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003475 if (cancelationEvents.empty()) {
3476 return;
3477 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003478 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3479 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3480 "with reality: %s, mode=%d.",
3481 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3482 options.mode);
3483 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003484
3485 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003486 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003487 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3488 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003489 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003490 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003491 target.globalScaleFactor = windowInfo->globalScaleFactor;
3492 }
3493 target.inputChannel = connection->inputChannel;
3494 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3495
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003496 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003497 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003498 switch (cancelationEventEntry->type) {
3499 case EventEntry::Type::KEY: {
3500 logOutboundKeyDetails("cancel - ",
3501 static_cast<const KeyEntry&>(*cancelationEventEntry));
3502 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003504 case EventEntry::Type::MOTION: {
3505 logOutboundMotionDetails("cancel - ",
3506 static_cast<const MotionEntry&>(*cancelationEventEntry));
3507 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003509 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08003510 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3511 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003512 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003513 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003514 break;
3515 }
3516 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003517 case EventEntry::Type::DEVICE_RESET:
3518 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003519 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003520 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003521 break;
3522 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003523 }
3524
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003525 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3526 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003527 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003528
3529 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003530}
3531
Svet Ganov5d3bc372020-01-26 23:11:07 -08003532void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3533 const sp<Connection>& connection) {
3534 if (connection->status == Connection::STATUS_BROKEN) {
3535 return;
3536 }
3537
3538 nsecs_t currentTime = now();
3539
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003540 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003541 connection->inputState.synthesizePointerDownEvents(currentTime);
3542
3543 if (downEvents.empty()) {
3544 return;
3545 }
3546
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003547 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003548 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3549 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003550 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003551
3552 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003553 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003554 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3555 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003556 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003557 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003558 target.globalScaleFactor = windowInfo->globalScaleFactor;
3559 }
3560 target.inputChannel = connection->inputChannel;
3561 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3562
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003563 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003564 switch (downEventEntry->type) {
3565 case EventEntry::Type::MOTION: {
3566 logOutboundMotionDetails("down - ",
3567 static_cast<const MotionEntry&>(*downEventEntry));
3568 break;
3569 }
3570
3571 case EventEntry::Type::KEY:
3572 case EventEntry::Type::FOCUS:
3573 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003574 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003575 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003576 case EventEntry::Type::SENSOR:
3577 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003578 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003579 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003580 break;
3581 }
3582 }
3583
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003584 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3585 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003586 }
3587
3588 startDispatchCycleLocked(currentTime, connection);
3589}
3590
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003591std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3592 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003593 ALOG_ASSERT(pointerIds.value != 0);
3594
3595 uint32_t splitPointerIndexMap[MAX_POINTERS];
3596 PointerProperties splitPointerProperties[MAX_POINTERS];
3597 PointerCoords splitPointerCoords[MAX_POINTERS];
3598
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003599 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 uint32_t splitPointerCount = 0;
3601
3602 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003603 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003604 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003605 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606 uint32_t pointerId = uint32_t(pointerProperties.id);
3607 if (pointerIds.hasBit(pointerId)) {
3608 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3609 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3610 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003611 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612 splitPointerCount += 1;
3613 }
3614 }
3615
3616 if (splitPointerCount != pointerIds.count()) {
3617 // This is bad. We are missing some of the pointers that we expected to deliver.
3618 // Most likely this indicates that we received an ACTION_MOVE events that has
3619 // different pointer ids than we expected based on the previous ACTION_DOWN
3620 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3621 // in this way.
3622 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003623 "we expected there to be %d pointers. This probably means we received "
3624 "a broken sequence of pointer ids from the input device.",
3625 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003626 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003627 }
3628
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003629 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003630 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003631 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3632 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003633 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3634 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003635 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636 uint32_t pointerId = uint32_t(pointerProperties.id);
3637 if (pointerIds.hasBit(pointerId)) {
3638 if (pointerIds.count() == 1) {
3639 // The first/last pointer went down/up.
3640 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003641 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003642 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3643 ? AMOTION_EVENT_ACTION_CANCEL
3644 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 } else {
3646 // A secondary pointer went down/up.
3647 uint32_t splitPointerIndex = 0;
3648 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3649 splitPointerIndex += 1;
3650 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003651 action = maskedAction |
3652 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003653 }
3654 } else {
3655 // An unrelated pointer changed.
3656 action = AMOTION_EVENT_ACTION_MOVE;
3657 }
3658 }
3659
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003660 int32_t newId = mIdGenerator.nextId();
3661 if (ATRACE_ENABLED()) {
3662 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3663 ") to MotionEvent(id=0x%" PRIx32 ").",
3664 originalMotionEntry.id, newId);
3665 ATRACE_NAME(message.c_str());
3666 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003667 std::unique_ptr<MotionEntry> splitMotionEntry =
3668 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3669 originalMotionEntry.deviceId, originalMotionEntry.source,
3670 originalMotionEntry.displayId,
3671 originalMotionEntry.policyFlags, action,
3672 originalMotionEntry.actionButton,
3673 originalMotionEntry.flags, originalMotionEntry.metaState,
3674 originalMotionEntry.buttonState,
3675 originalMotionEntry.classification,
3676 originalMotionEntry.edgeFlags,
3677 originalMotionEntry.xPrecision,
3678 originalMotionEntry.yPrecision,
3679 originalMotionEntry.xCursorPosition,
3680 originalMotionEntry.yCursorPosition,
3681 originalMotionEntry.downTime, splitPointerCount,
3682 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003683
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003684 if (originalMotionEntry.injectionState) {
3685 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003686 splitMotionEntry->injectionState->refCount += 1;
3687 }
3688
3689 return splitMotionEntry;
3690}
3691
3692void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003693 if (DEBUG_INBOUND_EVENT_DETAILS) {
3694 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3695 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003696
3697 bool needWake;
3698 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003699 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003700
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003701 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3702 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3703 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003704 } // release lock
3705
3706 if (needWake) {
3707 mLooper->wake();
3708 }
3709}
3710
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003711/**
3712 * If one of the meta shortcuts is detected, process them here:
3713 * Meta + Backspace -> generate BACK
3714 * Meta + Enter -> generate HOME
3715 * This will potentially overwrite keyCode and metaState.
3716 */
3717void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003718 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003719 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3720 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3721 if (keyCode == AKEYCODE_DEL) {
3722 newKeyCode = AKEYCODE_BACK;
3723 } else if (keyCode == AKEYCODE_ENTER) {
3724 newKeyCode = AKEYCODE_HOME;
3725 }
3726 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003727 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003728 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003729 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003730 keyCode = newKeyCode;
3731 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3732 }
3733 } else if (action == AKEY_EVENT_ACTION_UP) {
3734 // In order to maintain a consistent stream of up and down events, check to see if the key
3735 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3736 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003737 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003738 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003739 auto replacementIt = mReplacedKeys.find(replacement);
3740 if (replacementIt != mReplacedKeys.end()) {
3741 keyCode = replacementIt->second;
3742 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003743 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3744 }
3745 }
3746}
3747
Michael Wrightd02c5b62014-02-10 15:10:22 -08003748void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003749 if (DEBUG_INBOUND_EVENT_DETAILS) {
3750 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3751 "policyFlags=0x%x, action=0x%x, "
3752 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3753 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3754 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3755 args->downTime);
3756 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003757 if (!validateKeyEvent(args->action)) {
3758 return;
3759 }
3760
3761 uint32_t policyFlags = args->policyFlags;
3762 int32_t flags = args->flags;
3763 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003764 // InputDispatcher tracks and generates key repeats on behalf of
3765 // whatever notifies it, so repeatCount should always be set to 0
3766 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003767 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3768 policyFlags |= POLICY_FLAG_VIRTUAL;
3769 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3770 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003771 if (policyFlags & POLICY_FLAG_FUNCTION) {
3772 metaState |= AMETA_FUNCTION_ON;
3773 }
3774
3775 policyFlags |= POLICY_FLAG_TRUSTED;
3776
Michael Wright78f24442014-08-06 15:55:28 -07003777 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003778 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003779
Michael Wrightd02c5b62014-02-10 15:10:22 -08003780 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003781 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003782 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3783 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784
Michael Wright2b3c3302018-03-02 17:19:13 +00003785 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003786 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003787 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3788 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003789 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003790 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003791
Michael Wrightd02c5b62014-02-10 15:10:22 -08003792 bool needWake;
3793 { // acquire lock
3794 mLock.lock();
3795
3796 if (shouldSendKeyToInputFilterLocked(args)) {
3797 mLock.unlock();
3798
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003799 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003800 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3801 return; // event was consumed by the filter
3802 }
3803
3804 mLock.lock();
3805 }
3806
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003807 std::unique_ptr<KeyEntry> newEntry =
3808 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3809 args->displayId, policyFlags, args->action, flags,
3810 keyCode, args->scanCode, metaState, repeatCount,
3811 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003813 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814 mLock.unlock();
3815 } // release lock
3816
3817 if (needWake) {
3818 mLooper->wake();
3819 }
3820}
3821
3822bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3823 return mInputFilterEnabled;
3824}
3825
3826void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003827 if (DEBUG_INBOUND_EVENT_DETAILS) {
3828 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3829 "displayId=%" PRId32 ", policyFlags=0x%x, "
3830 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3831 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3832 "yCursorPosition=%f, downTime=%" PRId64,
3833 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3834 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3835 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3836 args->xCursorPosition, args->yCursorPosition, args->downTime);
3837 for (uint32_t i = 0; i < args->pointerCount; i++) {
3838 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3839 "x=%f, y=%f, pressure=%f, size=%f, "
3840 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3841 "orientation=%f",
3842 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3843 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3844 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3845 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3846 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3847 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3848 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3849 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3850 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3851 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3852 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003853 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003854 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3855 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003856 return;
3857 }
3858
3859 uint32_t policyFlags = args->policyFlags;
3860 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003861
3862 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003863 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003864 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3865 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003866 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003867 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868
3869 bool needWake;
3870 { // acquire lock
3871 mLock.lock();
3872
3873 if (shouldSendMotionToInputFilterLocked(args)) {
3874 mLock.unlock();
3875
3876 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003877 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003878 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3879 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003880 args->metaState, args->buttonState, args->classification, transform,
3881 args->xPrecision, args->yPrecision, args->xCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003882 args->yCursorPosition, ui::Transform::ROT_0, INVALID_DISPLAY_SIZE,
3883 INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
3884 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003885
3886 policyFlags |= POLICY_FLAG_FILTERED;
3887 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3888 return; // event was consumed by the filter
3889 }
3890
3891 mLock.lock();
3892 }
3893
3894 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003895 std::unique_ptr<MotionEntry> newEntry =
3896 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3897 args->source, args->displayId, policyFlags,
3898 args->action, args->actionButton, args->flags,
3899 args->metaState, args->buttonState,
3900 args->classification, args->edgeFlags,
3901 args->xPrecision, args->yPrecision,
3902 args->xCursorPosition, args->yCursorPosition,
3903 args->downTime, args->pointerCount,
3904 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003905
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00003906 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
3907 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
3908 !mInputFilterEnabled) {
3909 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
3910 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
3911 }
3912
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003913 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003914 mLock.unlock();
3915 } // release lock
3916
3917 if (needWake) {
3918 mLooper->wake();
3919 }
3920}
3921
Chris Yef59a2f42020-10-16 12:55:26 -07003922void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003923 if (DEBUG_INBOUND_EVENT_DETAILS) {
3924 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3925 " sensorType=%s",
3926 args->id, args->eventTime, args->deviceId, args->source,
3927 NamedEnum::string(args->sensorType).c_str());
3928 }
Chris Yef59a2f42020-10-16 12:55:26 -07003929
3930 bool needWake;
3931 { // acquire lock
3932 mLock.lock();
3933
3934 // Just enqueue a new sensor event.
3935 std::unique_ptr<SensorEntry> newEntry =
3936 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3937 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3938 args->sensorType, args->accuracy,
3939 args->accuracyChanged, args->values);
3940
3941 needWake = enqueueInboundEventLocked(std::move(newEntry));
3942 mLock.unlock();
3943 } // release lock
3944
3945 if (needWake) {
3946 mLooper->wake();
3947 }
3948}
3949
Chris Yefb552902021-02-03 17:18:37 -08003950void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003951 if (DEBUG_INBOUND_EVENT_DETAILS) {
3952 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3953 args->deviceId, args->isOn);
3954 }
Chris Yefb552902021-02-03 17:18:37 -08003955 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3956}
3957
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003959 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003960}
3961
3962void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003963 if (DEBUG_INBOUND_EVENT_DETAILS) {
3964 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
3965 "switchMask=0x%08x",
3966 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
3967 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968
3969 uint32_t policyFlags = args->policyFlags;
3970 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003971 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972}
3973
3974void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003975 if (DEBUG_INBOUND_EVENT_DETAILS) {
3976 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3977 args->deviceId);
3978 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003979
3980 bool needWake;
3981 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003982 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003983
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003984 std::unique_ptr<DeviceResetEntry> newEntry =
3985 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3986 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003987 } // release lock
3988
3989 if (needWake) {
3990 mLooper->wake();
3991 }
3992}
3993
Prabir Pradhan7e186182020-11-10 13:56:45 -08003994void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003995 if (DEBUG_INBOUND_EVENT_DETAILS) {
3996 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3997 args->enabled ? "true" : "false");
3998 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003999
Prabir Pradhan99987712020-11-10 18:43:05 -08004000 bool needWake;
4001 { // acquire lock
4002 std::scoped_lock _l(mLock);
4003 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
4004 args->enabled);
4005 needWake = enqueueInboundEventLocked(std::move(entry));
4006 } // release lock
4007
4008 if (needWake) {
4009 mLooper->wake();
4010 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004011}
4012
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004013InputEventInjectionResult InputDispatcher::injectInputEvent(
4014 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4015 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004016 if (DEBUG_INBOUND_EVENT_DETAILS) {
4017 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4018 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4019 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4020 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004021 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004022
4023 policyFlags |= POLICY_FLAG_INJECTED;
4024 if (hasInjectionPermission(injectorPid, injectorUid)) {
4025 policyFlags |= POLICY_FLAG_TRUSTED;
4026 }
4027
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004028 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004029 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4030 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4031 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4032 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4033 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004034 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004035 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004036 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004037 }
4038
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004039 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004040 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004041 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004042 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4043 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004044 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004045 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004046 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004047
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004048 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004049 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4050 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4051 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004052 int32_t keyCode = incomingKey.getKeyCode();
4053 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004054 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004055 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004056 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004057 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004058 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4059 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4060 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004061
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004062 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4063 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004064 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004065
4066 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4067 android::base::Timer t;
4068 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4069 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4070 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4071 std::to_string(t.duration().count()).c_str());
4072 }
4073 }
4074
4075 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004076 std::unique_ptr<KeyEntry> injectedEntry =
4077 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004078 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004079 incomingKey.getDisplayId(), policyFlags, action,
4080 flags, keyCode, incomingKey.getScanCode(), metaState,
4081 incomingKey.getRepeatCount(),
4082 incomingKey.getDownTime());
4083 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004084 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004085 }
4086
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004087 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004088 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4089 int32_t action = motionEvent.getAction();
4090 size_t pointerCount = motionEvent.getPointerCount();
4091 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
4092 int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004093 int32_t flags = motionEvent.getFlags();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004094 int32_t displayId = motionEvent.getDisplayId();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004095 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004096 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004097 }
4098
4099 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004100 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004101 android::base::Timer t;
4102 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4103 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4104 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4105 std::to_string(t.duration().count()).c_str());
4106 }
4107 }
4108
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004109 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4110 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4111 }
4112
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004113 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004114 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4115 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004116 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004117 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4118 resolvedDeviceId, motionEvent.getSource(),
4119 motionEvent.getDisplayId(), policyFlags, action,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004120 actionButton, flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004121 motionEvent.getButtonState(),
4122 motionEvent.getClassification(),
4123 motionEvent.getEdgeFlags(),
4124 motionEvent.getXPrecision(),
4125 motionEvent.getYPrecision(),
4126 motionEvent.getRawXCursorPosition(),
4127 motionEvent.getRawYCursorPosition(),
4128 motionEvent.getDownTime(), uint32_t(pointerCount),
4129 pointerProperties, samplePointerCoords,
4130 motionEvent.getXOffset(),
4131 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004132 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004133 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004134 sampleEventTimes += 1;
4135 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004136 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004137 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4138 resolvedDeviceId, motionEvent.getSource(),
4139 motionEvent.getDisplayId(), policyFlags,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004140 action, actionButton, flags,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004141 motionEvent.getMetaState(),
4142 motionEvent.getButtonState(),
4143 motionEvent.getClassification(),
4144 motionEvent.getEdgeFlags(),
4145 motionEvent.getXPrecision(),
4146 motionEvent.getYPrecision(),
4147 motionEvent.getRawXCursorPosition(),
4148 motionEvent.getRawYCursorPosition(),
4149 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004150 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004151 samplePointerCoords, motionEvent.getXOffset(),
4152 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004153 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004154 }
4155 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004156 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004157
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004158 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004159 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004160 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004161 }
4162
4163 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004164 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004165 injectionState->injectionIsAsync = true;
4166 }
4167
4168 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004169 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004170
4171 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004172 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004173 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004174 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004175 }
4176
4177 mLock.unlock();
4178
4179 if (needWake) {
4180 mLooper->wake();
4181 }
4182
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004183 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004184 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004185 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004186
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004187 if (syncMode == InputEventInjectionSync::NONE) {
4188 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004189 } else {
4190 for (;;) {
4191 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004192 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004193 break;
4194 }
4195
4196 nsecs_t remainingTimeout = endTime - now();
4197 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004198 if (DEBUG_INJECTION) {
4199 ALOGD("injectInputEvent - Timed out waiting for injection result "
4200 "to become available.");
4201 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004202 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004203 break;
4204 }
4205
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004206 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004207 }
4208
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004209 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4210 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004211 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004212 if (DEBUG_INJECTION) {
4213 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4214 injectionState->pendingForegroundDispatches);
4215 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004216 nsecs_t remainingTimeout = endTime - now();
4217 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004218 if (DEBUG_INJECTION) {
4219 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4220 "dispatches to finish.");
4221 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004222 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223 break;
4224 }
4225
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004226 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004227 }
4228 }
4229 }
4230
4231 injectionState->release();
4232 } // release lock
4233
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004234 if (DEBUG_INJECTION) {
4235 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4236 injectionResult, injectorPid, injectorUid);
4237 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004238
4239 return injectionResult;
4240}
4241
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004242std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004243 std::array<uint8_t, 32> calculatedHmac;
4244 std::unique_ptr<VerifiedInputEvent> result;
4245 switch (event.getType()) {
4246 case AINPUT_EVENT_TYPE_KEY: {
4247 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4248 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4249 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004250 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004251 break;
4252 }
4253 case AINPUT_EVENT_TYPE_MOTION: {
4254 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4255 VerifiedMotionEvent verifiedMotionEvent =
4256 verifiedMotionEventFromMotionEvent(motionEvent);
4257 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004258 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004259 break;
4260 }
4261 default: {
4262 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4263 return nullptr;
4264 }
4265 }
4266 if (calculatedHmac == INVALID_HMAC) {
4267 return nullptr;
4268 }
4269 if (calculatedHmac != event.getHmac()) {
4270 return nullptr;
4271 }
4272 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004273}
4274
Michael Wrightd02c5b62014-02-10 15:10:22 -08004275bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004276 return injectorUid == 0 ||
4277 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278}
4279
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004280void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004281 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004282 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004283 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004284 if (DEBUG_INJECTION) {
4285 ALOGD("Setting input event injection result to %d. "
4286 "injectorPid=%d, injectorUid=%d",
4287 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4288 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004289
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004290 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004291 // Log the outcome since the injector did not wait for the injection result.
4292 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004293 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004294 ALOGV("Asynchronous input event injection succeeded.");
4295 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004296 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004297 ALOGW("Asynchronous input event injection failed.");
4298 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004299 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004300 ALOGW("Asynchronous input event injection permission denied.");
4301 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004302 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004303 ALOGW("Asynchronous input event injection timed out.");
4304 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004305 case InputEventInjectionResult::PENDING:
4306 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4307 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004308 }
4309 }
4310
4311 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004312 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004313 }
4314}
4315
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004316void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4317 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004318 if (injectionState) {
4319 injectionState->pendingForegroundDispatches += 1;
4320 }
4321}
4322
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004323void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4324 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325 if (injectionState) {
4326 injectionState->pendingForegroundDispatches -= 1;
4327
4328 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004329 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 }
4331 }
4332}
4333
chaviw98318de2021-05-19 16:45:23 -05004334const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004335 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004336 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004337 auto it = mWindowHandlesByDisplay.find(displayId);
4338 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004339}
4340
chaviw98318de2021-05-19 16:45:23 -05004341sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004342 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004343 if (windowHandleToken == nullptr) {
4344 return nullptr;
4345 }
4346
Arthur Hungb92218b2018-08-14 12:00:21 +08004347 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004348 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4349 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004350 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004351 return windowHandle;
4352 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353 }
4354 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004355 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004356}
4357
chaviw98318de2021-05-19 16:45:23 -05004358sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4359 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004360 if (windowHandleToken == nullptr) {
4361 return nullptr;
4362 }
4363
chaviw98318de2021-05-19 16:45:23 -05004364 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004365 if (windowHandle->getToken() == windowHandleToken) {
4366 return windowHandle;
4367 }
4368 }
4369 return nullptr;
4370}
4371
chaviw98318de2021-05-19 16:45:23 -05004372sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4373 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004374 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004375 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4376 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004377 if (handle->getId() == windowHandle->getId() &&
4378 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004379 if (windowHandle->getInfo()->displayId != it.first) {
4380 ALOGE("Found window %s in display %" PRId32
4381 ", but it should belong to display %" PRId32,
4382 windowHandle->getName().c_str(), it.first,
4383 windowHandle->getInfo()->displayId);
4384 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004385 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004386 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004387 }
4388 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004389 return nullptr;
4390}
4391
chaviw98318de2021-05-19 16:45:23 -05004392sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004393 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4394 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004395}
4396
chaviw98318de2021-05-19 16:45:23 -05004397bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004398 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4399 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004400 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004401 if (connection != nullptr && noInputChannel) {
4402 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4403 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4404 return false;
4405 }
4406
4407 if (connection == nullptr) {
4408 if (!noInputChannel) {
4409 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4410 }
4411 return false;
4412 }
4413 if (!connection->responsive) {
4414 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4415 return false;
4416 }
4417 return true;
4418}
4419
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004420std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4421 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004422 auto connectionIt = mConnectionsByToken.find(token);
4423 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004424 return nullptr;
4425 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004426 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004427}
4428
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004429void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004430 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4431 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004432 // Remove all handles on a display if there are no windows left.
4433 mWindowHandlesByDisplay.erase(displayId);
4434 return;
4435 }
4436
4437 // Since we compare the pointer of input window handles across window updates, we need
4438 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004439 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4440 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4441 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004442 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004443 }
4444
chaviw98318de2021-05-19 16:45:23 -05004445 std::vector<sp<WindowInfoHandle>> newHandles;
4446 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004447 if (!handle->updateInfo()) {
4448 // handle no longer valid
4449 continue;
4450 }
4451
chaviw98318de2021-05-19 16:45:23 -05004452 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004453 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004454 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004455 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4456 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4457 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004458 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004459 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004460 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004461 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004462 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004463 }
4464
4465 if (info->displayId != displayId) {
4466 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4467 handle->getName().c_str(), displayId, info->displayId);
4468 continue;
4469 }
4470
Robert Carredd13602020-04-13 17:24:34 -07004471 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4472 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004473 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004474 oldHandle->updateFrom(handle);
4475 newHandles.push_back(oldHandle);
4476 } else {
4477 newHandles.push_back(handle);
4478 }
4479 }
4480
4481 // Insert or replace
4482 mWindowHandlesByDisplay[displayId] = newHandles;
4483}
4484
Arthur Hung72d8dc32020-03-28 00:48:39 +00004485void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004486 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004487 { // acquire lock
4488 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004489 for (const auto& [displayId, handles] : handlesPerDisplay) {
4490 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004491 }
4492 }
4493 // Wake up poll loop since it may need to make new input dispatching choices.
4494 mLooper->wake();
4495}
4496
Arthur Hungb92218b2018-08-14 12:00:21 +08004497/**
4498 * Called from InputManagerService, update window handle list by displayId that can receive input.
4499 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4500 * If set an empty list, remove all handles from the specific display.
4501 * For focused handle, check if need to change and send a cancel event to previous one.
4502 * For removed handle, check if need to send a cancel event if already in touch.
4503 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004504void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004505 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004506 if (DEBUG_FOCUS) {
4507 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004508 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004509 windowList += iwh->getName() + " ";
4510 }
4511 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4512 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004514 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004515 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004516 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004517 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004518 if (noInputWindow && window->getToken() != nullptr) {
4519 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4520 window->getName().c_str());
4521 window->releaseChannel();
4522 }
4523 }
4524
Arthur Hung72d8dc32020-03-28 00:48:39 +00004525 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004526 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004527
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004528 // Save the old windows' orientation by ID before it gets updated.
4529 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004530 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004531 oldWindowOrientations.emplace(handle->getId(),
4532 handle->getInfo()->transform.getOrientation());
4533 }
4534
chaviw98318de2021-05-19 16:45:23 -05004535 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004536
chaviw98318de2021-05-19 16:45:23 -05004537 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004538 if (mLastHoverWindowHandle &&
4539 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4540 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004541 mLastHoverWindowHandle = nullptr;
4542 }
4543
Vishnu Nairc519ff72021-01-21 08:23:08 -08004544 std::optional<FocusResolver::FocusChanges> changes =
4545 mFocusResolver.setInputWindows(displayId, windowHandles);
4546 if (changes) {
4547 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004548 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004549
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004550 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4551 mTouchStatesByDisplay.find(displayId);
4552 if (stateIt != mTouchStatesByDisplay.end()) {
4553 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004554 for (size_t i = 0; i < state.windows.size();) {
4555 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004556 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004557 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004558 ALOGD("Touched window was removed: %s in display %" PRId32,
4559 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004560 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004561 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004562 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4563 if (touchedInputChannel != nullptr) {
4564 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4565 "touched window was removed");
4566 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004568 state.windows.erase(state.windows.begin() + i);
4569 } else {
4570 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571 }
4572 }
arthurhungb89ccb02020-12-30 16:19:01 +08004573
arthurhung6d4bed92021-03-17 11:59:33 +08004574 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004575 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004576 if (mDragState &&
4577 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004578 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004579 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004580 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004581 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004582
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004583 if (isPerWindowInputRotationEnabled()) {
4584 // Determine if the orientation of any of the input windows have changed, and cancel all
4585 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004586 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4587 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004588 if (newWindowHandle != nullptr &&
4589 newWindowHandle->getInfo()->transform.getOrientation() !=
4590 oldWindowOrientations[oldWindowHandle->getId()]) {
4591 std::shared_ptr<InputChannel> inputChannel =
4592 getInputChannelLocked(newWindowHandle->getToken());
4593 if (inputChannel != nullptr) {
4594 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4595 "touched window's orientation changed");
4596 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4597 }
4598 }
4599 }
4600 }
4601
Arthur Hung72d8dc32020-03-28 00:48:39 +00004602 // Release information for windows that are no longer present.
4603 // This ensures that unused input channels are released promptly.
4604 // Otherwise, they might stick around until the window handle is destroyed
4605 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004606 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004607 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004608 if (DEBUG_FOCUS) {
4609 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004610 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004611 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004612 // To avoid making too many calls into the compat framework, only
4613 // check for window flags when windows are going away.
4614 // TODO(b/157929241) : delete this. This is only needed temporarily
4615 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004616 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004617 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4618 oldWindowHandle->getName().c_str());
4619 if (mCompatService != nullptr) {
4620 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4621 oldWindowHandle->getInfo()->ownerUid);
4622 }
4623 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004624 }
chaviw291d88a2019-02-14 10:33:58 -08004625 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004626}
4627
4628void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004629 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004630 if (DEBUG_FOCUS) {
4631 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4632 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4633 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004634 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004635 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004636 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637 } // release lock
4638
4639 // Wake up poll loop since it may need to make new input dispatching choices.
4640 mLooper->wake();
4641}
4642
Vishnu Nair599f1412021-06-21 10:39:58 -07004643void InputDispatcher::setFocusedApplicationLocked(
4644 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4645 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4646 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4647
4648 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4649 return; // This application is already focused. No need to wake up or change anything.
4650 }
4651
4652 // Set the new application handle.
4653 if (inputApplicationHandle != nullptr) {
4654 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4655 } else {
4656 mFocusedApplicationHandlesByDisplay.erase(displayId);
4657 }
4658
4659 // No matter what the old focused application was, stop waiting on it because it is
4660 // no longer focused.
4661 resetNoFocusedWindowTimeoutLocked();
4662}
4663
Tiger Huang721e26f2018-07-24 22:26:19 +08004664/**
4665 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4666 * the display not specified.
4667 *
4668 * We track any unreleased events for each window. If a window loses the ability to receive the
4669 * released event, we will send a cancel event to it. So when the focused display is changed, we
4670 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4671 * display. The display-specified events won't be affected.
4672 */
4673void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004674 if (DEBUG_FOCUS) {
4675 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4676 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004677 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004678 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004679
4680 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004681 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004682 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004683 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004684 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004685 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004686 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004687 CancelationOptions
4688 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4689 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004690 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004691 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4692 }
4693 }
4694 mFocusedDisplayId = displayId;
4695
Chris Ye3c2d6f52020-08-09 10:39:48 -07004696 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004697 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004698 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004699
Vishnu Nairad321cd2020-08-20 16:40:21 -07004700 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004701 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004702 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004703 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004704 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004705 }
4706 }
4707 }
4708
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004709 if (DEBUG_FOCUS) {
4710 logDispatchStateLocked();
4711 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004712 } // release lock
4713
4714 // Wake up poll loop since it may need to make new input dispatching choices.
4715 mLooper->wake();
4716}
4717
Michael Wrightd02c5b62014-02-10 15:10:22 -08004718void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004719 if (DEBUG_FOCUS) {
4720 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4721 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004722
4723 bool changed;
4724 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004725 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004726
4727 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4728 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004729 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004730 }
4731
4732 if (mDispatchEnabled && !enabled) {
4733 resetAndDropEverythingLocked("dispatcher is being disabled");
4734 }
4735
4736 mDispatchEnabled = enabled;
4737 mDispatchFrozen = frozen;
4738 changed = true;
4739 } else {
4740 changed = false;
4741 }
4742
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004743 if (DEBUG_FOCUS) {
4744 logDispatchStateLocked();
4745 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004746 } // release lock
4747
4748 if (changed) {
4749 // Wake up poll loop since it may need to make new input dispatching choices.
4750 mLooper->wake();
4751 }
4752}
4753
4754void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004755 if (DEBUG_FOCUS) {
4756 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4757 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004758
4759 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004760 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004761
4762 if (mInputFilterEnabled == enabled) {
4763 return;
4764 }
4765
4766 mInputFilterEnabled = enabled;
4767 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4768 } // release lock
4769
4770 // Wake up poll loop since there might be work to do to drop everything.
4771 mLooper->wake();
4772}
4773
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004774void InputDispatcher::setInTouchMode(bool inTouchMode) {
4775 std::scoped_lock lock(mLock);
4776 mInTouchMode = inTouchMode;
4777}
4778
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004779void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4780 if (opacity < 0 || opacity > 1) {
4781 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4782 return;
4783 }
4784
4785 std::scoped_lock lock(mLock);
4786 mMaximumObscuringOpacityForTouch = opacity;
4787}
4788
4789void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4790 std::scoped_lock lock(mLock);
4791 mBlockUntrustedTouchesMode = mode;
4792}
4793
arthurhungb89ccb02020-12-30 16:19:01 +08004794bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4795 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004796 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004797 if (DEBUG_FOCUS) {
4798 ALOGD("Trivial transfer to same window.");
4799 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004800 return true;
4801 }
4802
Michael Wrightd02c5b62014-02-10 15:10:22 -08004803 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004804 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004805
chaviw98318de2021-05-19 16:45:23 -05004806 sp<WindowInfoHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4807 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004808 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004809 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004810 return false;
4811 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004812 if (DEBUG_FOCUS) {
4813 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4814 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004817 if (DEBUG_FOCUS) {
4818 ALOGD("Cannot transfer focus because windows are on different displays.");
4819 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004820 return false;
4821 }
4822
4823 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004824 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4825 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004826 for (size_t i = 0; i < state.windows.size(); i++) {
4827 const TouchedWindow& touchedWindow = state.windows[i];
4828 if (touchedWindow.windowHandle == fromWindowHandle) {
4829 int32_t oldTargetFlags = touchedWindow.targetFlags;
4830 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004831
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004832 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004833
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004834 int32_t newTargetFlags = oldTargetFlags &
4835 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4836 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004837 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004838
arthurhungb89ccb02020-12-30 16:19:01 +08004839 // Store the dragging window.
4840 if (isDragDrop) {
arthurhung6d4bed92021-03-17 11:59:33 +08004841 mDragState = std::make_unique<DragState>(toWindowHandle);
arthurhungb89ccb02020-12-30 16:19:01 +08004842 }
4843
Jeff Brownf086ddb2014-02-11 14:28:48 -08004844 found = true;
4845 goto Found;
4846 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004847 }
4848 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004849 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004850
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004851 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004852 if (DEBUG_FOCUS) {
4853 ALOGD("Focus transfer failed because from window did not have focus.");
4854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004855 return false;
4856 }
4857
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004858 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4859 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004860 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004861 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004862 CancelationOptions
4863 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4864 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004865 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004866 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004867 }
4868
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004869 if (DEBUG_FOCUS) {
4870 logDispatchStateLocked();
4871 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004872 } // release lock
4873
4874 // Wake up poll loop since it may need to make new input dispatching choices.
4875 mLooper->wake();
4876 return true;
4877}
4878
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004879// Binder call
4880bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
4881 sp<IBinder> fromToken;
4882 { // acquire lock
4883 std::scoped_lock _l(mLock);
4884
chaviw98318de2021-05-19 16:45:23 -05004885 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004886 if (toWindowHandle == nullptr) {
4887 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
4888 return false;
4889 }
4890
4891 const int32_t displayId = toWindowHandle->getInfo()->displayId;
4892
4893 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
4894 if (touchStateIt == mTouchStatesByDisplay.end()) {
4895 ALOGD("Could not transfer touch because the display %" PRId32 " is not being touched",
4896 displayId);
4897 return false;
4898 }
4899
4900 TouchState& state = touchStateIt->second;
4901 if (state.windows.size() != 1) {
4902 ALOGW("Cannot transfer touch state because there are %zu windows being touched",
4903 state.windows.size());
4904 return false;
4905 }
4906 const TouchedWindow& touchedWindow = state.windows[0];
4907 fromToken = touchedWindow.windowHandle->getToken();
4908 } // release lock
4909
4910 return transferTouchFocus(fromToken, destChannelToken);
4911}
4912
Michael Wrightd02c5b62014-02-10 15:10:22 -08004913void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004914 if (DEBUG_FOCUS) {
4915 ALOGD("Resetting and dropping all events (%s).", reason);
4916 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004917
4918 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4919 synthesizeCancelationEventsForAllConnectionsLocked(options);
4920
4921 resetKeyRepeatLocked();
4922 releasePendingEventLocked();
4923 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004924 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004926 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004927 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004928 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004929 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004930}
4931
4932void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004933 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004934 dumpDispatchStateLocked(dump);
4935
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004936 std::istringstream stream(dump);
4937 std::string line;
4938
4939 while (std::getline(stream, line, '\n')) {
4940 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004941 }
4942}
4943
Prabir Pradhan99987712020-11-10 18:43:05 -08004944std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4945 std::string dump;
4946
4947 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4948 toString(mFocusedWindowRequestedPointerCapture));
4949
4950 std::string windowName = "None";
4951 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05004952 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08004953 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4954 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4955 : "token has capture without window";
4956 }
4957 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4958
4959 return dump;
4960}
4961
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004962void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004963 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4964 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4965 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004966 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004967
Tiger Huang721e26f2018-07-24 22:26:19 +08004968 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4969 dump += StringPrintf(INDENT "FocusedApplications:\n");
4970 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4971 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004972 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004973 const std::chrono::duration timeout =
4974 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004975 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004976 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004977 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004978 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004979 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004980 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004981 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004982
Vishnu Nairc519ff72021-01-21 08:23:08 -08004983 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004984 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004986 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004987 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004988 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4989 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004990 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004991 state.displayId, toString(state.down), toString(state.split),
4992 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004993 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004994 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004995 for (size_t i = 0; i < state.windows.size(); i++) {
4996 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004997 dump += StringPrintf(INDENT4
4998 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4999 i, touchedWindow.windowHandle->getName().c_str(),
5000 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005001 }
5002 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005003 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005004 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005 }
5006 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005007 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005008 }
5009
arthurhung6d4bed92021-03-17 11:59:33 +08005010 if (mDragState) {
5011 dump += StringPrintf(INDENT "DragState:\n");
5012 mDragState->dump(dump, INDENT2);
5013 }
5014
Arthur Hungb92218b2018-08-14 12:00:21 +08005015 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005016 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05005017 const std::vector<sp<WindowInfoHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08005018 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005019 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005020 dump += INDENT2 "Windows:\n";
5021 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005022 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5023 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005024
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005025 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005026 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005027 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005028 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005029 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005030 "applicationInfo.name=%s, "
5031 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005032 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005033 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005034 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005035 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005036 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005037 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005038 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005039 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005040 windowInfo->frameLeft, windowInfo->frameTop,
5041 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005042 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005043 windowInfo->applicationInfo.name.c_str(),
5044 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005045 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005046 dump += StringPrintf(", inputFeatures=%s",
5047 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005048 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005049 "ms, trustedOverlay=%s, hasToken=%s, "
5050 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005051 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005052 millis(windowInfo->dispatchingTimeout),
5053 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005054 toString(windowInfo->token != nullptr),
5055 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005056 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005057 }
5058 } else {
5059 dump += INDENT2 "Windows: <none>\n";
5060 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005061 }
5062 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005063 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005064 }
5065
Michael Wright3dd60e22019-03-27 22:06:44 +00005066 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005067 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005068 const std::vector<Monitor>& monitors = it.second;
5069 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5070 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005071 }
5072 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005073 const std::vector<Monitor>& monitors = it.second;
5074 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5075 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005076 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005078 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005079 }
5080
5081 nsecs_t currentTime = now();
5082
5083 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005084 if (!mRecentQueue.empty()) {
5085 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005086 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005087 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005088 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005089 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005090 }
5091 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005092 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005093 }
5094
5095 // Dump event currently being dispatched.
5096 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005097 dump += INDENT "PendingEvent:\n";
5098 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005099 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005100 dump += StringPrintf(", age=%" PRId64 "ms\n",
5101 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005102 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005103 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005104 }
5105
5106 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005107 if (!mInboundQueue.empty()) {
5108 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005109 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005110 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005111 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005112 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005113 }
5114 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005115 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005116 }
5117
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005118 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005119 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005120 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5121 const KeyReplacement& replacement = pair.first;
5122 int32_t newKeyCode = pair.second;
5123 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005124 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005125 }
5126 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005127 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005128 }
5129
Prabir Pradhancef936d2021-07-21 16:17:52 +00005130 if (!mCommandQueue.empty()) {
5131 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5132 } else {
5133 dump += INDENT "CommandQueue: <empty>\n";
5134 }
5135
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005136 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005137 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005138 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005139 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005140 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005141 connection->inputChannel->getFd().get(),
5142 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005143 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005144 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005145
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005146 if (!connection->outboundQueue.empty()) {
5147 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5148 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005149 dump += dumpQueue(connection->outboundQueue, currentTime);
5150
Michael Wrightd02c5b62014-02-10 15:10:22 -08005151 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005152 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005153 }
5154
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005155 if (!connection->waitQueue.empty()) {
5156 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5157 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005158 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005159 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005160 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005161 }
5162 }
5163 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005164 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005165 }
5166
5167 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005168 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5169 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005170 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005171 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005172 }
5173
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005174 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005175 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5176 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5177 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005178 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005179 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005180}
5181
Michael Wright3dd60e22019-03-27 22:06:44 +00005182void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5183 const size_t numMonitors = monitors.size();
5184 for (size_t i = 0; i < numMonitors; i++) {
5185 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005186 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005187 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5188 dump += "\n";
5189 }
5190}
5191
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005192class LooperEventCallback : public LooperCallback {
5193public:
5194 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5195 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5196
5197private:
5198 std::function<int(int events)> mCallback;
5199};
5200
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005201Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005202 if (DEBUG_CHANNEL_CREATION) {
5203 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5204 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005205
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005206 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005207 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005208 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005209
5210 if (result) {
5211 return base::Error(result) << "Failed to open input channel pair with name " << name;
5212 }
5213
Michael Wrightd02c5b62014-02-10 15:10:22 -08005214 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005215 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005216 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005217 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005218 sp<Connection> connection =
5219 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005220
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005221 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5222 ALOGE("Created a new connection, but the token %p is already known", token.get());
5223 }
5224 mConnectionsByToken.emplace(token, connection);
5225
5226 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5227 this, std::placeholders::_1, token);
5228
5229 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005230 } // release lock
5231
5232 // Wake the looper because some connections have changed.
5233 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005234 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005235}
5236
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005237Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5238 bool isGestureMonitor,
5239 const std::string& name,
5240 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005241 std::shared_ptr<InputChannel> serverChannel;
5242 std::unique_ptr<InputChannel> clientChannel;
5243 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5244 if (result) {
5245 return base::Error(result) << "Failed to open input channel pair with name " << name;
5246 }
5247
Michael Wright3dd60e22019-03-27 22:06:44 +00005248 { // acquire lock
5249 std::scoped_lock _l(mLock);
5250
5251 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005252 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5253 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005254 }
5255
Garfield Tan15601662020-09-22 15:32:38 -07005256 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005257 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005258 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005259
5260 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5261 ALOGE("Created a new connection, but the token %p is already known", token.get());
5262 }
5263 mConnectionsByToken.emplace(token, connection);
5264 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5265 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005266
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005267 auto& monitorsByDisplay =
5268 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005269 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005270
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005271 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005272 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5273 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005274 }
Garfield Tan15601662020-09-22 15:32:38 -07005275
Michael Wright3dd60e22019-03-27 22:06:44 +00005276 // Wake the looper because some connections have changed.
5277 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005278 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005279}
5280
Garfield Tan15601662020-09-22 15:32:38 -07005281status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005282 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005283 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005284
Garfield Tan15601662020-09-22 15:32:38 -07005285 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005286 if (status) {
5287 return status;
5288 }
5289 } // release lock
5290
5291 // Wake the poll loop because removing the connection may have changed the current
5292 // synchronization state.
5293 mLooper->wake();
5294 return OK;
5295}
5296
Garfield Tan15601662020-09-22 15:32:38 -07005297status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5298 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005299 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005300 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005301 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005302 return BAD_VALUE;
5303 }
5304
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005305 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005306
Michael Wrightd02c5b62014-02-10 15:10:22 -08005307 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005308 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005309 }
5310
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005311 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312
5313 nsecs_t currentTime = now();
5314 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5315
5316 connection->status = Connection::STATUS_ZOMBIE;
5317 return OK;
5318}
5319
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005320void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5321 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5322 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005323}
5324
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005325void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005326 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005327 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005328 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005329 std::vector<Monitor>& monitors = it->second;
5330 const size_t numMonitors = monitors.size();
5331 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005332 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005333 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5334 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005335 monitors.erase(monitors.begin() + i);
5336 break;
5337 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005338 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005339 if (monitors.empty()) {
5340 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005341 } else {
5342 ++it;
5343 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005344 }
5345}
5346
Michael Wright3dd60e22019-03-27 22:06:44 +00005347status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5348 { // acquire lock
5349 std::scoped_lock _l(mLock);
5350 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5351
5352 if (!foundDisplayId) {
5353 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5354 return BAD_VALUE;
5355 }
5356 int32_t displayId = foundDisplayId.value();
5357
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005358 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5359 mTouchStatesByDisplay.find(displayId);
5360 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005361 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5362 return BAD_VALUE;
5363 }
5364
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005365 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005366 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005367 std::optional<int32_t> foundDeviceId;
5368 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005369 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005370 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005371 foundDeviceId = state.deviceId;
5372 }
5373 }
5374 if (!foundDeviceId || !state.down) {
5375 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005376 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005377 return BAD_VALUE;
5378 }
5379 int32_t deviceId = foundDeviceId.value();
5380
5381 // Send cancel events to all the input channels we're stealing from.
5382 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005383 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005384 options.deviceId = deviceId;
5385 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005386 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005387 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005388 std::shared_ptr<InputChannel> channel =
5389 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005390 if (channel != nullptr) {
5391 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005392 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005393 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005394 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005395 canceledWindows += "]";
5396 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5397 canceledWindows.c_str());
5398
Michael Wright3dd60e22019-03-27 22:06:44 +00005399 // Then clear the current touch state so we stop dispatching to them as well.
5400 state.filterNonMonitors();
5401 }
5402 return OK;
5403}
5404
Prabir Pradhan99987712020-11-10 18:43:05 -08005405void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5406 { // acquire lock
5407 std::scoped_lock _l(mLock);
5408 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005409 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005410 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5411 windowHandle != nullptr ? windowHandle->getName().c_str()
5412 : "token without window");
5413 }
5414
Vishnu Nairc519ff72021-01-21 08:23:08 -08005415 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005416 if (focusedToken != windowToken) {
5417 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5418 enabled ? "enable" : "disable");
5419 return;
5420 }
5421
5422 if (enabled == mFocusedWindowRequestedPointerCapture) {
5423 ALOGW("Ignoring request to %s Pointer Capture: "
5424 "window has %s requested pointer capture.",
5425 enabled ? "enable" : "disable", enabled ? "already" : "not");
5426 return;
5427 }
5428
5429 mFocusedWindowRequestedPointerCapture = enabled;
5430 setPointerCaptureLocked(enabled);
5431 } // release lock
5432
5433 // Wake the thread to process command entries.
5434 mLooper->wake();
5435}
5436
Michael Wright3dd60e22019-03-27 22:06:44 +00005437std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5438 const sp<IBinder>& token) {
5439 for (const auto& it : mGestureMonitorsByDisplay) {
5440 const std::vector<Monitor>& monitors = it.second;
5441 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005442 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005443 return it.first;
5444 }
5445 }
5446 }
5447 return std::nullopt;
5448}
5449
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005450std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5451 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5452 if (gesturePid.has_value()) {
5453 return gesturePid;
5454 }
5455 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5456}
5457
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005458sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005459 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005460 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005461 }
5462
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005463 for (const auto& [token, connection] : mConnectionsByToken) {
5464 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005465 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005466 }
5467 }
Robert Carr4e670e52018-08-15 13:26:12 -07005468
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005469 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005470}
5471
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005472std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5473 sp<Connection> connection = getConnectionLocked(connectionToken);
5474 if (connection == nullptr) {
5475 return "<nullptr>";
5476 }
5477 return connection->getInputChannelName();
5478}
5479
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005480void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005481 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005482 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005483}
5484
Prabir Pradhancef936d2021-07-21 16:17:52 +00005485void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5486 const sp<Connection>& connection, uint32_t seq,
5487 bool handled, nsecs_t consumeTime) {
5488 // Handle post-event policy actions.
5489 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5490 if (dispatchEntryIt == connection->waitQueue.end()) {
5491 return;
5492 }
5493 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5494 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5495 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5496 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5497 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5498 }
5499 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5500 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5501 connection->inputChannel->getConnectionToken(),
5502 dispatchEntry->deliveryTime, consumeTime, finishTime);
5503 }
5504
5505 bool restartEvent;
5506 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5507 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5508 restartEvent =
5509 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5510 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5511 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5512 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5513 handled);
5514 } else {
5515 restartEvent = false;
5516 }
5517
5518 // Dequeue the event and start the next cycle.
5519 // Because the lock might have been released, it is possible that the
5520 // contents of the wait queue to have been drained, so we need to double-check
5521 // a few things.
5522 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5523 if (dispatchEntryIt != connection->waitQueue.end()) {
5524 dispatchEntry = *dispatchEntryIt;
5525 connection->waitQueue.erase(dispatchEntryIt);
5526 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5527 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5528 if (!connection->responsive) {
5529 connection->responsive = isConnectionResponsive(*connection);
5530 if (connection->responsive) {
5531 // The connection was unresponsive, and now it's responsive.
5532 processConnectionResponsiveLocked(*connection);
5533 }
5534 }
5535 traceWaitQueueLength(*connection);
5536 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5537 connection->outboundQueue.push_front(dispatchEntry);
5538 traceOutboundQueueLength(*connection);
5539 } else {
5540 releaseDispatchEntry(dispatchEntry);
5541 }
5542 }
5543
5544 // Start the next dispatch cycle for this connection.
5545 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005546}
5547
Prabir Pradhancef936d2021-07-21 16:17:52 +00005548void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5549 const sp<IBinder>& newToken) {
5550 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5551 scoped_unlock unlock(mLock);
5552 mPolicy->notifyFocusChanged(oldToken, newToken);
5553 };
5554 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005555}
5556
Prabir Pradhancef936d2021-07-21 16:17:52 +00005557void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5558 auto command = [this, token, x, y]() REQUIRES(mLock) {
5559 scoped_unlock unlock(mLock);
5560 mPolicy->notifyDropWindow(token, x, y);
5561 };
5562 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005563}
5564
Prabir Pradhancef936d2021-07-21 16:17:52 +00005565void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5566 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5567 scoped_unlock unlock(mLock);
5568 mPolicy->notifyUntrustedTouch(obscuringPackage);
5569 };
5570 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005571}
5572
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005573void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5574 if (connection == nullptr) {
5575 LOG_ALWAYS_FATAL("Caller must check for nullness");
5576 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005577 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5578 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005579 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005580 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005581 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005582 return;
5583 }
5584 /**
5585 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5586 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5587 * has changed. This could cause newer entries to time out before the already dispatched
5588 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5589 * processes the events linearly. So providing information about the oldest entry seems to be
5590 * most useful.
5591 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005592 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005593 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5594 std::string reason =
5595 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005596 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005597 ns2ms(currentWait),
5598 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005599 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005600 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005601
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005602 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5603
5604 // Stop waking up for events on this connection, it is already unresponsive
5605 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005606}
5607
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005608void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5609 std::string reason =
5610 StringPrintf("%s does not have a focused window", application->getName().c_str());
5611 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005612
Prabir Pradhancef936d2021-07-21 16:17:52 +00005613 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5614 scoped_unlock unlock(mLock);
5615 mPolicy->notifyNoFocusedWindowAnr(application);
5616 };
5617 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005618}
5619
chaviw98318de2021-05-19 16:45:23 -05005620void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005621 const std::string& reason) {
5622 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5623 updateLastAnrStateLocked(windowLabel, reason);
5624}
5625
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005626void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5627 const std::string& reason) {
5628 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005629 updateLastAnrStateLocked(windowLabel, reason);
5630}
5631
5632void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5633 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005634 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005635 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005636 struct tm tm;
5637 localtime_r(&t, &tm);
5638 char timestr[64];
5639 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005640 mLastAnrState.clear();
5641 mLastAnrState += INDENT "ANR:\n";
5642 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005643 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5644 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005645 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005646}
5647
Prabir Pradhancef936d2021-07-21 16:17:52 +00005648void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5649 KeyEntry& entry) {
5650 const KeyEvent event = createKeyEvent(entry);
5651 nsecs_t delay = 0;
5652 { // release lock
5653 scoped_unlock unlock(mLock);
5654 android::base::Timer t;
5655 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5656 entry.policyFlags);
5657 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5658 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5659 std::to_string(t.duration().count()).c_str());
5660 }
5661 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005662
5663 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005664 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005665 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005666 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005667 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005668 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5669 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005670 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005671}
5672
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005673void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005674 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5675 scoped_unlock unlock(mLock);
5676 mPolicy->notifyMonitorUnresponsive(pid, reason);
5677 };
5678 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005679}
5680
Prabir Pradhancef936d2021-07-21 16:17:52 +00005681void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005682 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005683 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5684 scoped_unlock unlock(mLock);
5685 mPolicy->notifyWindowUnresponsive(token, reason);
5686 };
5687 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005688}
5689
5690void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005691 auto command = [this, pid]() REQUIRES(mLock) {
5692 scoped_unlock unlock(mLock);
5693 mPolicy->notifyMonitorResponsive(pid);
5694 };
5695 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005696}
5697
Prabir Pradhancef936d2021-07-21 16:17:52 +00005698void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5699 auto command = [this, connectionToken]() REQUIRES(mLock) {
5700 scoped_unlock unlock(mLock);
5701 mPolicy->notifyWindowResponsive(connectionToken);
5702 };
5703 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005704}
5705
5706/**
5707 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5708 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5709 * command entry to the command queue.
5710 */
5711void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5712 std::string reason) {
5713 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5714 if (connection.monitor) {
5715 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5716 reason.c_str());
5717 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5718 if (!pid.has_value()) {
5719 ALOGE("Could not find unresponsive monitor for connection %s",
5720 connection.inputChannel->getName().c_str());
5721 return;
5722 }
5723 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5724 return;
5725 }
5726 // If not a monitor, must be a window
5727 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5728 reason.c_str());
5729 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5730}
5731
5732/**
5733 * Tell the policy that a connection has become responsive so that it can stop ANR.
5734 */
5735void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5736 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5737 if (connection.monitor) {
5738 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5739 if (!pid.has_value()) {
5740 ALOGE("Could not find responsive monitor for connection %s",
5741 connection.inputChannel->getName().c_str());
5742 return;
5743 }
5744 sendMonitorResponsiveCommandLocked(pid.value());
5745 return;
5746 }
5747 // If not a monitor, must be a window
5748 sendWindowResponsiveCommandLocked(connectionToken);
5749}
5750
Prabir Pradhancef936d2021-07-21 16:17:52 +00005751bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005752 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005753 KeyEntry& keyEntry, bool handled) {
5754 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005755 if (!handled) {
5756 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005757 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005758 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005759 return false;
5760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005761
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005762 // Get the fallback key state.
5763 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005764 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005765 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005766 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005767 connection->inputState.removeFallbackKey(originalKeyCode);
5768 }
5769
5770 if (handled || !dispatchEntry->hasForegroundTarget()) {
5771 // If the application handles the original key for which we previously
5772 // generated a fallback or if the window is not a foreground window,
5773 // then cancel the associated fallback key, if any.
5774 if (fallbackKeyCode != -1) {
5775 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005776 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5777 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5778 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5779 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5780 keyEntry.policyFlags);
5781 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005782 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005783 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005784
5785 mLock.unlock();
5786
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005787 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005788 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005789
5790 mLock.lock();
5791
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005792 // Cancel the fallback key.
5793 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005794 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005795 "application handled the original non-fallback key "
5796 "or is no longer a foreground target, "
5797 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798 options.keyCode = fallbackKeyCode;
5799 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005800 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005801 connection->inputState.removeFallbackKey(originalKeyCode);
5802 }
5803 } else {
5804 // If the application did not handle a non-fallback key, first check
5805 // that we are in a good state to perform unhandled key event processing
5806 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005807 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005808 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005809 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5810 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5811 "since this is not an initial down. "
5812 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5813 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5814 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005815 return false;
5816 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005817
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005818 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005819 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5820 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5821 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5822 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5823 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005824 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005825
5826 mLock.unlock();
5827
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005828 bool fallback =
5829 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005830 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005831
5832 mLock.lock();
5833
5834 if (connection->status != Connection::STATUS_NORMAL) {
5835 connection->inputState.removeFallbackKey(originalKeyCode);
5836 return false;
5837 }
5838
5839 // Latch the fallback keycode for this key on an initial down.
5840 // The fallback keycode cannot change at any other point in the lifecycle.
5841 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005842 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005843 fallbackKeyCode = event.getKeyCode();
5844 } else {
5845 fallbackKeyCode = AKEYCODE_UNKNOWN;
5846 }
5847 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5848 }
5849
5850 ALOG_ASSERT(fallbackKeyCode != -1);
5851
5852 // Cancel the fallback key if the policy decides not to send it anymore.
5853 // We will continue to dispatch the key to the policy but we will no
5854 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005855 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5856 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005857 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5858 if (fallback) {
5859 ALOGD("Unhandled key event: Policy requested to send key %d"
5860 "as a fallback for %d, but on the DOWN it had requested "
5861 "to send %d instead. Fallback canceled.",
5862 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
5863 } else {
5864 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
5865 "but on the DOWN it had requested to send %d. "
5866 "Fallback canceled.",
5867 originalKeyCode, fallbackKeyCode);
5868 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005869 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005870
5871 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5872 "canceling fallback, policy no longer desires it");
5873 options.keyCode = fallbackKeyCode;
5874 synthesizeCancelationEventsForConnectionLocked(connection, options);
5875
5876 fallback = false;
5877 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005878 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005879 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005880 }
5881 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005882
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005883 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5884 {
5885 std::string msg;
5886 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5887 connection->inputState.getFallbackKeys();
5888 for (size_t i = 0; i < fallbackKeys.size(); i++) {
5889 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
5890 }
5891 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
5892 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005893 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005894 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005895
5896 if (fallback) {
5897 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005898 keyEntry.eventTime = event.getEventTime();
5899 keyEntry.deviceId = event.getDeviceId();
5900 keyEntry.source = event.getSource();
5901 keyEntry.displayId = event.getDisplayId();
5902 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5903 keyEntry.keyCode = fallbackKeyCode;
5904 keyEntry.scanCode = event.getScanCode();
5905 keyEntry.metaState = event.getMetaState();
5906 keyEntry.repeatCount = event.getRepeatCount();
5907 keyEntry.downTime = event.getDownTime();
5908 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005909
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005910 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5911 ALOGD("Unhandled key event: Dispatching fallback key. "
5912 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
5913 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
5914 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005915 return true; // restart the event
5916 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005917 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5918 ALOGD("Unhandled key event: No fallback key.");
5919 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005920
5921 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005922 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005923 }
5924 }
5925 return false;
5926}
5927
Prabir Pradhancef936d2021-07-21 16:17:52 +00005928bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005929 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005930 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005931 return false;
5932}
5933
Michael Wrightd02c5b62014-02-10 15:10:22 -08005934void InputDispatcher::traceInboundQueueLengthLocked() {
5935 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005936 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005937 }
5938}
5939
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005940void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005941 if (ATRACE_ENABLED()) {
5942 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005943 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
5944 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005945 }
5946}
5947
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005948void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005949 if (ATRACE_ENABLED()) {
5950 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005951 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
5952 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005953 }
5954}
5955
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005956void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005957 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005958
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005959 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005960 dumpDispatchStateLocked(dump);
5961
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005962 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005963 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005964 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005965 }
5966}
5967
5968void InputDispatcher::monitor() {
5969 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005970 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005971 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005972 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005973}
5974
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005975/**
5976 * Wake up the dispatcher and wait until it processes all events and commands.
5977 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5978 * this method can be safely called from any thread, as long as you've ensured that
5979 * the work you are interested in completing has already been queued.
5980 */
5981bool InputDispatcher::waitForIdle() {
5982 /**
5983 * Timeout should represent the longest possible time that a device might spend processing
5984 * events and commands.
5985 */
5986 constexpr std::chrono::duration TIMEOUT = 100ms;
5987 std::unique_lock lock(mLock);
5988 mLooper->wake();
5989 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5990 return result == std::cv_status::no_timeout;
5991}
5992
Vishnu Naire798b472020-07-23 13:52:21 -07005993/**
5994 * Sets focus to the window identified by the token. This must be called
5995 * after updating any input window handles.
5996 *
5997 * Params:
5998 * request.token - input channel token used to identify the window that should gain focus.
5999 * request.focusedToken - the token that the caller expects currently to be focused. If the
6000 * specified token does not match the currently focused window, this request will be dropped.
6001 * If the specified focused token matches the currently focused window, the call will succeed.
6002 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6003 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6004 * when requesting the focus change. This determines which request gets
6005 * precedence if there is a focus change request from another source such as pointer down.
6006 */
Vishnu Nair958da932020-08-21 17:12:37 -07006007void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6008 { // acquire lock
6009 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006010 std::optional<FocusResolver::FocusChanges> changes =
6011 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6012 if (changes) {
6013 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006014 }
6015 } // release lock
6016 // Wake up poll loop since it may need to make new input dispatching choices.
6017 mLooper->wake();
6018}
6019
Vishnu Nairc519ff72021-01-21 08:23:08 -08006020void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6021 if (changes.oldFocus) {
6022 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006023 if (focusedInputChannel) {
6024 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6025 "focus left window");
6026 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006027 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006028 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006029 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006030 if (changes.newFocus) {
6031 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006032 }
6033
Prabir Pradhan99987712020-11-10 18:43:05 -08006034 // If a window has pointer capture, then it must have focus. We need to ensure that this
6035 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6036 // If the window loses focus before it loses pointer capture, then the window can be in a state
6037 // where it has pointer capture but not focus, violating the contract. Therefore we must
6038 // dispatch the pointer capture event before the focus event. Since focus events are added to
6039 // the front of the queue (above), we add the pointer capture event to the front of the queue
6040 // after the focus events are added. This ensures the pointer capture event ends up at the
6041 // front.
6042 disablePointerCaptureForcedLocked();
6043
Vishnu Nairc519ff72021-01-21 08:23:08 -08006044 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006045 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006046 }
6047}
Vishnu Nair958da932020-08-21 17:12:37 -07006048
Prabir Pradhan99987712020-11-10 18:43:05 -08006049void InputDispatcher::disablePointerCaptureForcedLocked() {
6050 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
6051 return;
6052 }
6053
6054 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6055
6056 if (mFocusedWindowRequestedPointerCapture) {
6057 mFocusedWindowRequestedPointerCapture = false;
6058 setPointerCaptureLocked(false);
6059 }
6060
6061 if (!mWindowTokenWithPointerCapture) {
6062 // No need to send capture changes because no window has capture.
6063 return;
6064 }
6065
6066 if (mPendingEvent != nullptr) {
6067 // Move the pending event to the front of the queue. This will give the chance
6068 // for the pending event to be dropped if it is a captured event.
6069 mInboundQueue.push_front(mPendingEvent);
6070 mPendingEvent = nullptr;
6071 }
6072
6073 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
6074 false /* hasCapture */);
6075 mInboundQueue.push_front(std::move(entry));
6076}
6077
Prabir Pradhan99987712020-11-10 18:43:05 -08006078void InputDispatcher::setPointerCaptureLocked(bool enabled) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006079 auto command = [this, enabled]() REQUIRES(mLock) {
6080 scoped_unlock unlock(mLock);
6081 mPolicy->setPointerCapture(enabled);
6082 };
6083 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006084}
6085
Vishnu Nair599f1412021-06-21 10:39:58 -07006086void InputDispatcher::displayRemoved(int32_t displayId) {
6087 { // acquire lock
6088 std::scoped_lock _l(mLock);
6089 // Set an empty list to remove all handles from the specific display.
6090 setInputWindowsLocked(/* window handles */ {}, displayId);
6091 setFocusedApplicationLocked(displayId, nullptr);
6092 // Call focus resolver to clean up stale requests. This must be called after input windows
6093 // have been removed for the removed display.
6094 mFocusResolver.displayRemoved(displayId);
6095 } // release lock
6096
6097 // Wake up poll loop since it may need to make new input dispatching choices.
6098 mLooper->wake();
6099}
6100
Garfield Tane84e6f92019-08-29 17:28:41 -07006101} // namespace android::inputdispatcher