blob: 84f5a185d1f535689b11f55ed63083d792208960 [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>
chaviw15fab6f2021-06-07 14:15:52 -050030#include <gui/SurfaceComposerClient.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080031#include <input/InputDevice.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070032#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000033#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070034#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010035#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070036#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080037
Michael Wright44753b12020-07-08 13:48:11 +010038#include <cerrno>
39#include <cinttypes>
40#include <climits>
41#include <cstddef>
42#include <ctime>
43#include <queue>
44#include <sstream>
45
46#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070047#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010048
Michael Wrightd02c5b62014-02-10 15:10:22 -080049#define INDENT " "
50#define INDENT2 " "
51#define INDENT3 " "
52#define INDENT4 " "
53
Peter Collingbourneb04b9b82021-02-08 12:09:47 -080054using android::base::HwTimeoutMultiplier;
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +000055using android::base::Result;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080056using android::base::StringPrintf;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -070057using android::gui::DisplayInfo;
chaviw98318de2021-05-19 16:45:23 -050058using android::gui::FocusRequest;
59using android::gui::TouchOcclusionMode;
60using android::gui::WindowInfo;
61using android::gui::WindowInfoHandle;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080062using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100063using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080064using android::os::InputEventInjectionResult;
65using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100066using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080067
Garfield Tane84e6f92019-08-29 17:28:41 -070068namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080069
Prabir Pradhancef936d2021-07-21 16:17:52 +000070namespace {
71
Prabir Pradhan61a5d242021-07-26 16:41:09 +000072// Log detailed debug messages about each inbound event notification to the dispatcher.
73constexpr bool DEBUG_INBOUND_EVENT_DETAILS = false;
74
75// Log detailed debug messages about each outbound event processed by the dispatcher.
76constexpr bool DEBUG_OUTBOUND_EVENT_DETAILS = false;
77
78// Log debug messages about the dispatch cycle.
79constexpr bool DEBUG_DISPATCH_CYCLE = false;
80
81// Log debug messages about channel creation
82constexpr bool DEBUG_CHANNEL_CREATION = false;
83
84// Log debug messages about input event injection.
85constexpr bool DEBUG_INJECTION = false;
86
87// Log debug messages about input focus tracking.
88constexpr bool DEBUG_FOCUS = false;
89
90// Log debug messages about touch occlusion
91// STOPSHIP(b/169067926): Set to false
92constexpr bool DEBUG_TOUCH_OCCLUSION = true;
93
94// Log debug messages about the app switch latency optimization.
95constexpr bool DEBUG_APP_SWITCH = false;
96
97// Log debug messages about hover events.
98constexpr bool DEBUG_HOVER = false;
99
Prabir Pradhancef936d2021-07-21 16:17:52 +0000100// Temporarily releases a held mutex for the lifetime of the instance.
101// Named to match std::scoped_lock
102class scoped_unlock {
103public:
104 explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
105 ~scoped_unlock() { mMutex.lock(); }
106
107private:
108 std::mutex& mMutex;
109};
110
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700111// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display
112// coordinates and SurfaceFlinger includes the display rotation in the input window transforms.
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000113bool isPerWindowInputRotationEnabled() {
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700114 static const bool PER_WINDOW_INPUT_ROTATION =
Vadim Tryshev7719c7d2021-08-27 17:28:43 +0000115 sysprop::InputFlingerProperties::per_window_input_rotation().value_or(false);
Prabir Pradhand2c9e8e2021-05-24 15:00:12 -0700116
Prabir Pradhan93a0f912021-04-21 13:47:42 -0700117 return PER_WINDOW_INPUT_ROTATION;
118}
119
Michael Wrightd02c5b62014-02-10 15:10:22 -0800120// Default input dispatching timeout if there is no focused application or paused window
121// from which to determine an appropriate dispatching timeout.
Peter Collingbourneb04b9b82021-02-08 12:09:47 -0800122const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
123 android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
124 HwTimeoutMultiplier());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800125
126// Amount of time to allow for all pending events to be processed when an app switch
127// key is on the way. This is used to preempt input dispatch and drop input events
128// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +0000129constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800130
131// Amount of time to allow for an event to be dispatched (measured since its eventTime)
132// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000133constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800134
Michael Wrightd02c5b62014-02-10 15:10:22 -0800135// 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 +0000136constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
137
138// Log a warning when an interception call takes longer than this to process.
139constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800140
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700141// Additional key latency in case a connection is still processing some motion events.
142// This will help with the case when a user touched a button that opens a new window,
143// and gives us the chance to dispatch the key to this new window.
144constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
145
Michael Wrightd02c5b62014-02-10 15:10:22 -0800146// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000147constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
148
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000149// Event log tags. See EventLogTags.logtags for reference
150constexpr int LOGTAG_INPUT_INTERACTION = 62000;
151constexpr int LOGTAG_INPUT_FOCUS = 62001;
152
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000153inline nsecs_t now() {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154 return systemTime(SYSTEM_TIME_MONOTONIC);
155}
156
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000157inline const char* toString(bool value) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800158 return value ? "true" : "false";
159}
160
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000161inline const std::string toString(const sp<IBinder>& binder) {
Bernardo Rufino49d99e42021-01-18 15:16:59 +0000162 if (binder == nullptr) {
163 return "<null>";
164 }
165 return StringPrintf("%p", binder.get());
166}
167
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000168inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700169 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
170 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800171}
172
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000173bool isValidKeyAction(int32_t action) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800174 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700175 case AKEY_EVENT_ACTION_DOWN:
176 case AKEY_EVENT_ACTION_UP:
177 return true;
178 default:
179 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800180 }
181}
182
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000183bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700184 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 ALOGE("Key event has invalid action code 0x%x", action);
186 return false;
187 }
188 return true;
189}
190
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000191bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800192 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700193 case AMOTION_EVENT_ACTION_DOWN:
194 case AMOTION_EVENT_ACTION_UP:
195 case AMOTION_EVENT_ACTION_CANCEL:
196 case AMOTION_EVENT_ACTION_MOVE:
197 case AMOTION_EVENT_ACTION_OUTSIDE:
198 case AMOTION_EVENT_ACTION_HOVER_ENTER:
199 case AMOTION_EVENT_ACTION_HOVER_MOVE:
200 case AMOTION_EVENT_ACTION_HOVER_EXIT:
201 case AMOTION_EVENT_ACTION_SCROLL:
202 return true;
203 case AMOTION_EVENT_ACTION_POINTER_DOWN:
204 case AMOTION_EVENT_ACTION_POINTER_UP: {
205 int32_t index = getMotionEventActionPointerIndex(action);
206 return index >= 0 && index < pointerCount;
207 }
208 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
209 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
210 return actionButton != 0;
211 default:
212 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 }
214}
215
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000216int64_t millis(std::chrono::nanoseconds t) {
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500217 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
218}
219
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000220bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
221 const PointerProperties* pointerProperties) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700222 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800223 ALOGE("Motion event has invalid action code 0x%x", action);
224 return false;
225 }
226 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000227 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700228 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229 return false;
230 }
231 BitSet32 pointerIdBits;
232 for (size_t i = 0; i < pointerCount; i++) {
233 int32_t id = pointerProperties[i].id;
234 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700235 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
236 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800237 return false;
238 }
239 if (pointerIdBits.hasBit(id)) {
240 ALOGE("Motion event has duplicate pointer id %d", id);
241 return false;
242 }
243 pointerIdBits.markBit(id);
244 }
245 return true;
246}
247
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000248std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800249 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000250 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800251 }
252
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000253 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800254 bool first = true;
255 Region::const_iterator cur = region.begin();
256 Region::const_iterator const tail = region.end();
257 while (cur != tail) {
258 if (first) {
259 first = false;
260 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800261 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800262 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800263 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800264 cur++;
265 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000266 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800267}
268
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000269std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500270 constexpr size_t maxEntries = 50; // max events to print
271 constexpr size_t skipBegin = maxEntries / 2;
272 const size_t skipEnd = queue.size() - maxEntries / 2;
273 // skip from maxEntries / 2 ... size() - maxEntries/2
274 // only print from 0 .. skipBegin and then from skipEnd .. size()
275
276 std::string dump;
277 for (size_t i = 0; i < queue.size(); i++) {
278 const DispatchEntry& entry = *queue[i];
279 if (i >= skipBegin && i < skipEnd) {
280 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
281 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
282 continue;
283 }
284 dump.append(INDENT4);
285 dump += entry.eventEntry->getDescription();
286 dump += StringPrintf(", seq=%" PRIu32
287 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
288 entry.seq, entry.targetFlags, entry.resolvedAction,
289 ns2ms(currentTime - entry.eventEntry->eventTime));
290 if (entry.deliveryTime != 0) {
291 // This entry was delivered, so add information on how long we've been waiting
292 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
293 }
294 dump.append("\n");
295 }
296 return dump;
297}
298
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700299/**
300 * Find the entry in std::unordered_map by key, and return it.
301 * If the entry is not found, return a default constructed entry.
302 *
303 * Useful when the entries are vectors, since an empty vector will be returned
304 * if the entry is not found.
305 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
306 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700307template <typename K, typename V>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000308V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700309 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700310 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800311}
312
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000313bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
chaviwaf87b3e2019-10-01 16:59:28 -0700314 if (first == second) {
315 return true;
316 }
317
318 if (first == nullptr || second == nullptr) {
319 return false;
320 }
321
322 return first->getToken() == second->getToken();
323}
324
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000325bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
Bernardo Rufino1ff9d592021-01-18 16:58:57 +0000326 if (first == nullptr || second == nullptr) {
327 return false;
328 }
329 return first->applicationInfo.token != nullptr &&
330 first->applicationInfo.token == second->applicationInfo.token;
331}
332
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000333bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800334 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
335}
336
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000337std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
338 std::shared_ptr<EventEntry> eventEntry,
339 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900340 if (eventEntry->type == EventEntry::Type::MOTION) {
341 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
Prabir Pradhan664834b2021-05-20 16:00:42 -0700342 if ((motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) ||
343 (motionEntry.source & AINPUT_SOURCE_CLASS_POSITION)) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900344 const ui::Transform identityTransform;
Prabir Pradhan664834b2021-05-20 16:00:42 -0700345 // Use identity transform for joystick and position-based (touchpad) events because they
346 // don't depend on the window transform.
yunho.shinf4a80b82020-11-16 21:13:57 +0900347 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700348 1.0f /*globalScaleFactor*/,
Evan Rosky09576692021-07-01 12:22:09 -0700349 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700350 inputTarget.displaySize);
yunho.shinf4a80b82020-11-16 21:13:57 +0900351 }
352 }
353
chaviw1ff3d1e2020-07-01 15:53:47 -0700354 if (inputTarget.useDefaultPointerTransform()) {
355 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700356 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
Evan Rosky84f07f02021-04-16 10:42:42 -0700357 inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700358 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700359 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000360 }
361
362 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
363 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
364
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700365 std::vector<PointerCoords> pointerCoords;
366 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000367
368 // Use the first pointer information to normalize all other pointers. This could be any pointer
369 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700370 // uses the transform for the normalized pointer.
371 const ui::Transform& firstPointerTransform =
372 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
373 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000374
375 // Iterate through all pointers in the event to normalize against the first.
376 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
377 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
378 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700379 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000380
381 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700382 // First, apply the current pointer's transform to update the coordinates into
383 // window space.
384 pointerCoords[pointerIndex].transform(currTransform);
385 // Next, apply the inverse transform of the normalized coordinates so the
386 // current coordinates are transformed into the normalized coordinate space.
387 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000388 }
389
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700390 std::unique_ptr<MotionEntry> combinedMotionEntry =
391 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
392 motionEntry.deviceId, motionEntry.source,
393 motionEntry.displayId, motionEntry.policyFlags,
394 motionEntry.action, motionEntry.actionButton,
395 motionEntry.flags, motionEntry.metaState,
396 motionEntry.buttonState, motionEntry.classification,
397 motionEntry.edgeFlags, motionEntry.xPrecision,
398 motionEntry.yPrecision, motionEntry.xCursorPosition,
399 motionEntry.yCursorPosition, motionEntry.downTime,
400 motionEntry.pointerCount, motionEntry.pointerProperties,
401 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000402
403 if (motionEntry.injectionState) {
404 combinedMotionEntry->injectionState = motionEntry.injectionState;
405 combinedMotionEntry->injectionState->refCount += 1;
406 }
407
408 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700409 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
Evan Rosky84f07f02021-04-16 10:42:42 -0700410 firstPointerTransform, inputTarget.globalScaleFactor,
Evan Rosky09576692021-07-01 12:22:09 -0700411 inputTarget.displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -0700412 inputTarget.displaySize);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000413 return dispatchEntry;
414}
415
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000416void addGestureMonitors(const std::vector<Monitor>& monitors,
417 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
418 float yOffset = 0) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700419 if (monitors.empty()) {
420 return;
421 }
422 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
423 for (const Monitor& monitor : monitors) {
424 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
425 }
426}
427
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000428status_t openInputChannelPair(const std::string& name, std::shared_ptr<InputChannel>& serverChannel,
429 std::unique_ptr<InputChannel>& clientChannel) {
Garfield Tan15601662020-09-22 15:32:38 -0700430 std::unique_ptr<InputChannel> uniqueServerChannel;
431 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
432
433 serverChannel = std::move(uniqueServerChannel);
434 return result;
435}
436
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500437template <typename T>
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000438bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500439 if (lhs == nullptr && rhs == nullptr) {
440 return true;
441 }
442 if (lhs == nullptr || rhs == nullptr) {
443 return false;
444 }
445 return *lhs == *rhs;
446}
447
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000448sp<IPlatformCompatNative> getCompatService() {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000449 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
450 if (service == nullptr) {
451 ALOGE("Failed to link to compat service");
452 return nullptr;
453 }
454 return interface_cast<IPlatformCompatNative>(service);
455}
456
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000457KeyEvent createKeyEvent(const KeyEntry& entry) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000458 KeyEvent event;
459 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
460 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
461 entry.repeatCount, entry.downTime, entry.eventTime);
462 return event;
463}
464
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000465std::optional<int32_t> findMonitorPidByToken(
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000466 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
467 const sp<IBinder>& token) {
468 for (const auto& it : monitorsByDisplay) {
469 const std::vector<Monitor>& monitors = it.second;
470 for (const Monitor& monitor : monitors) {
471 if (monitor.inputChannel->getConnectionToken() == token) {
472 return monitor.pid;
473 }
474 }
475 }
476 return std::nullopt;
477}
478
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000479bool shouldReportMetricsForConnection(const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000480 // Do not keep track of gesture monitors. They receive every event and would disproportionately
481 // affect the statistics.
482 if (connection.monitor) {
483 return false;
484 }
485 // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
486 if (!connection.responsive) {
487 return false;
488 }
489 return true;
490}
491
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000492bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +0000493 const EventEntry& eventEntry = *dispatchEntry.eventEntry;
494 const int32_t& inputEventId = eventEntry.id;
495 if (inputEventId != dispatchEntry.resolvedEventId) {
496 // Event was transmuted
497 return false;
498 }
499 if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
500 return false;
501 }
502 // Only track latency for events that originated from hardware
503 if (eventEntry.isSynthesized()) {
504 return false;
505 }
506 const EventEntry::Type& inputEventEntryType = eventEntry.type;
507 if (inputEventEntryType == EventEntry::Type::KEY) {
508 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
509 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
510 return false;
511 }
512 } else if (inputEventEntryType == EventEntry::Type::MOTION) {
513 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
514 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
515 motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
516 return false;
517 }
518 } else {
519 // Not a key or a motion
520 return false;
521 }
522 if (!shouldReportMetricsForConnection(connection)) {
523 return false;
524 }
525 return true;
526}
527
Prabir Pradhancef936d2021-07-21 16:17:52 +0000528/**
529 * Connection is responsive if it has no events in the waitQueue that are older than the
530 * current time.
531 */
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000532bool isConnectionResponsive(const Connection& connection) {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000533 const nsecs_t currentTime = now();
534 for (const DispatchEntry* entry : connection.waitQueue) {
535 if (entry->timeoutTime < currentTime) {
536 return false;
537 }
538 }
539 return true;
540}
541
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000542} // namespace
543
Michael Wrightd02c5b62014-02-10 15:10:22 -0800544// --- InputDispatcher ---
545
Garfield Tan00f511d2019-06-12 16:55:40 -0700546InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
547 : mPolicy(policy),
548 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700549 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800550 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700551 mAppSwitchSawKeyDown(false),
552 mAppSwitchDueTime(LONG_LONG_MAX),
553 mNextUnblockedEvent(nullptr),
554 mDispatchEnabled(false),
555 mDispatchFrozen(false),
556 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800557 // mInTouchMode will be initialized by the WindowManager to the default device config.
558 // To avoid leaking stack in case that call never comes, and for tests,
559 // initialize it here anyways.
560 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100561 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000562 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800563 mFocusedWindowRequestedPointerCapture(false),
564 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +0000565 mLatencyAggregator(),
566 mLatencyTracker(&mLatencyAggregator),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000567 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800568 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800569 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800570
Yi Kong9b14ac62018-07-17 13:48:38 -0700571 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800572
573 policy->getDispatcherConfiguration(&mConfig);
574}
575
576InputDispatcher::~InputDispatcher() {
Prabir Pradhancef936d2021-07-21 16:17:52 +0000577 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800578
Prabir Pradhancef936d2021-07-21 16:17:52 +0000579 resetKeyRepeatLocked();
580 releasePendingEventLocked();
581 drainInboundQueueLocked();
582 mCommandQueue.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800583
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +0000584 while (!mConnectionsByToken.empty()) {
585 sp<Connection> connection = mConnectionsByToken.begin()->second;
Prabir Pradhancef936d2021-07-21 16:17:52 +0000586 removeInputChannelLocked(connection->inputChannel->getConnectionToken(),
587 false /* notify */);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800588 }
589}
590
chaviw15fab6f2021-06-07 14:15:52 -0500591void InputDispatcher::onFirstRef() {
592 SurfaceComposerClient::getDefault()->addWindowInfosListener(this);
593}
594
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700595status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700596 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700597 return ALREADY_EXISTS;
598 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700599 mThread = std::make_unique<InputThread>(
600 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
601 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700602}
603
604status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700605 if (mThread && mThread->isCallingThread()) {
606 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700607 return INVALID_OPERATION;
608 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700609 mThread.reset();
610 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700611}
612
Michael Wrightd02c5b62014-02-10 15:10:22 -0800613void InputDispatcher::dispatchOnce() {
614 nsecs_t nextWakeupTime = LONG_LONG_MAX;
615 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800616 std::scoped_lock _l(mLock);
617 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800618
619 // Run a dispatch loop if there are no pending commands.
620 // The dispatch loop might enqueue commands to run afterwards.
621 if (!haveCommandsLocked()) {
622 dispatchOnceInnerLocked(&nextWakeupTime);
623 }
624
625 // Run all pending commands if there are any.
626 // If any commands were run then force the next poll to wake up immediately.
Prabir Pradhancef936d2021-07-21 16:17:52 +0000627 if (runCommandsLockedInterruptable()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800628 nextWakeupTime = LONG_LONG_MIN;
629 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800630
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700631 // If we are still waiting for ack on some events,
632 // we might have to wake up earlier to check if an app is anr'ing.
633 const nsecs_t nextAnrCheck = processAnrsLocked();
634 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
635
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800636 // We are about to enter an infinitely long sleep, because we have no commands or
637 // pending or queued events
638 if (nextWakeupTime == LONG_LONG_MAX) {
639 mDispatcherEnteredIdle.notify_all();
640 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800641 } // release lock
642
643 // Wait for callback or timeout or wake. (make sure we round up, not down)
644 nsecs_t currentTime = now();
645 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
646 mLooper->pollOnce(timeoutMillis);
647}
648
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700649/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500650 * Raise ANR if there is no focused window.
651 * Before the ANR is raised, do a final state check:
652 * 1. The currently focused application must be the same one we are waiting for.
653 * 2. Ensure we still don't have a focused window.
654 */
655void InputDispatcher::processNoFocusedWindowAnrLocked() {
656 // Check if the application that we are waiting for is still focused.
657 std::shared_ptr<InputApplicationHandle> focusedApplication =
658 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
659 if (focusedApplication == nullptr ||
660 focusedApplication->getApplicationToken() !=
661 mAwaitedFocusedApplication->getApplicationToken()) {
662 // Unexpected because we should have reset the ANR timer when focused application changed
663 ALOGE("Waited for a focused window, but focused application has already changed to %s",
664 focusedApplication->getName().c_str());
665 return; // The focused application has changed.
666 }
667
chaviw98318de2021-05-19 16:45:23 -0500668 const sp<WindowInfoHandle>& focusedWindowHandle =
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500669 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
670 if (focusedWindowHandle != nullptr) {
671 return; // We now have a focused window. No need for ANR.
672 }
673 onAnrLocked(mAwaitedFocusedApplication);
674}
675
676/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700677 * Check if any of the connections' wait queues have events that are too old.
678 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
679 * Return the time at which we should wake up next.
680 */
681nsecs_t InputDispatcher::processAnrsLocked() {
682 const nsecs_t currentTime = now();
683 nsecs_t nextAnrCheck = LONG_LONG_MAX;
684 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
685 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
686 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500687 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700688 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500689 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700690 return LONG_LONG_MIN;
691 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500692 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700693 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
694 }
695 }
696
697 // Check if any connection ANRs are due
698 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
699 if (currentTime < nextAnrCheck) { // most likely scenario
700 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
701 }
702
703 // If we reached here, we have an unresponsive connection.
704 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
705 if (connection == nullptr) {
706 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
707 return nextAnrCheck;
708 }
709 connection->responsive = false;
710 // Stop waking up for this unresponsive connection
711 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000712 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700713 return LONG_LONG_MIN;
714}
715
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500716std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
chaviw98318de2021-05-19 16:45:23 -0500717 sp<WindowInfoHandle> window = getWindowHandleLocked(token);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700718 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500719 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700720 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500721 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700722}
723
Michael Wrightd02c5b62014-02-10 15:10:22 -0800724void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
725 nsecs_t currentTime = now();
726
Jeff Browndc5992e2014-04-11 01:27:26 -0700727 // Reset the key repeat timer whenever normal dispatch is suspended while the
728 // device is in a non-interactive state. This is to ensure that we abort a key
729 // repeat if the device is just coming out of sleep.
730 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800731 resetKeyRepeatLocked();
732 }
733
734 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
735 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100736 if (DEBUG_FOCUS) {
737 ALOGD("Dispatch frozen. Waiting some more.");
738 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800739 return;
740 }
741
742 // Optimize latency of app switches.
743 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
744 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
745 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
746 if (mAppSwitchDueTime < *nextWakeupTime) {
747 *nextWakeupTime = mAppSwitchDueTime;
748 }
749
750 // Ready to start a new event.
751 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700752 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700753 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800754 if (isAppSwitchDue) {
755 // The inbound queue is empty so the app switch key we were waiting
756 // for will never arrive. Stop waiting for it.
757 resetPendingAppSwitchLocked(false);
758 isAppSwitchDue = false;
759 }
760
761 // Synthesize a key repeat if appropriate.
762 if (mKeyRepeatState.lastKeyEntry) {
763 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
764 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
765 } else {
766 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
767 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
768 }
769 }
770 }
771
772 // Nothing to do if there is no pending event.
773 if (!mPendingEvent) {
774 return;
775 }
776 } else {
777 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700778 mPendingEvent = mInboundQueue.front();
779 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800780 traceInboundQueueLengthLocked();
781 }
782
783 // Poke user activity for this event.
784 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700785 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800786 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800787 }
788
789 // Now we have an event to dispatch.
790 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700791 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700793 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800794 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700795 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800796 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700797 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 }
799
800 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700801 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800802 }
803
804 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700805 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700806 const ConfigurationChangedEntry& typedEntry =
807 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700808 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700809 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700810 break;
811 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800812
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700813 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700814 const DeviceResetEntry& typedEntry =
815 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700816 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700817 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700818 break;
819 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800820
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100821 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700822 std::shared_ptr<FocusEntry> typedEntry =
823 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100824 dispatchFocusLocked(currentTime, typedEntry);
825 done = true;
826 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
827 break;
828 }
829
Prabir Pradhan99987712020-11-10 18:43:05 -0800830 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
831 const auto typedEntry =
832 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
833 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
834 done = true;
835 break;
836 }
837
arthurhungb89ccb02020-12-30 16:19:01 +0800838 case EventEntry::Type::DRAG: {
839 std::shared_ptr<DragEntry> typedEntry =
840 std::static_pointer_cast<DragEntry>(mPendingEvent);
841 dispatchDragLocked(currentTime, typedEntry);
842 done = true;
843 break;
844 }
845
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700846 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700847 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700848 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700849 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700850 resetPendingAppSwitchLocked(true);
851 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700852 } else if (dropReason == DropReason::NOT_DROPPED) {
853 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700854 }
855 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700856 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700857 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700858 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700859 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
860 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700861 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700862 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700863 break;
864 }
865
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700866 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700867 std::shared_ptr<MotionEntry> motionEntry =
868 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700869 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
870 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800871 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700872 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700873 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700874 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700875 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
876 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700877 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700878 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700879 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880 }
Chris Yef59a2f42020-10-16 12:55:26 -0700881
882 case EventEntry::Type::SENSOR: {
883 std::shared_ptr<SensorEntry> sensorEntry =
884 std::static_pointer_cast<SensorEntry>(mPendingEvent);
885 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
886 dropReason = DropReason::APP_SWITCH;
887 }
888 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
889 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
890 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
891 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
892 dropReason = DropReason::STALE;
893 }
894 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
895 done = true;
896 break;
897 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800898 }
899
900 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700901 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700902 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800903 }
Michael Wright3a981722015-06-10 15:26:13 +0100904 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800905
906 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700907 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800908 }
909}
910
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700911/**
912 * Return true if the events preceding this incoming motion event should be dropped
913 * Return false otherwise (the default behaviour)
914 */
915bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700916 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700917 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700918
919 // Optimize case where the current application is unresponsive and the user
920 // decides to touch a window in a different application.
921 // If the application takes too long to catch up then we drop all events preceding
922 // the touch into the other window.
923 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700924 int32_t displayId = motionEntry.displayId;
925 int32_t x = static_cast<int32_t>(
926 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
927 int32_t y = static_cast<int32_t>(
928 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
chaviw98318de2021-05-19 16:45:23 -0500929 sp<WindowInfoHandle> touchedWindowHandle =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700930 findTouchedWindowAtLocked(displayId, x, y, nullptr);
931 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700932 touchedWindowHandle->getApplicationToken() !=
933 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700934 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700935 ALOGI("Pruning input queue because user touched a different application while waiting "
936 "for %s",
937 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700938 return true;
939 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700940
941 // Alternatively, maybe there's a gesture monitor that could handle this event
Siarhei Vishniakou64452932020-11-06 17:51:32 -0600942 std::vector<TouchedMonitor> gestureMonitors = findTouchedGestureMonitorsLocked(displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700943 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
944 sp<Connection> connection =
945 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000946 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700947 // This monitor could take more input. Drop all events preceding this
948 // event, so that gesture monitor could get a chance to receive the stream
949 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
950 "responsive gesture monitor that may handle the event",
951 mAwaitedFocusedApplication->getName().c_str());
952 return true;
953 }
954 }
955 }
956
957 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
958 // yet been processed by some connections, the dispatcher will wait for these motion
959 // events to be processed before dispatching the key event. This is because these motion events
960 // may cause a new window to be launched, which the user might expect to receive focus.
961 // To prevent waiting forever for such events, just send the key to the currently focused window
962 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
963 ALOGD("Received a new pointer down event, stop waiting for events to process and "
964 "just send the pending key event to the focused window.");
965 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700966 }
967 return false;
968}
969
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700970bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700971 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700972 mInboundQueue.push_back(std::move(newEntry));
973 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800974 traceInboundQueueLengthLocked();
975
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700976 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700977 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700978 // Optimize app switch latency.
979 // If the application takes too long to catch up then we drop all events preceding
980 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700981 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700982 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700983 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700984 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700985 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700986 if (mAppSwitchSawKeyDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +0000987 if (DEBUG_APP_SWITCH) {
988 ALOGD("App switch is pending!");
989 }
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700990 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700991 mAppSwitchSawKeyDown = false;
992 needWake = true;
993 }
994 }
995 }
996 break;
997 }
998
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700999 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001000 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
1001 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001002 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001003 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001005 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001006 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001007 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1008 break;
1009 }
1010 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08001011 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07001012 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08001013 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1014 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001015 // nothing to do
1016 break;
1017 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001018 }
1019
1020 return needWake;
1021}
1022
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001023void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -07001024 // Do not store sensor event in recent queue to avoid flooding the queue.
1025 if (entry->type != EventEntry::Type::SENSOR) {
1026 mRecentQueue.push_back(entry);
1027 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001028 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001029 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001030 }
1031}
1032
chaviw98318de2021-05-19 16:45:23 -05001033sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
1034 int32_t y, TouchState* touchState,
1035 bool addOutsideTargets,
1036 bool ignoreDragWindow) {
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001037 if (addOutsideTargets && touchState == nullptr) {
1038 LOG_ALWAYS_FATAL("Must provide a valid touch state if adding outside targets");
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001039 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001040 // Traverse windows from front to back to find touched window.
chaviw98318de2021-05-19 16:45:23 -05001041 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
1042 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
arthurhung6d4bed92021-03-17 11:59:33 +08001043 if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
arthurhungb89ccb02020-12-30 16:19:01 +08001044 continue;
1045 }
chaviw98318de2021-05-19 16:45:23 -05001046 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +01001048 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001049
1050 if (windowInfo->visible) {
chaviw98318de2021-05-19 16:45:23 -05001051 if (!flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
1052 bool isTouchModal = !flags.test(WindowInfo::Flag::NOT_FOCUSABLE) &&
1053 !flags.test(WindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001054 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
1055 // Found window.
1056 return windowHandle;
1057 }
1058 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001059
chaviw98318de2021-05-19 16:45:23 -05001060 if (addOutsideTargets && flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001061 touchState->addOrUpdateWindow(windowHandle,
1062 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
1063 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001064 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001065 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001066 }
1067 }
Yi Kong9b14ac62018-07-17 13:48:38 -07001068 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001069}
1070
Garfield Tane84e6f92019-08-29 17:28:41 -07001071std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001072 int32_t displayId) const {
Michael Wright3dd60e22019-03-27 22:06:44 +00001073 std::vector<TouchedMonitor> touchedMonitors;
1074
1075 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
1076 addGestureMonitors(monitors, touchedMonitors);
Michael Wright3dd60e22019-03-27 22:06:44 +00001077 return touchedMonitors;
1078}
1079
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001080void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001081 const char* reason;
1082 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001083 case DropReason::POLICY:
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001084 if (DEBUG_INBOUND_EVENT_DETAILS) {
1085 ALOGD("Dropped event because policy consumed it.");
1086 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001087 reason = "inbound event was dropped because the policy consumed it";
1088 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001089 case DropReason::DISABLED:
1090 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001091 ALOGI("Dropped event because input dispatch is disabled.");
1092 }
1093 reason = "inbound event was dropped because input dispatch is disabled";
1094 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001095 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001096 ALOGI("Dropped event because of pending overdue app switch.");
1097 reason = "inbound event was dropped because of pending overdue app switch";
1098 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001099 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001100 ALOGI("Dropped event because the current application is not responding and the user "
1101 "has started interacting with a different application.");
1102 reason = "inbound event was dropped because the current application is not responding "
1103 "and the user has started interacting with a different application";
1104 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001105 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001106 ALOGI("Dropped event because it is stale.");
1107 reason = "inbound event was dropped because it is stale";
1108 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001109 case DropReason::NO_POINTER_CAPTURE:
1110 ALOGI("Dropped event because there is no window with Pointer Capture.");
1111 reason = "inbound event was dropped because there is no window with Pointer Capture";
1112 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001113 case DropReason::NOT_DROPPED: {
1114 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001115 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001116 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 }
1118
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001119 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001120 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001121 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1122 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001123 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001124 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001125 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001126 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1127 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001128 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1129 synthesizeCancelationEventsForAllConnectionsLocked(options);
1130 } else {
1131 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1132 synthesizeCancelationEventsForAllConnectionsLocked(options);
1133 }
1134 break;
1135 }
Chris Yef59a2f42020-10-16 12:55:26 -07001136 case EventEntry::Type::SENSOR: {
1137 break;
1138 }
arthurhungb89ccb02020-12-30 16:19:01 +08001139 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1140 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08001141 break;
1142 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001143 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001144 case EventEntry::Type::CONFIGURATION_CHANGED:
1145 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001146 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001147 break;
1148 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001149 }
1150}
1151
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001152static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001153 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1154 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001155}
1156
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001157bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1158 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1159 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1160 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001161}
1162
1163bool InputDispatcher::isAppSwitchPendingLocked() {
1164 return mAppSwitchDueTime != LONG_LONG_MAX;
1165}
1166
1167void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1168 mAppSwitchDueTime = LONG_LONG_MAX;
1169
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001170 if (DEBUG_APP_SWITCH) {
1171 if (handled) {
1172 ALOGD("App switch has arrived.");
1173 } else {
1174 ALOGD("App switch was abandoned.");
1175 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001176 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001177}
1178
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001180 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001181}
1182
Prabir Pradhancef936d2021-07-21 16:17:52 +00001183bool InputDispatcher::runCommandsLockedInterruptable() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001184 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001185 return false;
1186 }
1187
1188 do {
Prabir Pradhancef936d2021-07-21 16:17:52 +00001189 auto command = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001190 mCommandQueue.pop_front();
Prabir Pradhancef936d2021-07-21 16:17:52 +00001191 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1192 command();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001193 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001194 return true;
1195}
1196
Prabir Pradhancef936d2021-07-21 16:17:52 +00001197void InputDispatcher::postCommandLocked(Command&& command) {
1198 mCommandQueue.push_back(command);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001199}
1200
1201void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001202 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001203 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001204 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001205 releaseInboundEventLocked(entry);
1206 }
1207 traceInboundQueueLengthLocked();
1208}
1209
1210void InputDispatcher::releasePendingEventLocked() {
1211 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001212 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001213 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001214 }
1215}
1216
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001217void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001218 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001219 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001220 if (DEBUG_DISPATCH_CYCLE) {
1221 ALOGD("Injected inbound event was dropped.");
1222 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001223 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001224 }
1225 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001226 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001227 }
1228 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001229}
1230
1231void InputDispatcher::resetKeyRepeatLocked() {
1232 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001233 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001234 }
1235}
1236
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001237std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1238 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001239
Michael Wright2e732952014-09-24 13:26:59 -07001240 uint32_t policyFlags = entry->policyFlags &
1241 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001242
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001243 std::shared_ptr<KeyEntry> newEntry =
1244 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1245 entry->source, entry->displayId, policyFlags, entry->action,
1246 entry->flags, entry->keyCode, entry->scanCode,
1247 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001248
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001249 newEntry->syntheticRepeat = true;
1250 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001251 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001252 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001253}
1254
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001255bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001256 const ConfigurationChangedEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001257 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1258 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
1259 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001260
1261 // Reset key repeating in case a keyboard device was added or removed or something.
1262 resetKeyRepeatLocked();
1263
1264 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Prabir Pradhancef936d2021-07-21 16:17:52 +00001265 auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
1266 scoped_unlock unlock(mLock);
1267 mPolicy->notifyConfigurationChanged(eventTime);
1268 };
1269 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001270 return true;
1271}
1272
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001273bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1274 const DeviceResetEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001275 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1276 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1277 entry.deviceId);
1278 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001279
liushenxiang42232912021-05-21 20:24:09 +08001280 // Reset key repeating in case a keyboard device was disabled or enabled.
1281 if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1282 resetKeyRepeatLocked();
1283 }
1284
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001285 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001286 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001287 synthesizeCancelationEventsForAllConnectionsLocked(options);
1288 return true;
1289}
1290
Vishnu Nairad321cd2020-08-20 16:40:21 -07001291void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nairc519ff72021-01-21 08:23:08 -08001292 const std::string& reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001293 if (mPendingEvent != nullptr) {
1294 // Move the pending event to the front of the queue. This will give the chance
1295 // for the pending event to get dispatched to the newly focused window
1296 mInboundQueue.push_front(mPendingEvent);
1297 mPendingEvent = nullptr;
1298 }
1299
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001300 std::unique_ptr<FocusEntry> focusEntry =
1301 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1302 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001303
1304 // This event should go to the front of the queue, but behind all other focus events
1305 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001306 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001307 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001308 [](const std::shared_ptr<EventEntry>& event) {
1309 return event->type == EventEntry::Type::FOCUS;
1310 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001311
1312 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001313 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001314}
1315
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001316void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001317 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001318 if (channel == nullptr) {
1319 return; // Window has gone away
1320 }
1321 InputTarget target;
1322 target.inputChannel = channel;
1323 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1324 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001325 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1326 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001327 std::string reason = std::string("reason=").append(entry->reason);
1328 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001329 dispatchEventLocked(currentTime, entry, {target});
1330}
1331
Prabir Pradhan99987712020-11-10 18:43:05 -08001332void InputDispatcher::dispatchPointerCaptureChangedLocked(
1333 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1334 DropReason& dropReason) {
1335 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
Prabir Pradhan167e6d92021-02-04 16:18:17 -08001336 if (entry->pointerCaptureEnabled && haveWindowWithPointerCapture) {
1337 LOG_ALWAYS_FATAL("Pointer Capture has already been enabled for the window.");
1338 }
1339 if (!entry->pointerCaptureEnabled && !haveWindowWithPointerCapture) {
Prabir Pradhan99987712020-11-10 18:43:05 -08001340 // Pointer capture was already forcefully disabled because of focus change.
1341 dropReason = DropReason::NOT_DROPPED;
1342 return;
1343 }
1344
1345 // Set drop reason for early returns
1346 dropReason = DropReason::NO_POINTER_CAPTURE;
1347
1348 sp<IBinder> token;
1349 if (entry->pointerCaptureEnabled) {
1350 // Enable Pointer Capture
1351 if (!mFocusedWindowRequestedPointerCapture) {
1352 // This can happen if a window requests capture and immediately releases capture.
1353 ALOGW("No window requested Pointer Capture.");
1354 return;
1355 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08001356 token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08001357 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1358 mWindowTokenWithPointerCapture = token;
1359 } else {
1360 // Disable Pointer Capture
1361 token = mWindowTokenWithPointerCapture;
1362 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001363 if (mFocusedWindowRequestedPointerCapture) {
1364 mFocusedWindowRequestedPointerCapture = false;
1365 setPointerCaptureLocked(false);
1366 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001367 }
1368
1369 auto channel = getInputChannelLocked(token);
1370 if (channel == nullptr) {
1371 // Window has gone away, clean up Pointer Capture state.
1372 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001373 if (mFocusedWindowRequestedPointerCapture) {
1374 mFocusedWindowRequestedPointerCapture = false;
1375 setPointerCaptureLocked(false);
1376 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001377 return;
1378 }
1379 InputTarget target;
1380 target.inputChannel = channel;
1381 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1382 entry->dispatchInProgress = true;
1383 dispatchEventLocked(currentTime, entry, {target});
1384
1385 dropReason = DropReason::NOT_DROPPED;
1386}
1387
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001388bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001389 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001390 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001391 if (!entry->dispatchInProgress) {
1392 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1393 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1394 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1395 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001396 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001397 // We have seen two identical key downs in a row which indicates that the device
1398 // driver is automatically generating key repeats itself. We take note of the
1399 // repeat here, but we disable our own next key repeat timer since it is clear that
1400 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001401 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1402 // Make sure we don't get key down from a different device. If a different
1403 // device Id has same key pressed down, the new device Id will replace the
1404 // current one to hold the key repeat with repeat count reset.
1405 // In the future when got a KEY_UP on the device id, drop it and do not
1406 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001407 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1408 resetKeyRepeatLocked();
1409 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1410 } else {
1411 // Not a repeat. Save key down state in case we do see a repeat later.
1412 resetKeyRepeatLocked();
1413 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1414 }
1415 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001416 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1417 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001418 // The key on device 'deviceId' is still down, do not stop key repeat
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001419 if (DEBUG_INBOUND_EVENT_DETAILS) {
1420 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1421 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001422 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001423 resetKeyRepeatLocked();
1424 }
1425
1426 if (entry->repeatCount == 1) {
1427 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1428 } else {
1429 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1430 }
1431
1432 entry->dispatchInProgress = true;
1433
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001434 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001435 }
1436
1437 // Handle case where the policy asked us to try again later last time.
1438 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1439 if (currentTime < entry->interceptKeyWakeupTime) {
1440 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1441 *nextWakeupTime = entry->interceptKeyWakeupTime;
1442 }
1443 return false; // wait until next wakeup
1444 }
1445 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1446 entry->interceptKeyWakeupTime = 0;
1447 }
1448
1449 // Give the policy a chance to intercept the key.
1450 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1451 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07001452 sp<IBinder> focusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08001453 mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
Prabir Pradhancef936d2021-07-21 16:17:52 +00001454
1455 auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1456 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1457 };
1458 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001459 return false; // wait for the command to run
1460 } else {
1461 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1462 }
1463 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001464 if (*dropReason == DropReason::NOT_DROPPED) {
1465 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001466 }
1467 }
1468
1469 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001470 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001471 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001472 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1473 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001474 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001475 return true;
1476 }
1477
1478 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001479 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001480 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001481 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001482 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 return false;
1484 }
1485
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001486 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001487 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001488 return true;
1489 }
1490
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001491 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001492 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001493
1494 // Dispatch the key.
1495 dispatchEventLocked(currentTime, entry, inputTargets);
1496 return true;
1497}
1498
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001499void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001500 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1501 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
1502 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1503 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1504 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1505 entry.policyFlags, entry.action, entry.flags, entry.keyCode, entry.scanCode,
1506 entry.metaState, entry.repeatCount, entry.downTime);
1507 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001508}
1509
Prabir Pradhancef936d2021-07-21 16:17:52 +00001510void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
1511 const std::shared_ptr<SensorEntry>& entry,
Chris Yef59a2f42020-10-16 12:55:26 -07001512 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001513 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1514 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1515 "source=0x%x, sensorType=%s",
1516 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
1517 NamedEnum::string(entry->sensorType).c_str());
1518 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00001519 auto command = [this, entry]() REQUIRES(mLock) {
1520 scoped_unlock unlock(mLock);
1521
1522 if (entry->accuracyChanged) {
1523 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1524 }
1525 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1526 entry->hwTimestamp, entry->values);
1527 };
1528 postCommandLocked(std::move(command));
Chris Yef59a2f42020-10-16 12:55:26 -07001529}
1530
1531bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001532 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1533 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1534 NamedEnum::string(sensorType).c_str());
1535 }
Chris Yef59a2f42020-10-16 12:55:26 -07001536 { // acquire lock
1537 std::scoped_lock _l(mLock);
1538
1539 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1540 std::shared_ptr<EventEntry> entry = *it;
1541 if (entry->type == EventEntry::Type::SENSOR) {
1542 it = mInboundQueue.erase(it);
1543 releaseInboundEventLocked(entry);
1544 }
1545 }
1546 }
1547 return true;
1548}
1549
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001550bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001551 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001552 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001553 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001554 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001555 entry->dispatchInProgress = true;
1556
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001557 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001558 }
1559
1560 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001561 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001562 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001563 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1564 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001565 return true;
1566 }
1567
1568 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1569
1570 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001571 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001572
1573 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001574 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001575 if (isPointerEvent) {
1576 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001577 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001578 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001579 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001580 } else {
1581 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001582 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001583 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001584 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001585 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001586 return false;
1587 }
1588
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001589 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001590 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001591 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1592 return true;
1593 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001594 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001595 CancelationOptions::Mode mode(isPointerEvent
1596 ? CancelationOptions::CANCEL_POINTER_EVENTS
1597 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1598 CancelationOptions options(mode, "input event injection failed");
1599 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001600 return true;
1601 }
1602
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001603 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001604 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001605
1606 // Dispatch the motion.
1607 if (conflictingPointerActions) {
1608 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001609 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001610 synthesizeCancelationEventsForAllConnectionsLocked(options);
1611 }
1612 dispatchEventLocked(currentTime, entry, inputTargets);
1613 return true;
1614}
1615
chaviw98318de2021-05-19 16:45:23 -05001616void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
arthurhungb89ccb02020-12-30 16:19:01 +08001617 bool isExiting, const MotionEntry& motionEntry) {
1618 // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
1619 // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
1620 LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
1621 PointerCoords pointerCoords;
1622 pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
1623 pointerCoords.transform(windowHandle->getInfo()->transform);
1624
1625 std::unique_ptr<DragEntry> dragEntry =
1626 std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
1627 windowHandle->getToken(), isExiting, pointerCoords.getX(),
1628 pointerCoords.getY());
1629
1630 enqueueInboundEventLocked(std::move(dragEntry));
1631}
1632
1633void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
1634 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
1635 if (channel == nullptr) {
1636 return; // Window has gone away
1637 }
1638 InputTarget target;
1639 target.inputChannel = channel;
1640 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1641 entry->dispatchInProgress = true;
1642 dispatchEventLocked(currentTime, entry, {target});
1643}
1644
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001645void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001646 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1647 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
1648 ", policyFlags=0x%x, "
1649 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1650 "metaState=0x%x, buttonState=0x%x,"
1651 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
1652 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId,
1653 entry.policyFlags, entry.action, entry.actionButton, entry.flags, entry.metaState,
1654 entry.buttonState, entry.edgeFlags, entry.xPrecision, entry.yPrecision,
1655 entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001656
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001657 for (uint32_t i = 0; i < entry.pointerCount; i++) {
1658 ALOGD(" Pointer %d: id=%d, toolType=%d, "
1659 "x=%f, y=%f, pressure=%f, size=%f, "
1660 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1661 "orientation=%f",
1662 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1663 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1664 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1665 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1666 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1667 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1668 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1669 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1670 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1671 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
1672 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001673 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001674}
1675
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001676void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1677 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001678 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001679 ATRACE_CALL();
Prabir Pradhan61a5d242021-07-26 16:41:09 +00001680 if (DEBUG_DISPATCH_CYCLE) {
1681 ALOGD("dispatchEventToCurrentInputTargets");
1682 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001683
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001684 updateInteractionTokensLocked(*eventEntry, inputTargets);
1685
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1687
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001688 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001689
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001690 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001691 sp<Connection> connection =
1692 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001693 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001694 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001695 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001696 if (DEBUG_FOCUS) {
1697 ALOGD("Dropping event delivery to target with channel '%s' because it "
1698 "is no longer registered with the input dispatcher.",
1699 inputTarget.inputChannel->getName().c_str());
1700 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001701 }
1702 }
1703}
1704
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001705void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1706 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1707 // If the policy decides to close the app, we will get a channel removal event via
1708 // unregisterInputChannel, and will clean up the connection that way. We are already not
1709 // sending new pointers to the connection when it blocked, but focused events will continue to
1710 // pile up.
1711 ALOGW("Canceling events for %s because it is unresponsive",
1712 connection->inputChannel->getName().c_str());
1713 if (connection->status == Connection::STATUS_NORMAL) {
1714 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1715 "application not responding");
1716 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001717 }
1718}
1719
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001720void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001721 if (DEBUG_FOCUS) {
1722 ALOGD("Resetting ANR timeouts.");
1723 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001724
1725 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001726 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001727 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001728}
1729
Tiger Huang721e26f2018-07-24 22:26:19 +08001730/**
1731 * Get the display id that the given event should go to. If this event specifies a valid display id,
1732 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1733 * Focused display is the display that the user most recently interacted with.
1734 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001735int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001736 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001737 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001738 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001739 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1740 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001741 break;
1742 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001743 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001744 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1745 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001746 break;
1747 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001748 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001749 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001750 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001751 case EventEntry::Type::DEVICE_RESET:
arthurhungb89ccb02020-12-30 16:19:01 +08001752 case EventEntry::Type::SENSOR:
1753 case EventEntry::Type::DRAG: {
Chris Yef59a2f42020-10-16 12:55:26 -07001754 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001755 return ADISPLAY_ID_NONE;
1756 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001757 }
1758 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1759}
1760
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001761bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1762 const char* focusedWindowName) {
1763 if (mAnrTracker.empty()) {
1764 // already processed all events that we waited for
1765 mKeyIsWaitingForEventsTimeout = std::nullopt;
1766 return false;
1767 }
1768
1769 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1770 // Start the timer
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00001771 // Wait to send key because there are unprocessed events that may cause focus to change
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001772 mKeyIsWaitingForEventsTimeout = currentTime +
1773 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1774 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001775 return true;
1776 }
1777
1778 // We still have pending events, and already started the timer
1779 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1780 return true; // Still waiting
1781 }
1782
1783 // Waited too long, and some connection still hasn't processed all motions
1784 // Just send the key to the focused window
1785 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1786 focusedWindowName);
1787 mKeyIsWaitingForEventsTimeout = std::nullopt;
1788 return false;
1789}
1790
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001791InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1792 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1793 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001794 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001795
Tiger Huang721e26f2018-07-24 22:26:19 +08001796 int32_t displayId = getTargetDisplayId(entry);
chaviw98318de2021-05-19 16:45:23 -05001797 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001798 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001799 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1800
Michael Wrightd02c5b62014-02-10 15:10:22 -08001801 // If there is no currently focused window and no focused application
1802 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001803 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1804 ALOGI("Dropping %s event because there is no focused window or focused application in "
1805 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001806 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001807 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001808 }
1809
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001810 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1811 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1812 // start interacting with another application via touch (app switch). This code can be removed
1813 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1814 // an app is expected to have a focused window.
1815 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1816 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1817 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001818 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1819 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1820 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001821 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001822 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001823 ALOGW("Waiting because no window has focus but %s may eventually add a "
1824 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001825 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001826 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001827 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001828 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1829 // Already raised ANR. Drop the event
1830 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001831 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001832 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001833 } else {
1834 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001835 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001836 }
1837 }
1838
1839 // we have a valid, non-null focused window
1840 resetNoFocusedWindowTimeoutLocked();
1841
Michael Wrightd02c5b62014-02-10 15:10:22 -08001842 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001843 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001844 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001845 }
1846
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001847 if (focusedWindowHandle->getInfo()->paused) {
1848 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001849 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001850 }
1851
1852 // If the event is a key event, then we must wait for all previous events to
1853 // complete before delivering it because previous events may have the
1854 // side-effect of transferring focus to a different window and we want to
1855 // ensure that the following keys are sent to the new window.
1856 //
1857 // Suppose the user touches a button in a window then immediately presses "A".
1858 // If the button causes a pop-up window to appear then we want to ensure that
1859 // the "A" key is delivered to the new pop-up window. This is because users
1860 // often anticipate pending UI changes when typing on a keyboard.
1861 // To obtain this behavior, we must serialize key events with respect to all
1862 // prior input events.
1863 if (entry.type == EventEntry::Type::KEY) {
1864 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1865 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001866 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001867 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001868 }
1869
1870 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001871 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001872 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1873 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001874
1875 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001876 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001877}
1878
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001879/**
1880 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1881 * that are currently unresponsive.
1882 */
1883std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1884 const std::vector<TouchedMonitor>& monitors) const {
1885 std::vector<TouchedMonitor> responsiveMonitors;
1886 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1887 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1888 sp<Connection> connection = getConnectionLocked(
1889 monitor.monitor.inputChannel->getConnectionToken());
1890 if (connection == nullptr) {
1891 ALOGE("Could not find connection for monitor %s",
1892 monitor.monitor.inputChannel->getName().c_str());
1893 return false;
1894 }
1895 if (!connection->responsive) {
1896 ALOGW("Unresponsive monitor %s will not get the new gesture",
1897 connection->inputChannel->getName().c_str());
1898 return false;
1899 }
1900 return true;
1901 });
1902 return responsiveMonitors;
1903}
1904
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001905InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1906 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1907 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001908 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 enum InjectionPermission {
1910 INJECTION_PERMISSION_UNKNOWN,
1911 INJECTION_PERMISSION_GRANTED,
1912 INJECTION_PERMISSION_DENIED
1913 };
1914
Michael Wrightd02c5b62014-02-10 15:10:22 -08001915 // For security reasons, we defer updating the touch state until we are sure that
1916 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001917 int32_t displayId = entry.displayId;
1918 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001919 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1920
1921 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001922 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001923 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
chaviw98318de2021-05-19 16:45:23 -05001924 sp<WindowInfoHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1925 sp<WindowInfoHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001926
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001927 // Copy current touch state into tempTouchState.
1928 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1929 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001930 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001931 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001932 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1933 mTouchStatesByDisplay.find(displayId);
1934 if (oldStateIt != mTouchStatesByDisplay.end()) {
1935 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001936 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001937 }
1938
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001939 bool isSplit = tempTouchState.split;
1940 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1941 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1942 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001943 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1944 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1945 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1946 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1947 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001948 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001949 bool wrongDevice = false;
1950 if (newGesture) {
1951 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001952 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001953 ALOGI("Dropping event because a pointer for a different device is already down "
1954 "in display %" PRId32,
1955 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001956 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001957 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001958 switchedDevice = false;
1959 wrongDevice = true;
1960 goto Failed;
1961 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001962 tempTouchState.reset();
1963 tempTouchState.down = down;
1964 tempTouchState.deviceId = entry.deviceId;
1965 tempTouchState.source = entry.source;
1966 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001967 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001968 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001969 ALOGI("Dropping move event because a pointer for a different device is already active "
1970 "in display %" PRId32,
1971 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001972 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001973 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001974 switchedDevice = false;
1975 wrongDevice = true;
1976 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001977 }
1978
1979 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1980 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1981
Garfield Tan00f511d2019-06-12 16:55:40 -07001982 int32_t x;
1983 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001984 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001985 // Always dispatch mouse events to cursor position.
1986 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001987 x = int32_t(entry.xCursorPosition);
1988 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001989 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001990 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1991 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001992 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001993 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001994 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1995 isDown /*addOutsideTargets*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001996
1997 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou64452932020-11-06 17:51:32 -06001998 ? findTouchedGestureMonitorsLocked(displayId)
Michael Wright3dd60e22019-03-27 22:06:44 +00001999 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08002000
Michael Wrightd02c5b62014-02-10 15:10:22 -08002001 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002002 if (newTouchedWindowHandle != nullptr &&
2003 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07002004 // New window supports splitting, but we should never split mouse events.
2005 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002006 } else if (isSplit) {
2007 // New window does not support splitting but we have already split events.
2008 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002009 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002010 }
2011
2012 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07002013 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002015 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002016 }
2017
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002018 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
2019 ALOGI("Not sending touch event to %s because it is paused",
2020 newTouchedWindowHandle->getName().c_str());
2021 newTouchedWindowHandle = nullptr;
2022 }
2023
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002024 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002025 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05002026 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
2027 if (!isResponsive) {
2028 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002029 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
2030 newTouchedWindowHandle = nullptr;
2031 }
2032 }
2033
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002034 // Drop events that can't be trusted due to occlusion
2035 if (newTouchedWindowHandle != nullptr &&
2036 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
2037 TouchOcclusionInfo occlusionInfo =
2038 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002039 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002040 if (DEBUG_TOUCH_OCCLUSION) {
2041 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
2042 for (const auto& log : occlusionInfo.debugInfo) {
2043 ALOGD("%s", log.c_str());
2044 }
2045 }
Prabir Pradhancef936d2021-07-21 16:17:52 +00002046 sendUntrustedTouchCommandLocked(occlusionInfo.obscuringPackage);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00002047 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
2048 ALOGW("Dropping untrusted touch event due to %s/%d",
2049 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
2050 newTouchedWindowHandle = nullptr;
2051 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002052 }
2053 }
2054
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002055 // Also don't send the new touch event to unresponsive gesture monitors
2056 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
2057
Michael Wright3dd60e22019-03-27 22:06:44 +00002058 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
2059 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002060 "(%d, %d) in display %" PRId32 ".",
2061 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002062 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00002063 goto Failed;
2064 }
2065
2066 if (newTouchedWindowHandle != nullptr) {
2067 // Set target flags.
2068 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
2069 if (isSplit) {
2070 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002071 }
Michael Wright3dd60e22019-03-27 22:06:44 +00002072 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2073 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
2074 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2075 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2076 }
2077
2078 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07002079 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2080 newHoverWindowHandle = nullptr;
2081 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002082 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00002083 }
2084
2085 // Update the temporary touch state.
2086 BitSet32 pointerIds;
2087 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002088 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002089 pointerIds.markBit(pointerId);
2090 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002091 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002092 }
2093
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002094 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002095 } else {
2096 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2097
2098 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002099 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002100 if (DEBUG_FOCUS) {
2101 ALOGD("Dropping event because the pointer is not down or we previously "
2102 "dropped the pointer down event in display %" PRId32,
2103 displayId);
2104 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002105 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002106 goto Failed;
2107 }
2108
arthurhung6d4bed92021-03-17 11:59:33 +08002109 addDragEventLocked(entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002110
Michael Wrightd02c5b62014-02-10 15:10:22 -08002111 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002112 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002113 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002114 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2115 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002116
chaviw98318de2021-05-19 16:45:23 -05002117 sp<WindowInfoHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002118 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002119 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002120 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2121 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002122 if (DEBUG_FOCUS) {
2123 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2124 oldTouchedWindowHandle->getName().c_str(),
2125 newTouchedWindowHandle->getName().c_str(), displayId);
2126 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002127 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002128 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2129 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2130 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002131
2132 // Make a slippery entrance into the new window.
2133 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2134 isSplit = true;
2135 }
2136
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002137 int32_t targetFlags =
2138 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139 if (isSplit) {
2140 targetFlags |= InputTarget::FLAG_SPLIT;
2141 }
2142 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2143 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002144 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2145 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002146 }
2147
2148 BitSet32 pointerIds;
2149 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002150 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002151 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002152 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002153 }
2154 }
2155 }
2156
2157 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002158 // Let the previous window know that the hover sequence is over, unless we already did it
2159 // when dispatching it as is to newTouchedWindowHandle.
2160 if (mLastHoverWindowHandle != nullptr &&
2161 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2162 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002163 if (DEBUG_HOVER) {
2164 ALOGD("Sending hover exit event to window %s.",
2165 mLastHoverWindowHandle->getName().c_str());
2166 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002167 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2168 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002169 }
2170
Garfield Tandf26e862020-07-01 20:18:19 -07002171 // Let the new window know that the hover sequence is starting, unless we already did it
2172 // when dispatching it as is to newTouchedWindowHandle.
2173 if (newHoverWindowHandle != nullptr &&
2174 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2175 newHoverWindowHandle != newTouchedWindowHandle)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002176 if (DEBUG_HOVER) {
2177 ALOGD("Sending hover enter event to window %s.",
2178 newHoverWindowHandle->getName().c_str());
2179 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002180 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2181 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2182 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183 }
2184 }
2185
2186 // Check permission to inject into all touched foreground windows and ensure there
2187 // is at least one touched foreground window.
2188 {
2189 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002190 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002191 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2192 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002193 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002194 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002195 injectionPermission = INJECTION_PERMISSION_DENIED;
2196 goto Failed;
2197 }
2198 }
2199 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002200 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002201 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002202 ALOGI("Dropping event because there is no touched foreground window in display "
2203 "%" PRId32 " or gesture monitor to receive it.",
2204 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002205 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002206 goto Failed;
2207 }
2208
2209 // Permission granted to injection into all touched foreground windows.
2210 injectionPermission = INJECTION_PERMISSION_GRANTED;
2211 }
2212
2213 // Check whether windows listening for outside touches are owned by the same UID. If it is
2214 // set the policy flag that we will not reveal coordinate information to this window.
2215 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002216 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002217 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002218 if (foregroundWindowHandle) {
2219 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002220 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002221 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
chaviw98318de2021-05-19 16:45:23 -05002222 sp<WindowInfoHandle> windowInfoHandle = touchedWindow.windowHandle;
2223 if (windowInfoHandle->getInfo()->ownerUid != foregroundWindowUid) {
2224 tempTouchState.addOrUpdateWindow(windowInfoHandle,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002225 InputTarget::FLAG_ZERO_COORDS,
2226 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002227 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002228 }
2229 }
2230 }
2231 }
2232
Michael Wrightd02c5b62014-02-10 15:10:22 -08002233 // If this is the first pointer going down and the touched window has a wallpaper
2234 // then also add the touched wallpaper windows so they are locked in for the duration
2235 // of the touch gesture.
2236 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2237 // engine only supports touch events. We would need to add a mechanism similar
2238 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2239 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
chaviw98318de2021-05-19 16:45:23 -05002240 sp<WindowInfoHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002241 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002242 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
chaviw98318de2021-05-19 16:45:23 -05002243 const std::vector<sp<WindowInfoHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002244 getWindowHandlesLocked(displayId);
chaviw98318de2021-05-19 16:45:23 -05002245 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
2246 const WindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002247 if (info->displayId == displayId &&
chaviw98318de2021-05-19 16:45:23 -05002248 windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002249 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002250 .addOrUpdateWindow(windowHandle,
2251 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2252 InputTarget::
2253 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2254 InputTarget::FLAG_DISPATCH_AS_IS,
2255 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002256 }
2257 }
2258 }
2259 }
2260
2261 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002262 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002263
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002264 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002265 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002266 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002267 }
2268
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002269 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002270 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002271 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002272 }
2273
Michael Wrightd02c5b62014-02-10 15:10:22 -08002274 // Drop the outside or hover touch windows since we will not care about them
2275 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002276 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002277
2278Failed:
2279 // Check injection permission once and for all.
2280 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002281 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002282 injectionPermission = INJECTION_PERMISSION_GRANTED;
2283 } else {
2284 injectionPermission = INJECTION_PERMISSION_DENIED;
2285 }
2286 }
2287
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002288 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2289 return injectionResult;
2290 }
2291
Michael Wrightd02c5b62014-02-10 15:10:22 -08002292 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002293 if (!wrongDevice) {
2294 if (switchedDevice) {
2295 if (DEBUG_FOCUS) {
2296 ALOGD("Conflicting pointer actions: Switched to a different device.");
2297 }
2298 *outConflictingPointerActions = true;
2299 }
2300
2301 if (isHoverAction) {
2302 // Started hovering, therefore no longer down.
2303 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002304 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002305 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2306 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002307 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002308 *outConflictingPointerActions = true;
2309 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002310 tempTouchState.reset();
2311 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2312 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2313 tempTouchState.deviceId = entry.deviceId;
2314 tempTouchState.source = entry.source;
2315 tempTouchState.displayId = displayId;
2316 }
2317 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2318 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2319 // All pointers up or canceled.
2320 tempTouchState.reset();
2321 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2322 // First pointer went down.
2323 if (oldState && oldState->down) {
2324 if (DEBUG_FOCUS) {
2325 ALOGD("Conflicting pointer actions: Down received while already down.");
2326 }
2327 *outConflictingPointerActions = true;
2328 }
2329 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2330 // One pointer went up.
2331 if (isSplit) {
2332 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2333 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002334
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002335 for (size_t i = 0; i < tempTouchState.windows.size();) {
2336 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2337 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2338 touchedWindow.pointerIds.clearBit(pointerId);
2339 if (touchedWindow.pointerIds.isEmpty()) {
2340 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2341 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002343 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002344 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002345 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002346 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002347 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002348
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002349 // Save changes unless the action was scroll in which case the temporary touch
2350 // state was only valid for this one action.
2351 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2352 if (tempTouchState.displayId >= 0) {
2353 mTouchStatesByDisplay[displayId] = tempTouchState;
2354 } else {
2355 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002356 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002357 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002358
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002359 // Update hover state.
2360 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002361 }
2362
Michael Wrightd02c5b62014-02-10 15:10:22 -08002363 return injectionResult;
2364}
2365
arthurhung6d4bed92021-03-17 11:59:33 +08002366void InputDispatcher::finishDragAndDrop(int32_t displayId, float x, float y) {
chaviw98318de2021-05-19 16:45:23 -05002367 const sp<WindowInfoHandle> dropWindow =
arthurhung6d4bed92021-03-17 11:59:33 +08002368 findTouchedWindowAtLocked(displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002369 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhung6d4bed92021-03-17 11:59:33 +08002370 if (dropWindow) {
2371 vec2 local = dropWindow->getInfo()->transform.transform(x, y);
Prabir Pradhancef936d2021-07-21 16:17:52 +00002372 sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
Arthur Hung6d0571e2021-04-09 20:18:16 +08002373 } else {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002374 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002375 }
2376 mDragState.reset();
2377}
2378
2379void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2380 if (entry.pointerCount != 1 || !mDragState) {
arthurhungb89ccb02020-12-30 16:19:01 +08002381 return;
2382 }
2383
arthurhung6d4bed92021-03-17 11:59:33 +08002384 if (!mDragState->isStartDrag) {
2385 mDragState->isStartDrag = true;
2386 mDragState->isStylusButtonDownAtStart =
2387 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2388 }
2389
arthurhungb89ccb02020-12-30 16:19:01 +08002390 int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2391 int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2392 int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
2393 if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
arthurhung6d4bed92021-03-17 11:59:33 +08002394 // Handle the special case : stylus button no longer pressed.
2395 bool isStylusButtonDown = (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2396 if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2397 finishDragAndDrop(entry.displayId, x, y);
2398 return;
2399 }
2400
chaviw98318de2021-05-19 16:45:23 -05002401 const sp<WindowInfoHandle> hoverWindowHandle =
arthurhung6d4bed92021-03-17 11:59:33 +08002402 findTouchedWindowAtLocked(entry.displayId, x, y, nullptr /*touchState*/,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06002403 false /*addOutsideTargets*/, true /*ignoreDragWindow*/);
arthurhungb89ccb02020-12-30 16:19:01 +08002404 // enqueue drag exit if needed.
arthurhung6d4bed92021-03-17 11:59:33 +08002405 if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2406 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2407 if (mDragState->dragHoverWindowHandle != nullptr) {
2408 enqueueDragEventLocked(mDragState->dragHoverWindowHandle, true /*isExiting*/,
2409 entry);
arthurhungb89ccb02020-12-30 16:19:01 +08002410 }
arthurhung6d4bed92021-03-17 11:59:33 +08002411 mDragState->dragHoverWindowHandle = hoverWindowHandle;
arthurhungb89ccb02020-12-30 16:19:01 +08002412 }
2413 // enqueue drag location if needed.
2414 if (hoverWindowHandle != nullptr) {
2415 enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
2416 }
arthurhung6d4bed92021-03-17 11:59:33 +08002417 } else if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2418 finishDragAndDrop(entry.displayId, x, y);
2419 } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00002420 sendDropWindowCommandLocked(nullptr, 0, 0);
arthurhung6d4bed92021-03-17 11:59:33 +08002421 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08002422 }
2423}
2424
chaviw98318de2021-05-19 16:45:23 -05002425void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002426 int32_t targetFlags, BitSet32 pointerIds,
2427 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002428 std::vector<InputTarget>::iterator it =
2429 std::find_if(inputTargets.begin(), inputTargets.end(),
2430 [&windowHandle](const InputTarget& inputTarget) {
2431 return inputTarget.inputChannel->getConnectionToken() ==
2432 windowHandle->getToken();
2433 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002434
chaviw98318de2021-05-19 16:45:23 -05002435 const WindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002436
2437 if (it == inputTargets.end()) {
2438 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002439 std::shared_ptr<InputChannel> inputChannel =
2440 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002441 if (inputChannel == nullptr) {
2442 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2443 return;
2444 }
2445 inputTarget.inputChannel = inputChannel;
2446 inputTarget.flags = targetFlags;
2447 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07002448 const auto& displayInfoIt = mDisplayInfos.find(windowInfo->displayId);
2449 if (displayInfoIt != mDisplayInfos.end()) {
2450 const auto& displayInfo = displayInfoIt->second;
2451 inputTarget.displayOrientation = displayInfo.transform.getOrientation();
2452 inputTarget.displaySize = int2(displayInfo.logicalWidth, displayInfo.logicalHeight);
2453 } else {
2454 ALOGI_IF(isPerWindowInputRotationEnabled(),
2455 "DisplayInfo not found for window on display: %d", windowInfo->displayId);
2456 }
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002457 inputTargets.push_back(inputTarget);
2458 it = inputTargets.end() - 1;
2459 }
2460
2461 ALOG_ASSERT(it->flags == targetFlags);
2462 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2463
chaviw1ff3d1e2020-07-01 15:53:47 -07002464 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002465}
2466
Michael Wright3dd60e22019-03-27 22:06:44 +00002467void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002468 int32_t displayId, float xOffset,
2469 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002470 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2471 mGlobalMonitorsByDisplay.find(displayId);
2472
2473 if (it != mGlobalMonitorsByDisplay.end()) {
2474 const std::vector<Monitor>& monitors = it->second;
2475 for (const Monitor& monitor : monitors) {
2476 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002477 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002478 }
2479}
2480
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002481void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2482 float yOffset,
2483 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002484 InputTarget target;
2485 target.inputChannel = monitor.inputChannel;
2486 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002487 ui::Transform t;
2488 t.set(xOffset, yOffset);
2489 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002490 inputTargets.push_back(target);
2491}
2492
chaviw98318de2021-05-19 16:45:23 -05002493bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002494 const InjectionState* injectionState) {
2495 if (injectionState &&
2496 (windowHandle == nullptr ||
2497 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2498 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002499 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002500 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002501 "owned by uid %d",
2502 injectionState->injectorPid, injectionState->injectorUid,
2503 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504 } else {
2505 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002506 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002507 }
2508 return false;
2509 }
2510 return true;
2511}
2512
Robert Carrc9bf1d32020-04-13 17:21:08 -07002513/**
2514 * Indicate whether one window handle should be considered as obscuring
2515 * another window handle. We only check a few preconditions. Actually
2516 * checking the bounds is left to the caller.
2517 */
chaviw98318de2021-05-19 16:45:23 -05002518static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
2519 const sp<WindowInfoHandle>& otherHandle) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002520 // Compare by token so cloned layers aren't counted
2521 if (haveSameToken(windowHandle, otherHandle)) {
2522 return false;
2523 }
2524 auto info = windowHandle->getInfo();
2525 auto otherInfo = otherHandle->getInfo();
2526 if (!otherInfo->visible) {
2527 return false;
chaviw98318de2021-05-19 16:45:23 -05002528 } else if (otherInfo->alpha == 0 && otherInfo->flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002529 // Those act as if they were invisible, so we don't need to flag them.
2530 // We do want to potentially flag touchable windows even if they have 0
2531 // opacity, since they can consume touches and alter the effects of the
2532 // user interaction (eg. apps that rely on
2533 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2534 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2535 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002536 } else if (info->ownerUid == otherInfo->ownerUid) {
2537 // If ownerUid is the same we don't generate occlusion events as there
2538 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002539 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002540 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002541 return false;
2542 } else if (otherInfo->displayId != info->displayId) {
2543 return false;
2544 }
2545 return true;
2546}
2547
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002548/**
2549 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2550 * untrusted, one should check:
2551 *
2552 * 1. If result.hasBlockingOcclusion is true.
2553 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2554 * BLOCK_UNTRUSTED.
2555 *
2556 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2557 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2558 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2559 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2560 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2561 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2562 *
2563 * If neither of those is true, then it means the touch can be allowed.
2564 */
2565InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
chaviw98318de2021-05-19 16:45:23 -05002566 const sp<WindowInfoHandle>& windowHandle, int32_t x, int32_t y) const {
2567 const WindowInfo* windowInfo = windowHandle->getInfo();
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002568 int32_t displayId = windowInfo->displayId;
chaviw98318de2021-05-19 16:45:23 -05002569 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002570 TouchOcclusionInfo info;
2571 info.hasBlockingOcclusion = false;
2572 info.obscuringOpacity = 0;
2573 info.obscuringUid = -1;
2574 std::map<int32_t, float> opacityByUid;
chaviw98318de2021-05-19 16:45:23 -05002575 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002576 if (windowHandle == otherHandle) {
2577 break; // All future windows are below us. Exit early.
2578 }
chaviw98318de2021-05-19 16:45:23 -05002579 const WindowInfo* otherInfo = otherHandle->getInfo();
Bernardo Rufino1ff9d592021-01-18 16:58:57 +00002580 if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->frameContainsPoint(x, y) &&
2581 !haveSameApplicationToken(windowInfo, otherInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002582 if (DEBUG_TOUCH_OCCLUSION) {
2583 info.debugInfo.push_back(
2584 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2585 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002586 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2587 // we perform the checks below to see if the touch can be propagated or not based on the
2588 // window's touch occlusion mode
2589 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2590 info.hasBlockingOcclusion = true;
2591 info.obscuringUid = otherInfo->ownerUid;
2592 info.obscuringPackage = otherInfo->packageName;
2593 break;
2594 }
2595 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2596 uint32_t uid = otherInfo->ownerUid;
2597 float opacity =
2598 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2599 // Given windows A and B:
2600 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2601 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2602 opacityByUid[uid] = opacity;
2603 if (opacity > info.obscuringOpacity) {
2604 info.obscuringOpacity = opacity;
2605 info.obscuringUid = uid;
2606 info.obscuringPackage = otherInfo->packageName;
2607 }
2608 }
2609 }
2610 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002611 if (DEBUG_TOUCH_OCCLUSION) {
2612 info.debugInfo.push_back(
2613 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2614 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002615 return info;
2616}
2617
chaviw98318de2021-05-19 16:45:23 -05002618std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002619 bool isTouchedWindow) const {
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002620 return StringPrintf(INDENT2
2621 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32 ", mode=%s, alpha=%.2f, "
2622 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2623 "], touchableRegion=%s, window={%s}, flags={%s}, inputFeatures={%s}, "
2624 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002625 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002626 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002627 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002628 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2629 info->frameTop, info->frameRight, info->frameBottom,
2630 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufino49d99e42021-01-18 15:16:59 +00002631 info->flags.string().c_str(), info->inputFeatures.string().c_str(),
2632 toString(info->token != nullptr), info->applicationInfo.name.c_str(),
2633 toString(info->applicationInfo.token).c_str());
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002634}
2635
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002636bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2637 if (occlusionInfo.hasBlockingOcclusion) {
2638 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2639 occlusionInfo.obscuringUid);
2640 return false;
2641 }
2642 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2643 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2644 "%.2f, maximum allowed = %.2f)",
2645 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2646 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2647 return false;
2648 }
2649 return true;
2650}
2651
chaviw98318de2021-05-19 16:45:23 -05002652bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002653 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002654 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002655 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2656 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002657 if (windowHandle == otherHandle) {
2658 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002659 }
chaviw98318de2021-05-19 16:45:23 -05002660 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002661 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002662 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002663 return true;
2664 }
2665 }
2666 return false;
2667}
2668
chaviw98318de2021-05-19 16:45:23 -05002669bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002670 int32_t displayId = windowHandle->getInfo()->displayId;
chaviw98318de2021-05-19 16:45:23 -05002671 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2672 const WindowInfo* windowInfo = windowHandle->getInfo();
2673 for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002674 if (windowHandle == otherHandle) {
2675 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002676 }
chaviw98318de2021-05-19 16:45:23 -05002677 const WindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002678 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002679 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002680 return true;
2681 }
2682 }
2683 return false;
2684}
2685
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002686std::string InputDispatcher::getApplicationWindowLabel(
chaviw98318de2021-05-19 16:45:23 -05002687 const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002688 if (applicationHandle != nullptr) {
2689 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002690 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002691 } else {
2692 return applicationHandle->getName();
2693 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002694 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002695 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002696 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002697 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698 }
2699}
2700
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002701void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002702 if (eventEntry.type == EventEntry::Type::FOCUS ||
arthurhungb89ccb02020-12-30 16:19:01 +08002703 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
2704 eventEntry.type == EventEntry::Type::DRAG) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002705 // Focus or pointer capture changed events are passed to apps, but do not represent user
2706 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002707 return;
2708 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002709 int32_t displayId = getTargetDisplayId(eventEntry);
chaviw98318de2021-05-19 16:45:23 -05002710 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002711 if (focusedWindowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05002712 const WindowInfo* info = focusedWindowHandle->getInfo();
2713 if (info->inputFeatures.test(WindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002714 if (DEBUG_DISPATCH_CYCLE) {
2715 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2716 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717 return;
2718 }
2719 }
2720
2721 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002722 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002723 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002724 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2725 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002726 return;
2727 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002729 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002730 eventType = USER_ACTIVITY_EVENT_TOUCH;
2731 }
2732 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002733 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002734 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002735 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2736 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002737 return;
2738 }
2739 eventType = USER_ACTIVITY_EVENT_BUTTON;
2740 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002741 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002742 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002743 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002744 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002745 case EventEntry::Type::SENSOR:
arthurhungb89ccb02020-12-30 16:19:01 +08002746 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2747 case EventEntry::Type::DRAG: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002748 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002749 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002750 break;
2751 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002752 }
2753
Prabir Pradhancef936d2021-07-21 16:17:52 +00002754 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2755 REQUIRES(mLock) {
2756 scoped_unlock unlock(mLock);
2757 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2758 };
2759 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002760}
2761
2762void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002763 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002764 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002765 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002766 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002767 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002768 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002769 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002770 ATRACE_NAME(message.c_str());
2771 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002772 if (DEBUG_DISPATCH_CYCLE) {
2773 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
2774 "globalScaleFactor=%f, pointerIds=0x%x %s",
2775 connection->getInputChannelName().c_str(), inputTarget.flags,
2776 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2777 inputTarget.getPointerInfoString().c_str());
2778 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002779
2780 // Skip this event if the connection status is not normal.
2781 // We don't want to enqueue additional outbound events if the connection is broken.
2782 if (connection->status != Connection::STATUS_NORMAL) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002783 if (DEBUG_DISPATCH_CYCLE) {
2784 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
2785 connection->getInputChannelName().c_str(), connection->getStatusLabel());
2786 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002787 return;
2788 }
2789
2790 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002791 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2792 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2793 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002794 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002796 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002797 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002798 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002799 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002800 if (!splitMotionEntry) {
2801 return; // split event was dropped
2802 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002803 if (DEBUG_FOCUS) {
2804 ALOGD("channel '%s' ~ Split motion event.",
2805 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002806 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002807 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002808 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2809 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 return;
2811 }
2812 }
2813
2814 // Not splitting. Enqueue dispatch entries for the event as is.
2815 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2816}
2817
2818void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002819 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002820 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002821 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002822 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002823 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002824 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002825 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002826 ATRACE_NAME(message.c_str());
2827 }
2828
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002829 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002830
2831 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002832 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002833 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002834 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002835 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002836 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002837 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002838 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002839 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002840 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002841 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002842 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002843 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002844
2845 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002846 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002847 startDispatchCycleLocked(currentTime, connection);
2848 }
2849}
2850
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002851void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002852 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002853 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002854 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002855 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002856 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2857 connection->getInputChannelName().c_str(),
2858 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002859 ATRACE_NAME(message.c_str());
2860 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002861 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002862 if (!(inputTargetFlags & dispatchMode)) {
2863 return;
2864 }
2865 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2866
2867 // This is a new event.
2868 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002869 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002870 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002871
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002872 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2873 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002874 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002875 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002876 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002877 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002878 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002879 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002880 dispatchEntry->resolvedAction = keyEntry.action;
2881 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002882
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002883 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2884 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002885 if (DEBUG_DISPATCH_CYCLE) {
2886 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key "
2887 "event",
2888 connection->getInputChannelName().c_str());
2889 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002890 return; // skip the inconsistent event
2891 }
2892 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002893 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002894
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002895 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002896 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002897 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2898 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2899 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2900 static_cast<int32_t>(IdGenerator::Source::OTHER);
2901 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002902 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2903 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2904 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2905 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2906 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2907 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2908 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2909 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2910 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2911 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2912 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002913 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002914 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 }
2916 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002917 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2918 motionEntry.displayId)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002919 if (DEBUG_DISPATCH_CYCLE) {
2920 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover "
2921 "enter event",
2922 connection->getInputChannelName().c_str());
2923 }
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00002924 // We keep the 'resolvedEventId' here equal to the original 'motionEntry.id' because
2925 // this is a one-to-one event conversion.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002926 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2927 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002928
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002929 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002930 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2931 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2932 }
2933 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2934 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2935 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002937 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2938 dispatchEntry->resolvedFlags)) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00002939 if (DEBUG_DISPATCH_CYCLE) {
2940 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2941 "event",
2942 connection->getInputChannelName().c_str());
2943 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002944 return; // skip the inconsistent event
2945 }
2946
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002947 dispatchEntry->resolvedEventId =
2948 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2949 ? mIdGenerator.nextId()
2950 : motionEntry.id;
2951 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2952 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2953 ") to MotionEvent(id=0x%" PRIx32 ").",
2954 motionEntry.id, dispatchEntry->resolvedEventId);
2955 ATRACE_NAME(message.c_str());
2956 }
2957
Prabir Pradhan47cf0a02021-03-11 20:30:57 -08002958 if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
2959 (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
2960 // Skip reporting pointer down outside focus to the policy.
2961 break;
2962 }
2963
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002964 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002965 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002966
2967 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002968 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002969 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08002970 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2971 case EventEntry::Type::DRAG: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002972 break;
2973 }
Chris Yef59a2f42020-10-16 12:55:26 -07002974 case EventEntry::Type::SENSOR: {
2975 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2976 break;
2977 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002978 case EventEntry::Type::CONFIGURATION_CHANGED:
2979 case EventEntry::Type::DEVICE_RESET: {
2980 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002981 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002982 break;
2983 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002984 }
2985
2986 // Remember that we are waiting for this dispatch to complete.
2987 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002988 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002989 }
2990
2991 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002992 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00002993 traceOutboundQueueLength(*connection);
chaviw8c9cf542019-03-25 13:02:48 -07002994}
2995
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002996/**
2997 * This function is purely for debugging. It helps us understand where the user interaction
2998 * was taking place. For example, if user is touching launcher, we will see a log that user
2999 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
3000 * We will see both launcher and wallpaper in that list.
3001 * Once the interaction with a particular set of connections starts, no new logs will be printed
3002 * until the set of interacted connections changes.
3003 *
3004 * The following items are skipped, to reduce the logspam:
3005 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
3006 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
3007 * This includes situations like the soft BACK button key. When the user releases (lifts up the
3008 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
3009 * Both of those ACTION_UP events would not be logged
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003010 */
3011void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
3012 const std::vector<InputTarget>& targets) {
3013 // Skip ACTION_UP events, and all events other than keys and motions
3014 if (entry.type == EventEntry::Type::KEY) {
3015 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3016 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3017 return;
3018 }
3019 } else if (entry.type == EventEntry::Type::MOTION) {
3020 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3021 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3022 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3023 return;
3024 }
3025 } else {
3026 return; // Not a key or a motion
3027 }
3028
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07003029 std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003030 std::vector<sp<Connection>> newConnections;
3031 for (const InputTarget& target : targets) {
3032 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
3033 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
3034 continue; // Skip windows that receive ACTION_OUTSIDE
3035 }
3036
3037 sp<IBinder> token = target.inputChannel->getConnectionToken();
3038 sp<Connection> connection = getConnectionLocked(token);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003039 if (connection == nullptr) {
3040 continue;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003041 }
3042 newConnectionTokens.insert(std::move(token));
3043 newConnections.emplace_back(connection);
3044 }
3045 if (newConnectionTokens == mInteractionConnectionTokens) {
3046 return; // no change
3047 }
3048 mInteractionConnectionTokens = newConnectionTokens;
3049
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003050 std::string targetList;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003051 for (const sp<Connection>& connection : newConnections) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003052 targetList += connection->getWindowName() + ", ";
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003053 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00003054 std::string message = "Interaction with: " + targetList;
3055 if (targetList.empty()) {
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00003056 message += "<none>";
3057 }
3058 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3059}
3060
chaviwfd6d3512019-03-25 13:23:49 -07003061void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07003062 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07003063 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07003064 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3065 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07003066 return;
3067 }
3068
Vishnu Nairc519ff72021-01-21 08:23:08 -08003069 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07003070 if (focusedToken == token) {
3071 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07003072 return;
3073 }
3074
Prabir Pradhancef936d2021-07-21 16:17:52 +00003075 auto command = [this, token]() REQUIRES(mLock) {
3076 scoped_unlock unlock(mLock);
3077 mPolicy->onPointerDownOutsideFocus(token);
3078 };
3079 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003080}
3081
3082void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003083 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003084 if (ATRACE_ENABLED()) {
3085 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003086 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00003087 ATRACE_NAME(message.c_str());
3088 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003089 if (DEBUG_DISPATCH_CYCLE) {
3090 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3091 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003092
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003093 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
3094 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003095 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003096 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003097 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05003098 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003099
3100 // Publish the event.
3101 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003102 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3103 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003104 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003105 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3106 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003107
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003108 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003109 status = connection->inputPublisher
3110 .publishKeyEvent(dispatchEntry->seq,
3111 dispatchEntry->resolvedEventId, keyEntry.deviceId,
3112 keyEntry.source, keyEntry.displayId,
3113 std::move(hmac), dispatchEntry->resolvedAction,
3114 dispatchEntry->resolvedFlags, keyEntry.keyCode,
3115 keyEntry.scanCode, keyEntry.metaState,
3116 keyEntry.repeatCount, keyEntry.downTime,
3117 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003118 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003119 }
3120
Siarhei Vishniakou49483272019-10-22 13:13:47 -07003121 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003122 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003124 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003125 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003126
chaviw82357092020-01-28 13:13:06 -08003127 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003128 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003129 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
3130 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08003131 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003132 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
3133 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08003134 // Don't apply window scale here since we don't want scale to affect raw
3135 // coordinates. The scale will be sent back to the client and applied
3136 // later when requesting relative coordinates.
3137 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
3138 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003139 }
3140 usingCoords = scaledCoords;
3141 }
3142 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003143 // We don't want the dispatch target to know.
3144 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003145 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003146 scaledCoords[i].clear();
3147 }
3148 usingCoords = scaledCoords;
3149 }
3150 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003151
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003152 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003153
3154 // Publish the motion event.
3155 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003156 .publishMotionEvent(dispatchEntry->seq,
3157 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003158 motionEntry.deviceId, motionEntry.source,
3159 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003160 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003161 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003162 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003163 motionEntry.edgeFlags, motionEntry.metaState,
3164 motionEntry.buttonState,
3165 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003166 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003167 motionEntry.xPrecision, motionEntry.yPrecision,
3168 motionEntry.xCursorPosition,
3169 motionEntry.yCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003170 dispatchEntry->displayOrientation,
Evan Rosky84f07f02021-04-16 10:42:42 -07003171 dispatchEntry->displaySize.x,
3172 dispatchEntry->displaySize.y,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003173 motionEntry.downTime, motionEntry.eventTime,
3174 motionEntry.pointerCount,
3175 motionEntry.pointerProperties, usingCoords);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003176 break;
3177 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003178
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003179 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003180 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003181 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003182 focusEntry.id,
3183 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003184 mInTouchMode);
3185 break;
3186 }
3187
Prabir Pradhan99987712020-11-10 18:43:05 -08003188 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3189 const auto& captureEntry =
3190 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3191 status = connection->inputPublisher
3192 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3193 captureEntry.pointerCaptureEnabled);
3194 break;
3195 }
3196
arthurhungb89ccb02020-12-30 16:19:01 +08003197 case EventEntry::Type::DRAG: {
3198 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3199 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3200 dragEntry.id, dragEntry.x,
3201 dragEntry.y,
3202 dragEntry.isExiting);
3203 break;
3204 }
3205
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003206 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003207 case EventEntry::Type::DEVICE_RESET:
3208 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003209 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003210 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003211 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003212 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003213 }
3214
3215 // Check the result.
3216 if (status) {
3217 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003218 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003219 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003220 "This is unexpected because the wait queue is empty, so the pipe "
3221 "should be empty and we shouldn't have any problems writing an "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003222 "event to it, status=%s(%d)",
3223 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3224 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003225 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3226 } else {
3227 // Pipe is full and we are waiting for the app to finish process some events
3228 // before sending more events to it.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003229 if (DEBUG_DISPATCH_CYCLE) {
3230 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3231 "waiting for the application to catch up",
3232 connection->getInputChannelName().c_str());
3233 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003234 }
3235 } else {
3236 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +00003237 "status=%s(%d)",
3238 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3239 status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003240 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3241 }
3242 return;
3243 }
3244
3245 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003246 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3247 connection->outboundQueue.end(),
3248 dispatchEntry));
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003249 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003250 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003251 if (connection->responsive) {
3252 mAnrTracker.insert(dispatchEntry->timeoutTime,
3253 connection->inputChannel->getConnectionToken());
3254 }
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003255 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003256 }
3257}
3258
chaviw09c8d2d2020-08-24 15:48:26 -07003259std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3260 size_t size;
3261 switch (event.type) {
3262 case VerifiedInputEvent::Type::KEY: {
3263 size = sizeof(VerifiedKeyEvent);
3264 break;
3265 }
3266 case VerifiedInputEvent::Type::MOTION: {
3267 size = sizeof(VerifiedMotionEvent);
3268 break;
3269 }
3270 }
3271 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3272 return mHmacKeyManager.sign(start, size);
3273}
3274
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003275const std::array<uint8_t, 32> InputDispatcher::getSignature(
3276 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3277 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3278 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3279 // Only sign events up and down events as the purely move events
3280 // are tied to their up/down counterparts so signing would be redundant.
3281 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3282 verifiedEvent.actionMasked = actionMasked;
3283 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003284 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003285 }
3286 return INVALID_HMAC;
3287}
3288
3289const std::array<uint8_t, 32> InputDispatcher::getSignature(
3290 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3291 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3292 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3293 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003294 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003295}
3296
Michael Wrightd02c5b62014-02-10 15:10:22 -08003297void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003298 const sp<Connection>& connection, uint32_t seq,
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10003299 bool handled, nsecs_t consumeTime) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003300 if (DEBUG_DISPATCH_CYCLE) {
3301 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
3302 connection->getInputChannelName().c_str(), seq, toString(handled));
3303 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003304
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003305 if (connection->status == Connection::STATUS_BROKEN ||
3306 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003307 return;
3308 }
3309
3310 // Notify other system components and prepare to start the next dispatch cycle.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003311 auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
3312 doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
3313 };
3314 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003315}
3316
3317void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003318 const sp<Connection>& connection,
3319 bool notify) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003320 if (DEBUG_DISPATCH_CYCLE) {
3321 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
3322 connection->getInputChannelName().c_str(), toString(notify));
3323 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003324
3325 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003326 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003327 traceOutboundQueueLength(*connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003328 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00003329 traceWaitQueueLength(*connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003330
3331 // The connection appears to be unrecoverably broken.
3332 // Ignore already broken or zombie connections.
3333 if (connection->status == Connection::STATUS_NORMAL) {
3334 connection->status = Connection::STATUS_BROKEN;
3335
3336 if (notify) {
3337 // Notify other system components.
Prabir Pradhancef936d2021-07-21 16:17:52 +00003338 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
3339 connection->getInputChannelName().c_str());
3340
3341 auto command = [this, connection]() REQUIRES(mLock) {
3342 if (connection->status == Connection::STATUS_ZOMBIE) return;
3343 scoped_unlock unlock(mLock);
3344 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
3345 };
3346 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003347 }
3348 }
3349}
3350
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003351void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3352 while (!queue.empty()) {
3353 DispatchEntry* dispatchEntry = queue.front();
3354 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003355 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003356 }
3357}
3358
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003359void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003360 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003361 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003362 }
3363 delete dispatchEntry;
3364}
3365
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003366int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
3367 std::scoped_lock _l(mLock);
3368 sp<Connection> connection = getConnectionLocked(connectionToken);
3369 if (connection == nullptr) {
3370 ALOGW("Received looper callback for unknown input channel token %p. events=0x%x",
3371 connectionToken.get(), events);
3372 return 0; // remove the callback
3373 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003374
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003375 bool notify;
3376 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3377 if (!(events & ALOOPER_EVENT_INPUT)) {
3378 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
3379 "events=0x%x",
3380 connection->getInputChannelName().c_str(), events);
3381 return 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003382 }
3383
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003384 nsecs_t currentTime = now();
3385 bool gotOne = false;
3386 status_t status = OK;
3387 for (;;) {
3388 Result<InputPublisher::ConsumerResponse> result =
3389 connection->inputPublisher.receiveConsumerResponse();
3390 if (!result.ok()) {
3391 status = result.error().code();
3392 break;
3393 }
3394
3395 if (std::holds_alternative<InputPublisher::Finished>(*result)) {
3396 const InputPublisher::Finished& finish =
3397 std::get<InputPublisher::Finished>(*result);
3398 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
3399 finish.consumeTime);
3400 } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00003401 if (shouldReportMetricsForConnection(*connection)) {
3402 const InputPublisher::Timeline& timeline =
3403 std::get<InputPublisher::Timeline>(*result);
3404 mLatencyTracker
3405 .trackGraphicsLatency(timeline.inputEventId,
3406 connection->inputChannel->getConnectionToken(),
3407 std::move(timeline.graphicsTimeline));
3408 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003409 }
3410 gotOne = true;
3411 }
3412 if (gotOne) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00003413 runCommandsLockedInterruptable();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003414 if (status == WOULD_BLOCK) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003415 return 1;
3416 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003417 }
3418
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003419 notify = status != DEAD_OBJECT || !connection->monitor;
3420 if (notify) {
3421 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%s(%d)",
3422 connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3423 status);
3424 }
3425 } else {
3426 // Monitor channels are never explicitly unregistered.
3427 // We do it automatically when the remote endpoint is closed so don't warn about them.
3428 const bool stillHaveWindowHandle =
3429 getWindowHandleLocked(connection->inputChannel->getConnectionToken()) != nullptr;
3430 notify = !connection->monitor && stillHaveWindowHandle;
3431 if (notify) {
3432 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. events=0x%x",
3433 connection->getInputChannelName().c_str(), events);
3434 }
3435 }
3436
3437 // Remove the channel.
3438 removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
3439 return 0; // remove the callback
Michael Wrightd02c5b62014-02-10 15:10:22 -08003440}
3441
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003442void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003443 const CancelationOptions& options) {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00003444 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003445 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003446 }
3447}
3448
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003449void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003450 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003451 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3452 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3453}
3454
3455void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3456 const CancelationOptions& options,
3457 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3458 for (const auto& it : monitorsByDisplay) {
3459 const std::vector<Monitor>& monitors = it.second;
3460 for (const Monitor& monitor : monitors) {
3461 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003462 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003463 }
3464}
3465
Michael Wrightd02c5b62014-02-10 15:10:22 -08003466void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003467 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003468 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003469 if (connection == nullptr) {
3470 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003471 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003472
3473 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003474}
3475
3476void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3477 const sp<Connection>& connection, const CancelationOptions& options) {
3478 if (connection->status == Connection::STATUS_BROKEN) {
3479 return;
3480 }
3481
3482 nsecs_t currentTime = now();
3483
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003484 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003485 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003486
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003487 if (cancelationEvents.empty()) {
3488 return;
3489 }
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003490 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3491 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3492 "with reality: %s, mode=%d.",
3493 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3494 options.mode);
3495 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003496
3497 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003498 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003499 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3500 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003501 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003502 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003503 target.globalScaleFactor = windowInfo->globalScaleFactor;
3504 }
3505 target.inputChannel = connection->inputChannel;
3506 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3507
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003508 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003509 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003510 switch (cancelationEventEntry->type) {
3511 case EventEntry::Type::KEY: {
3512 logOutboundKeyDetails("cancel - ",
3513 static_cast<const KeyEntry&>(*cancelationEventEntry));
3514 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003515 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003516 case EventEntry::Type::MOTION: {
3517 logOutboundMotionDetails("cancel - ",
3518 static_cast<const MotionEntry&>(*cancelationEventEntry));
3519 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003520 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003521 case EventEntry::Type::FOCUS:
arthurhungb89ccb02020-12-30 16:19:01 +08003522 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3523 case EventEntry::Type::DRAG: {
Prabir Pradhan99987712020-11-10 18:43:05 -08003524 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003525 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003526 break;
3527 }
3528 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003529 case EventEntry::Type::DEVICE_RESET:
3530 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003531 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003532 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003533 break;
3534 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003535 }
3536
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003537 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3538 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003539 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003540
3541 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003542}
3543
Svet Ganov5d3bc372020-01-26 23:11:07 -08003544void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3545 const sp<Connection>& connection) {
3546 if (connection->status == Connection::STATUS_BROKEN) {
3547 return;
3548 }
3549
3550 nsecs_t currentTime = now();
3551
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003552 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003553 connection->inputState.synthesizePointerDownEvents(currentTime);
3554
3555 if (downEvents.empty()) {
3556 return;
3557 }
3558
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003559 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003560 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3561 connection->getInputChannelName().c_str(), downEvents.size());
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003562 }
Svet Ganov5d3bc372020-01-26 23:11:07 -08003563
3564 InputTarget target;
chaviw98318de2021-05-19 16:45:23 -05003565 sp<WindowInfoHandle> windowHandle =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003566 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3567 if (windowHandle != nullptr) {
chaviw98318de2021-05-19 16:45:23 -05003568 const WindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003569 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003570 target.globalScaleFactor = windowInfo->globalScaleFactor;
3571 }
3572 target.inputChannel = connection->inputChannel;
3573 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3574
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003575 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003576 switch (downEventEntry->type) {
3577 case EventEntry::Type::MOTION: {
3578 logOutboundMotionDetails("down - ",
3579 static_cast<const MotionEntry&>(*downEventEntry));
3580 break;
3581 }
3582
3583 case EventEntry::Type::KEY:
3584 case EventEntry::Type::FOCUS:
3585 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003586 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003587 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
arthurhungb89ccb02020-12-30 16:19:01 +08003588 case EventEntry::Type::SENSOR:
3589 case EventEntry::Type::DRAG: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003590 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003591 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003592 break;
3593 }
3594 }
3595
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003596 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3597 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003598 }
3599
3600 startDispatchCycleLocked(currentTime, connection);
3601}
3602
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003603std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3604 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605 ALOG_ASSERT(pointerIds.value != 0);
3606
3607 uint32_t splitPointerIndexMap[MAX_POINTERS];
3608 PointerProperties splitPointerProperties[MAX_POINTERS];
3609 PointerCoords splitPointerCoords[MAX_POINTERS];
3610
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003611 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003612 uint32_t splitPointerCount = 0;
3613
3614 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003615 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003616 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003617 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003618 uint32_t pointerId = uint32_t(pointerProperties.id);
3619 if (pointerIds.hasBit(pointerId)) {
3620 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3621 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3622 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003623 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003624 splitPointerCount += 1;
3625 }
3626 }
3627
3628 if (splitPointerCount != pointerIds.count()) {
3629 // This is bad. We are missing some of the pointers that we expected to deliver.
3630 // Most likely this indicates that we received an ACTION_MOVE events that has
3631 // different pointer ids than we expected based on the previous ACTION_DOWN
3632 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3633 // in this way.
3634 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003635 "we expected there to be %d pointers. This probably means we received "
3636 "a broken sequence of pointer ids from the input device.",
3637 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003638 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003639 }
3640
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003641 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003642 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003643 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3644 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3646 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003647 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003648 uint32_t pointerId = uint32_t(pointerProperties.id);
3649 if (pointerIds.hasBit(pointerId)) {
3650 if (pointerIds.count() == 1) {
3651 // The first/last pointer went down/up.
3652 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003653 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003654 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3655 ? AMOTION_EVENT_ACTION_CANCEL
3656 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003657 } else {
3658 // A secondary pointer went down/up.
3659 uint32_t splitPointerIndex = 0;
3660 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3661 splitPointerIndex += 1;
3662 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003663 action = maskedAction |
3664 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003665 }
3666 } else {
3667 // An unrelated pointer changed.
3668 action = AMOTION_EVENT_ACTION_MOVE;
3669 }
3670 }
3671
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003672 int32_t newId = mIdGenerator.nextId();
3673 if (ATRACE_ENABLED()) {
3674 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3675 ") to MotionEvent(id=0x%" PRIx32 ").",
3676 originalMotionEntry.id, newId);
3677 ATRACE_NAME(message.c_str());
3678 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003679 std::unique_ptr<MotionEntry> splitMotionEntry =
3680 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3681 originalMotionEntry.deviceId, originalMotionEntry.source,
3682 originalMotionEntry.displayId,
3683 originalMotionEntry.policyFlags, action,
3684 originalMotionEntry.actionButton,
3685 originalMotionEntry.flags, originalMotionEntry.metaState,
3686 originalMotionEntry.buttonState,
3687 originalMotionEntry.classification,
3688 originalMotionEntry.edgeFlags,
3689 originalMotionEntry.xPrecision,
3690 originalMotionEntry.yPrecision,
3691 originalMotionEntry.xCursorPosition,
3692 originalMotionEntry.yCursorPosition,
3693 originalMotionEntry.downTime, splitPointerCount,
3694 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003695
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003696 if (originalMotionEntry.injectionState) {
3697 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003698 splitMotionEntry->injectionState->refCount += 1;
3699 }
3700
3701 return splitMotionEntry;
3702}
3703
3704void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003705 if (DEBUG_INBOUND_EVENT_DETAILS) {
3706 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
3707 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003708
3709 bool needWake;
3710 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003711 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003712
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003713 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3714 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3715 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003716 } // release lock
3717
3718 if (needWake) {
3719 mLooper->wake();
3720 }
3721}
3722
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003723/**
3724 * If one of the meta shortcuts is detected, process them here:
3725 * Meta + Backspace -> generate BACK
3726 * Meta + Enter -> generate HOME
3727 * This will potentially overwrite keyCode and metaState.
3728 */
3729void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003730 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003731 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3732 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3733 if (keyCode == AKEYCODE_DEL) {
3734 newKeyCode = AKEYCODE_BACK;
3735 } else if (keyCode == AKEYCODE_ENTER) {
3736 newKeyCode = AKEYCODE_HOME;
3737 }
3738 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003739 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003740 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003741 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003742 keyCode = newKeyCode;
3743 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3744 }
3745 } else if (action == AKEY_EVENT_ACTION_UP) {
3746 // In order to maintain a consistent stream of up and down events, check to see if the key
3747 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3748 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003749 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003750 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003751 auto replacementIt = mReplacedKeys.find(replacement);
3752 if (replacementIt != mReplacedKeys.end()) {
3753 keyCode = replacementIt->second;
3754 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003755 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3756 }
3757 }
3758}
3759
Michael Wrightd02c5b62014-02-10 15:10:22 -08003760void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003761 if (DEBUG_INBOUND_EVENT_DETAILS) {
3762 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3763 "policyFlags=0x%x, action=0x%x, "
3764 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3765 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3766 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3767 args->downTime);
3768 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003769 if (!validateKeyEvent(args->action)) {
3770 return;
3771 }
3772
3773 uint32_t policyFlags = args->policyFlags;
3774 int32_t flags = args->flags;
3775 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003776 // InputDispatcher tracks and generates key repeats on behalf of
3777 // whatever notifies it, so repeatCount should always be set to 0
3778 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3780 policyFlags |= POLICY_FLAG_VIRTUAL;
3781 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3782 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003783 if (policyFlags & POLICY_FLAG_FUNCTION) {
3784 metaState |= AMETA_FUNCTION_ON;
3785 }
3786
3787 policyFlags |= POLICY_FLAG_TRUSTED;
3788
Michael Wright78f24442014-08-06 15:55:28 -07003789 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003790 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003791
Michael Wrightd02c5b62014-02-10 15:10:22 -08003792 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003793 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003794 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3795 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003796
Michael Wright2b3c3302018-03-02 17:19:13 +00003797 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003798 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003799 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3800 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003801 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003802 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003803
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804 bool needWake;
3805 { // acquire lock
3806 mLock.lock();
3807
3808 if (shouldSendKeyToInputFilterLocked(args)) {
3809 mLock.unlock();
3810
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00003811 policyFlags |= POLICY_FLAG_FILTERED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3813 return; // event was consumed by the filter
3814 }
3815
3816 mLock.lock();
3817 }
3818
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003819 std::unique_ptr<KeyEntry> newEntry =
3820 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3821 args->displayId, policyFlags, args->action, flags,
3822 keyCode, args->scanCode, metaState, repeatCount,
3823 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003824
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003825 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003826 mLock.unlock();
3827 } // release lock
3828
3829 if (needWake) {
3830 mLooper->wake();
3831 }
3832}
3833
3834bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3835 return mInputFilterEnabled;
3836}
3837
3838void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003839 if (DEBUG_INBOUND_EVENT_DETAILS) {
3840 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3841 "displayId=%" PRId32 ", policyFlags=0x%x, "
3842 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3843 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
3844 "yCursorPosition=%f, downTime=%" PRId64,
3845 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3846 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3847 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3848 args->xCursorPosition, args->yCursorPosition, args->downTime);
3849 for (uint32_t i = 0; i < args->pointerCount; i++) {
3850 ALOGD(" Pointer %d: id=%d, toolType=%d, "
3851 "x=%f, y=%f, pressure=%f, size=%f, "
3852 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3853 "orientation=%f",
3854 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3855 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3856 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3857 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3858 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3859 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3860 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3861 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3862 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3863 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
3864 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003865 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003866 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3867 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003868 return;
3869 }
3870
3871 uint32_t policyFlags = args->policyFlags;
3872 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003873
3874 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003875 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003876 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3877 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003878 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003879 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003880
3881 bool needWake;
3882 { // acquire lock
3883 mLock.lock();
3884
3885 if (shouldSendMotionToInputFilterLocked(args)) {
3886 mLock.unlock();
3887
3888 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003889 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003890 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3891 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003892 args->metaState, args->buttonState, args->classification, transform,
3893 args->xPrecision, args->yPrecision, args->xCursorPosition,
Evan Rosky09576692021-07-01 12:22:09 -07003894 args->yCursorPosition, ui::Transform::ROT_0, INVALID_DISPLAY_SIZE,
3895 INVALID_DISPLAY_SIZE, args->downTime, args->eventTime,
3896 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003897
3898 policyFlags |= POLICY_FLAG_FILTERED;
3899 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3900 return; // event was consumed by the filter
3901 }
3902
3903 mLock.lock();
3904 }
3905
3906 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003907 std::unique_ptr<MotionEntry> newEntry =
3908 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3909 args->source, args->displayId, policyFlags,
3910 args->action, args->actionButton, args->flags,
3911 args->metaState, args->buttonState,
3912 args->classification, args->edgeFlags,
3913 args->xPrecision, args->yPrecision,
3914 args->xCursorPosition, args->yCursorPosition,
3915 args->downTime, args->pointerCount,
3916 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003917
Siarhei Vishniakou363e7292021-07-09 03:22:42 +00003918 if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
3919 IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
3920 !mInputFilterEnabled) {
3921 const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
3922 mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
3923 }
3924
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003925 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 mLock.unlock();
3927 } // release lock
3928
3929 if (needWake) {
3930 mLooper->wake();
3931 }
3932}
3933
Chris Yef59a2f42020-10-16 12:55:26 -07003934void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003935 if (DEBUG_INBOUND_EVENT_DETAILS) {
3936 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3937 " sensorType=%s",
3938 args->id, args->eventTime, args->deviceId, args->source,
3939 NamedEnum::string(args->sensorType).c_str());
3940 }
Chris Yef59a2f42020-10-16 12:55:26 -07003941
3942 bool needWake;
3943 { // acquire lock
3944 mLock.lock();
3945
3946 // Just enqueue a new sensor event.
3947 std::unique_ptr<SensorEntry> newEntry =
3948 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3949 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3950 args->sensorType, args->accuracy,
3951 args->accuracyChanged, args->values);
3952
3953 needWake = enqueueInboundEventLocked(std::move(newEntry));
3954 mLock.unlock();
3955 } // release lock
3956
3957 if (needWake) {
3958 mLooper->wake();
3959 }
3960}
3961
Chris Yefb552902021-02-03 17:18:37 -08003962void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003963 if (DEBUG_INBOUND_EVENT_DETAILS) {
3964 ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args->eventTime,
3965 args->deviceId, args->isOn);
3966 }
Chris Yefb552902021-02-03 17:18:37 -08003967 mPolicy->notifyVibratorState(args->deviceId, args->isOn);
3968}
3969
Michael Wrightd02c5b62014-02-10 15:10:22 -08003970bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003971 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972}
3973
3974void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003975 if (DEBUG_INBOUND_EVENT_DETAILS) {
3976 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
3977 "switchMask=0x%08x",
3978 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
3979 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003980
3981 uint32_t policyFlags = args->policyFlags;
3982 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003983 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984}
3985
3986void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00003987 if (DEBUG_INBOUND_EVENT_DETAILS) {
3988 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3989 args->deviceId);
3990 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003991
3992 bool needWake;
3993 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003994 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003995
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003996 std::unique_ptr<DeviceResetEntry> newEntry =
3997 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3998 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003999 } // release lock
4000
4001 if (needWake) {
4002 mLooper->wake();
4003 }
4004}
4005
Prabir Pradhan7e186182020-11-10 13:56:45 -08004006void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004007 if (DEBUG_INBOUND_EVENT_DETAILS) {
4008 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
4009 args->enabled ? "true" : "false");
4010 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004011
Prabir Pradhan99987712020-11-10 18:43:05 -08004012 bool needWake;
4013 { // acquire lock
4014 std::scoped_lock _l(mLock);
4015 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
4016 args->enabled);
4017 needWake = enqueueInboundEventLocked(std::move(entry));
4018 } // release lock
4019
4020 if (needWake) {
4021 mLooper->wake();
4022 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08004023}
4024
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004025InputEventInjectionResult InputDispatcher::injectInputEvent(
4026 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
4027 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004028 if (DEBUG_INBOUND_EVENT_DETAILS) {
4029 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
4030 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
4031 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
4032 }
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004033 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004034
4035 policyFlags |= POLICY_FLAG_INJECTED;
4036 if (hasInjectionPermission(injectorPid, injectorUid)) {
4037 policyFlags |= POLICY_FLAG_TRUSTED;
4038 }
4039
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004040 // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004041 // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4042 // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4043 // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4044 // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4045 // from events that originate from actual hardware.
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004046 int32_t resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004047 if (policyFlags & POLICY_FLAG_FILTERED) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004048 resolvedDeviceId = event->getDeviceId();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004049 }
4050
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004051 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004052 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004053 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004054 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4055 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004056 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004057 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00004058 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004060 int32_t flags = incomingKey.getFlags();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004061 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4062 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4063 }
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004064 int32_t keyCode = incomingKey.getKeyCode();
4065 int32_t metaState = incomingKey.getMetaState();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004066 accelerateMetaShortcuts(resolvedDeviceId, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004067 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004068 KeyEvent keyEvent;
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004069 keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08004070 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4071 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4072 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004073
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004074 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4075 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00004076 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004077
4078 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4079 android::base::Timer t;
4080 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
4081 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4082 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4083 std::to_string(t.duration().count()).c_str());
4084 }
4085 }
4086
4087 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004088 std::unique_ptr<KeyEntry> injectedEntry =
4089 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004090 resolvedDeviceId, incomingKey.getSource(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004091 incomingKey.getDisplayId(), policyFlags, action,
4092 flags, keyCode, incomingKey.getScanCode(), metaState,
4093 incomingKey.getRepeatCount(),
4094 incomingKey.getDownTime());
4095 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004096 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004097 }
4098
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004099 case AINPUT_EVENT_TYPE_MOTION: {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004100 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4101 int32_t action = motionEvent.getAction();
4102 size_t pointerCount = motionEvent.getPointerCount();
4103 const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
4104 int32_t actionButton = motionEvent.getActionButton();
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004105 int32_t flags = motionEvent.getFlags();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004106 int32_t displayId = motionEvent.getDisplayId();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004107 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004108 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004109 }
4110
4111 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004112 nsecs_t eventTime = motionEvent.getEventTime();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004113 android::base::Timer t;
4114 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
4115 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4116 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4117 std::to_string(t.duration().count()).c_str());
4118 }
4119 }
4120
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004121 if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4122 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4123 }
4124
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004125 mLock.lock();
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004126 const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4127 const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004128 std::unique_ptr<MotionEntry> injectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004129 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4130 resolvedDeviceId, motionEvent.getSource(),
4131 motionEvent.getDisplayId(), policyFlags, action,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004132 actionButton, flags, motionEvent.getMetaState(),
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004133 motionEvent.getButtonState(),
4134 motionEvent.getClassification(),
4135 motionEvent.getEdgeFlags(),
4136 motionEvent.getXPrecision(),
4137 motionEvent.getYPrecision(),
4138 motionEvent.getRawXCursorPosition(),
4139 motionEvent.getRawYCursorPosition(),
4140 motionEvent.getDownTime(), uint32_t(pointerCount),
4141 pointerProperties, samplePointerCoords,
4142 motionEvent.getXOffset(),
4143 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004144 injectedEntries.push(std::move(injectedEntry));
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004145 for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004146 sampleEventTimes += 1;
4147 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004148 std::unique_ptr<MotionEntry> nextInjectedEntry =
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004149 std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
4150 resolvedDeviceId, motionEvent.getSource(),
4151 motionEvent.getDisplayId(), policyFlags,
Siarhei Vishniakouf00a4ec2021-06-16 03:55:32 +00004152 action, actionButton, flags,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004153 motionEvent.getMetaState(),
4154 motionEvent.getButtonState(),
4155 motionEvent.getClassification(),
4156 motionEvent.getEdgeFlags(),
4157 motionEvent.getXPrecision(),
4158 motionEvent.getYPrecision(),
4159 motionEvent.getRawXCursorPosition(),
4160 motionEvent.getRawYCursorPosition(),
4161 motionEvent.getDownTime(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004162 uint32_t(pointerCount), pointerProperties,
Siarhei Vishniakou5d552c42021-05-21 05:02:22 +00004163 samplePointerCoords, motionEvent.getXOffset(),
4164 motionEvent.getYOffset());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004165 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004166 }
4167 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004168 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004169
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004170 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08004171 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004172 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004173 }
4174
4175 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004176 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004177 injectionState->injectionIsAsync = true;
4178 }
4179
4180 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004181 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004182
4183 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004184 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004185 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004186 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004187 }
4188
4189 mLock.unlock();
4190
4191 if (needWake) {
4192 mLooper->wake();
4193 }
4194
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004195 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004196 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004197 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004198
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004199 if (syncMode == InputEventInjectionSync::NONE) {
4200 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004201 } else {
4202 for (;;) {
4203 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004204 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004205 break;
4206 }
4207
4208 nsecs_t remainingTimeout = endTime - now();
4209 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004210 if (DEBUG_INJECTION) {
4211 ALOGD("injectInputEvent - Timed out waiting for injection result "
4212 "to become available.");
4213 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004214 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004215 break;
4216 }
4217
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004218 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004219 }
4220
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004221 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
4222 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004223 while (injectionState->pendingForegroundDispatches != 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004224 if (DEBUG_INJECTION) {
4225 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
4226 injectionState->pendingForegroundDispatches);
4227 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004228 nsecs_t remainingTimeout = endTime - now();
4229 if (remainingTimeout <= 0) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004230 if (DEBUG_INJECTION) {
4231 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4232 "dispatches to finish.");
4233 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004234 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004235 break;
4236 }
4237
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004238 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004239 }
4240 }
4241 }
4242
4243 injectionState->release();
4244 } // release lock
4245
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004246 if (DEBUG_INJECTION) {
4247 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
4248 injectionResult, injectorPid, injectorUid);
4249 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004250
4251 return injectionResult;
4252}
4253
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004254std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004255 std::array<uint8_t, 32> calculatedHmac;
4256 std::unique_ptr<VerifiedInputEvent> result;
4257 switch (event.getType()) {
4258 case AINPUT_EVENT_TYPE_KEY: {
4259 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4260 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4261 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004262 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004263 break;
4264 }
4265 case AINPUT_EVENT_TYPE_MOTION: {
4266 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4267 VerifiedMotionEvent verifiedMotionEvent =
4268 verifiedMotionEventFromMotionEvent(motionEvent);
4269 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004270 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004271 break;
4272 }
4273 default: {
4274 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4275 return nullptr;
4276 }
4277 }
4278 if (calculatedHmac == INVALID_HMAC) {
4279 return nullptr;
4280 }
4281 if (calculatedHmac != event.getHmac()) {
4282 return nullptr;
4283 }
4284 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004285}
4286
Michael Wrightd02c5b62014-02-10 15:10:22 -08004287bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004288 return injectorUid == 0 ||
4289 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004290}
4291
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004292void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004293 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004294 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004295 if (injectionState) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00004296 if (DEBUG_INJECTION) {
4297 ALOGD("Setting input event injection result to %d. "
4298 "injectorPid=%d, injectorUid=%d",
4299 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
4300 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004301
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004302 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004303 // Log the outcome since the injector did not wait for the injection result.
4304 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004305 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004306 ALOGV("Asynchronous input event injection succeeded.");
4307 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004308 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004309 ALOGW("Asynchronous input event injection failed.");
4310 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004311 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004312 ALOGW("Asynchronous input event injection permission denied.");
4313 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004314 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004315 ALOGW("Asynchronous input event injection timed out.");
4316 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004317 case InputEventInjectionResult::PENDING:
4318 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4319 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004320 }
4321 }
4322
4323 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004324 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325 }
4326}
4327
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004328void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4329 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004330 if (injectionState) {
4331 injectionState->pendingForegroundDispatches += 1;
4332 }
4333}
4334
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004335void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4336 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337 if (injectionState) {
4338 injectionState->pendingForegroundDispatches -= 1;
4339
4340 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004341 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004342 }
4343 }
4344}
4345
chaviw98318de2021-05-19 16:45:23 -05004346const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004347 int32_t displayId) const {
chaviw98318de2021-05-19 16:45:23 -05004348 static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
Vishnu Nairad321cd2020-08-20 16:40:21 -07004349 auto it = mWindowHandlesByDisplay.find(displayId);
4350 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004351}
4352
chaviw98318de2021-05-19 16:45:23 -05004353sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004354 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004355 if (windowHandleToken == nullptr) {
4356 return nullptr;
4357 }
4358
Arthur Hungb92218b2018-08-14 12:00:21 +08004359 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004360 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4361 for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004362 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004363 return windowHandle;
4364 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004365 }
4366 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004367 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004368}
4369
chaviw98318de2021-05-19 16:45:23 -05004370sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4371 int displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004372 if (windowHandleToken == nullptr) {
4373 return nullptr;
4374 }
4375
chaviw98318de2021-05-19 16:45:23 -05004376 for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004377 if (windowHandle->getToken() == windowHandleToken) {
4378 return windowHandle;
4379 }
4380 }
4381 return nullptr;
4382}
4383
chaviw98318de2021-05-19 16:45:23 -05004384sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
4385 const sp<WindowInfoHandle>& windowHandle) const {
Mady Mellor017bcd12020-06-23 19:12:00 +00004386 for (auto& it : mWindowHandlesByDisplay) {
chaviw98318de2021-05-19 16:45:23 -05004387 const std::vector<sp<WindowInfoHandle>>& windowHandles = it.second;
4388 for (const sp<WindowInfoHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004389 if (handle->getId() == windowHandle->getId() &&
4390 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004391 if (windowHandle->getInfo()->displayId != it.first) {
4392 ALOGE("Found window %s in display %" PRId32
4393 ", but it should belong to display %" PRId32,
4394 windowHandle->getName().c_str(), it.first,
4395 windowHandle->getInfo()->displayId);
4396 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004397 return handle;
Arthur Hungb92218b2018-08-14 12:00:21 +08004398 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004399 }
4400 }
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004401 return nullptr;
4402}
4403
chaviw98318de2021-05-19 16:45:23 -05004404sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004405 sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
4406 return getWindowHandleLocked(focusedToken, displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004407}
4408
chaviw98318de2021-05-19 16:45:23 -05004409bool InputDispatcher::hasResponsiveConnectionLocked(WindowInfoHandle& windowHandle) const {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004410 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4411 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004412 windowHandle.getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004413 if (connection != nullptr && noInputChannel) {
4414 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4415 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4416 return false;
4417 }
4418
4419 if (connection == nullptr) {
4420 if (!noInputChannel) {
4421 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4422 }
4423 return false;
4424 }
4425 if (!connection->responsive) {
4426 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4427 return false;
4428 }
4429 return true;
4430}
4431
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004432std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4433 const sp<IBinder>& token) const {
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004434 auto connectionIt = mConnectionsByToken.find(token);
4435 if (connectionIt == mConnectionsByToken.end()) {
Robert Carr5c8a0262018-10-03 16:30:44 -07004436 return nullptr;
4437 }
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00004438 return connectionIt->second->inputChannel;
Robert Carr5c8a0262018-10-03 16:30:44 -07004439}
4440
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004441void InputDispatcher::updateWindowHandlesForDisplayLocked(
chaviw98318de2021-05-19 16:45:23 -05004442 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
4443 if (windowInfoHandles.empty()) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004444 // Remove all handles on a display if there are no windows left.
4445 mWindowHandlesByDisplay.erase(displayId);
4446 return;
4447 }
4448
4449 // Since we compare the pointer of input window handles across window updates, we need
4450 // to make sure the handle object for the same window stays unchanged across updates.
chaviw98318de2021-05-19 16:45:23 -05004451 const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
4452 std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
4453 for (const sp<WindowInfoHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004454 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004455 }
4456
chaviw98318de2021-05-19 16:45:23 -05004457 std::vector<sp<WindowInfoHandle>> newHandles;
4458 for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
chaviw98318de2021-05-19 16:45:23 -05004459 const WindowInfo* info = handle->getInfo();
Siarhei Vishniakou64452932020-11-06 17:51:32 -06004460 if (getInputChannelLocked(handle->getToken()) == nullptr) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004461 const bool noInputChannel =
chaviw98318de2021-05-19 16:45:23 -05004462 info->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
4463 const bool canReceiveInput = !info->flags.test(WindowInfo::Flag::NOT_TOUCHABLE) ||
4464 !info->flags.test(WindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004465 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004466 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004467 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004468 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004469 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004470 }
4471
4472 if (info->displayId != displayId) {
4473 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4474 handle->getName().c_str(), displayId, info->displayId);
4475 continue;
4476 }
4477
Robert Carredd13602020-04-13 17:24:34 -07004478 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4479 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviw98318de2021-05-19 16:45:23 -05004480 const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004481 oldHandle->updateFrom(handle);
4482 newHandles.push_back(oldHandle);
4483 } else {
4484 newHandles.push_back(handle);
4485 }
4486 }
4487
4488 // Insert or replace
4489 mWindowHandlesByDisplay[displayId] = newHandles;
4490}
4491
Arthur Hung72d8dc32020-03-28 00:48:39 +00004492void InputDispatcher::setInputWindows(
chaviw98318de2021-05-19 16:45:23 -05004493 const std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>>& handlesPerDisplay) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07004494 // TODO(b/198444055): Remove setInputWindows from InputDispatcher.
Arthur Hung72d8dc32020-03-28 00:48:39 +00004495 { // acquire lock
4496 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004497 for (const auto& [displayId, handles] : handlesPerDisplay) {
4498 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004499 }
4500 }
4501 // Wake up poll loop since it may need to make new input dispatching choices.
4502 mLooper->wake();
4503}
4504
Arthur Hungb92218b2018-08-14 12:00:21 +08004505/**
4506 * Called from InputManagerService, update window handle list by displayId that can receive input.
4507 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4508 * If set an empty list, remove all handles from the specific display.
4509 * For focused handle, check if need to change and send a cancel event to previous one.
4510 * For removed handle, check if need to send a cancel event if already in touch.
4511 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004512void InputDispatcher::setInputWindowsLocked(
chaviw98318de2021-05-19 16:45:23 -05004513 const std::vector<sp<WindowInfoHandle>>& windowInfoHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004514 if (DEBUG_FOCUS) {
4515 std::string windowList;
chaviw98318de2021-05-19 16:45:23 -05004516 for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004517 windowList += iwh->getName() + " ";
4518 }
4519 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4520 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004521
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004522 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
chaviw98318de2021-05-19 16:45:23 -05004523 for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004524 const bool noInputWindow =
chaviw98318de2021-05-19 16:45:23 -05004525 window->getInfo()->inputFeatures.test(WindowInfo::Feature::NO_INPUT_CHANNEL);
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004526 if (noInputWindow && window->getToken() != nullptr) {
4527 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4528 window->getName().c_str());
4529 window->releaseChannel();
4530 }
4531 }
4532
Arthur Hung72d8dc32020-03-28 00:48:39 +00004533 // Copy old handles for release if they are no longer present.
chaviw98318de2021-05-19 16:45:23 -05004534 const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004535
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004536 // Save the old windows' orientation by ID before it gets updated.
4537 std::unordered_map<int32_t, uint32_t> oldWindowOrientations;
chaviw98318de2021-05-19 16:45:23 -05004538 for (const sp<WindowInfoHandle>& handle : oldWindowHandles) {
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004539 oldWindowOrientations.emplace(handle->getId(),
4540 handle->getInfo()->transform.getOrientation());
4541 }
4542
chaviw98318de2021-05-19 16:45:23 -05004543 updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004544
chaviw98318de2021-05-19 16:45:23 -05004545 const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Vishnu Nair958da932020-08-21 17:12:37 -07004546 if (mLastHoverWindowHandle &&
4547 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4548 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004549 mLastHoverWindowHandle = nullptr;
4550 }
4551
Vishnu Nairc519ff72021-01-21 08:23:08 -08004552 std::optional<FocusResolver::FocusChanges> changes =
4553 mFocusResolver.setInputWindows(displayId, windowHandles);
4554 if (changes) {
4555 onFocusChangedLocked(*changes);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004556 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004557
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004558 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4559 mTouchStatesByDisplay.find(displayId);
4560 if (stateIt != mTouchStatesByDisplay.end()) {
4561 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004562 for (size_t i = 0; i < state.windows.size();) {
4563 TouchedWindow& touchedWindow = state.windows[i];
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004564 if (getWindowHandleLocked(touchedWindow.windowHandle) == nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004565 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004566 ALOGD("Touched window was removed: %s in display %" PRId32,
4567 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004568 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004569 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004570 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4571 if (touchedInputChannel != nullptr) {
4572 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4573 "touched window was removed");
4574 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004575 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004576 state.windows.erase(state.windows.begin() + i);
4577 } else {
4578 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004579 }
4580 }
arthurhungb89ccb02020-12-30 16:19:01 +08004581
arthurhung6d4bed92021-03-17 11:59:33 +08004582 // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
arthurhungb89ccb02020-12-30 16:19:01 +08004583 // could just clear the state here.
arthurhung6d4bed92021-03-17 11:59:33 +08004584 if (mDragState &&
4585 std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
arthurhungb89ccb02020-12-30 16:19:01 +08004586 windowHandles.end()) {
arthurhung6d4bed92021-03-17 11:59:33 +08004587 mDragState.reset();
arthurhungb89ccb02020-12-30 16:19:01 +08004588 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004589 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004590
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004591 if (isPerWindowInputRotationEnabled()) {
4592 // Determine if the orientation of any of the input windows have changed, and cancel all
4593 // pointer events if necessary.
chaviw98318de2021-05-19 16:45:23 -05004594 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
4595 const sp<WindowInfoHandle> newWindowHandle = getWindowHandleLocked(oldWindowHandle);
Prabir Pradhan93a0f912021-04-21 13:47:42 -07004596 if (newWindowHandle != nullptr &&
4597 newWindowHandle->getInfo()->transform.getOrientation() !=
4598 oldWindowOrientations[oldWindowHandle->getId()]) {
4599 std::shared_ptr<InputChannel> inputChannel =
4600 getInputChannelLocked(newWindowHandle->getToken());
4601 if (inputChannel != nullptr) {
4602 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4603 "touched window's orientation changed");
4604 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4605 }
4606 }
4607 }
4608 }
4609
Arthur Hung72d8dc32020-03-28 00:48:39 +00004610 // Release information for windows that are no longer present.
4611 // This ensures that unused input channels are released promptly.
4612 // Otherwise, they might stick around until the window handle is destroyed
4613 // which might not happen until the next GC.
chaviw98318de2021-05-19 16:45:23 -05004614 for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
Prabir Pradhan6a9a8312021-04-23 11:59:31 -07004615 if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004616 if (DEBUG_FOCUS) {
4617 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004618 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004619 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004620 // To avoid making too many calls into the compat framework, only
4621 // check for window flags when windows are going away.
4622 // TODO(b/157929241) : delete this. This is only needed temporarily
4623 // in order to gather some data about the flag usage
chaviw98318de2021-05-19 16:45:23 -05004624 if (oldWindowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004625 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4626 oldWindowHandle->getName().c_str());
4627 if (mCompatService != nullptr) {
4628 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4629 oldWindowHandle->getInfo()->ownerUid);
4630 }
4631 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004632 }
chaviw291d88a2019-02-14 10:33:58 -08004633 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004634}
4635
4636void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004637 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004638 if (DEBUG_FOCUS) {
4639 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4640 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4641 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004642 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004643 std::scoped_lock _l(mLock);
Vishnu Nair599f1412021-06-21 10:39:58 -07004644 setFocusedApplicationLocked(displayId, inputApplicationHandle);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004645 } // release lock
4646
4647 // Wake up poll loop since it may need to make new input dispatching choices.
4648 mLooper->wake();
4649}
4650
Vishnu Nair599f1412021-06-21 10:39:58 -07004651void InputDispatcher::setFocusedApplicationLocked(
4652 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
4653 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
4654 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
4655
4656 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4657 return; // This application is already focused. No need to wake up or change anything.
4658 }
4659
4660 // Set the new application handle.
4661 if (inputApplicationHandle != nullptr) {
4662 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4663 } else {
4664 mFocusedApplicationHandlesByDisplay.erase(displayId);
4665 }
4666
4667 // No matter what the old focused application was, stop waiting on it because it is
4668 // no longer focused.
4669 resetNoFocusedWindowTimeoutLocked();
4670}
4671
Tiger Huang721e26f2018-07-24 22:26:19 +08004672/**
4673 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4674 * the display not specified.
4675 *
4676 * We track any unreleased events for each window. If a window loses the ability to receive the
4677 * released event, we will send a cancel event to it. So when the focused display is changed, we
4678 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4679 * display. The display-specified events won't be affected.
4680 */
4681void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004682 if (DEBUG_FOCUS) {
4683 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4684 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004685 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004686 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004687
4688 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004689 sp<IBinder> oldFocusedWindowToken =
Vishnu Nairc519ff72021-01-21 08:23:08 -08004690 mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004691 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004692 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004693 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004694 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004695 CancelationOptions
4696 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4697 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004698 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004699 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4700 }
4701 }
4702 mFocusedDisplayId = displayId;
4703
Chris Ye3c2d6f52020-08-09 10:39:48 -07004704 // Find new focused window and validate
Vishnu Nairc519ff72021-01-21 08:23:08 -08004705 sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
Prabir Pradhancef936d2021-07-21 16:17:52 +00004706 sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004707
Vishnu Nairad321cd2020-08-20 16:40:21 -07004708 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004709 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairc519ff72021-01-21 08:23:08 -08004710 if (mFocusResolver.hasFocusedWindowTokens()) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004711 ALOGE("But another display has a focused window\n%s",
Vishnu Nairc519ff72021-01-21 08:23:08 -08004712 mFocusResolver.dumpFocusedWindows().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004713 }
4714 }
4715 }
4716
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004717 if (DEBUG_FOCUS) {
4718 logDispatchStateLocked();
4719 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004720 } // release lock
4721
4722 // Wake up poll loop since it may need to make new input dispatching choices.
4723 mLooper->wake();
4724}
4725
Michael Wrightd02c5b62014-02-10 15:10:22 -08004726void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004727 if (DEBUG_FOCUS) {
4728 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4729 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004730
4731 bool changed;
4732 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004733 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004734
4735 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4736 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004737 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004738 }
4739
4740 if (mDispatchEnabled && !enabled) {
4741 resetAndDropEverythingLocked("dispatcher is being disabled");
4742 }
4743
4744 mDispatchEnabled = enabled;
4745 mDispatchFrozen = frozen;
4746 changed = true;
4747 } else {
4748 changed = false;
4749 }
4750
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004751 if (DEBUG_FOCUS) {
4752 logDispatchStateLocked();
4753 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004754 } // release lock
4755
4756 if (changed) {
4757 // Wake up poll loop since it may need to make new input dispatching choices.
4758 mLooper->wake();
4759 }
4760}
4761
4762void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004763 if (DEBUG_FOCUS) {
4764 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4765 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004766
4767 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004768 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004769
4770 if (mInputFilterEnabled == enabled) {
4771 return;
4772 }
4773
4774 mInputFilterEnabled = enabled;
4775 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4776 } // release lock
4777
4778 // Wake up poll loop since there might be work to do to drop everything.
4779 mLooper->wake();
4780}
4781
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004782void InputDispatcher::setInTouchMode(bool inTouchMode) {
4783 std::scoped_lock lock(mLock);
4784 mInTouchMode = inTouchMode;
4785}
4786
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004787void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4788 if (opacity < 0 || opacity > 1) {
4789 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4790 return;
4791 }
4792
4793 std::scoped_lock lock(mLock);
4794 mMaximumObscuringOpacityForTouch = opacity;
4795}
4796
4797void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4798 std::scoped_lock lock(mLock);
4799 mBlockUntrustedTouchesMode = mode;
4800}
4801
arthurhungb89ccb02020-12-30 16:19:01 +08004802bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
4803 bool isDragDrop) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004804 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004805 if (DEBUG_FOCUS) {
4806 ALOGD("Trivial transfer to same window.");
4807 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004808 return true;
4809 }
4810
Michael Wrightd02c5b62014-02-10 15:10:22 -08004811 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004812 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004813
chaviw98318de2021-05-19 16:45:23 -05004814 sp<WindowInfoHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4815 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004816 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004817 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004818 return false;
4819 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004820 if (DEBUG_FOCUS) {
4821 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4822 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4823 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004824 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004825 if (DEBUG_FOCUS) {
4826 ALOGD("Cannot transfer focus because windows are on different displays.");
4827 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004828 return false;
4829 }
4830
4831 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004832 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4833 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004834 for (size_t i = 0; i < state.windows.size(); i++) {
4835 const TouchedWindow& touchedWindow = state.windows[i];
4836 if (touchedWindow.windowHandle == fromWindowHandle) {
4837 int32_t oldTargetFlags = touchedWindow.targetFlags;
4838 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004839
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004840 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004841
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004842 int32_t newTargetFlags = oldTargetFlags &
4843 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4844 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004845 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004846
arthurhungb89ccb02020-12-30 16:19:01 +08004847 // Store the dragging window.
4848 if (isDragDrop) {
arthurhung6d4bed92021-03-17 11:59:33 +08004849 mDragState = std::make_unique<DragState>(toWindowHandle);
arthurhungb89ccb02020-12-30 16:19:01 +08004850 }
4851
Jeff Brownf086ddb2014-02-11 14:28:48 -08004852 found = true;
4853 goto Found;
4854 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004855 }
4856 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004857 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004858
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004859 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004860 if (DEBUG_FOCUS) {
4861 ALOGD("Focus transfer failed because from window did not have focus.");
4862 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863 return false;
4864 }
4865
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004866 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4867 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004868 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004869 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004870 CancelationOptions
4871 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4872 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004873 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004874 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004875 }
4876
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004877 if (DEBUG_FOCUS) {
4878 logDispatchStateLocked();
4879 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004880 } // release lock
4881
4882 // Wake up poll loop since it may need to make new input dispatching choices.
4883 mLooper->wake();
4884 return true;
4885}
4886
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004887// Binder call
4888bool InputDispatcher::transferTouch(const sp<IBinder>& destChannelToken) {
4889 sp<IBinder> fromToken;
4890 { // acquire lock
4891 std::scoped_lock _l(mLock);
4892
chaviw98318de2021-05-19 16:45:23 -05004893 sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken);
Siarhei Vishniakoud0c6bc82021-03-13 03:14:52 +00004894 if (toWindowHandle == nullptr) {
4895 ALOGW("Could not find window associated with token=%p", destChannelToken.get());
4896 return false;
4897 }
4898
4899 const int32_t displayId = toWindowHandle->getInfo()->displayId;
4900
4901 auto touchStateIt = mTouchStatesByDisplay.find(displayId);
4902 if (touchStateIt == mTouchStatesByDisplay.end()) {
4903 ALOGD("Could not transfer touch because the display %" PRId32 " is not being touched",
4904 displayId);
4905 return false;
4906 }
4907
4908 TouchState& state = touchStateIt->second;
4909 if (state.windows.size() != 1) {
4910 ALOGW("Cannot transfer touch state because there are %zu windows being touched",
4911 state.windows.size());
4912 return false;
4913 }
4914 const TouchedWindow& touchedWindow = state.windows[0];
4915 fromToken = touchedWindow.windowHandle->getToken();
4916 } // release lock
4917
4918 return transferTouchFocus(fromToken, destChannelToken);
4919}
4920
Michael Wrightd02c5b62014-02-10 15:10:22 -08004921void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004922 if (DEBUG_FOCUS) {
4923 ALOGD("Resetting and dropping all events (%s).", reason);
4924 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925
4926 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4927 synthesizeCancelationEventsForAllConnectionsLocked(options);
4928
4929 resetKeyRepeatLocked();
4930 releasePendingEventLocked();
4931 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004932 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004933
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004934 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004935 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004936 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004937 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004938}
4939
4940void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004941 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004942 dumpDispatchStateLocked(dump);
4943
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004944 std::istringstream stream(dump);
4945 std::string line;
4946
4947 while (std::getline(stream, line, '\n')) {
4948 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004949 }
4950}
4951
Prabir Pradhan99987712020-11-10 18:43:05 -08004952std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4953 std::string dump;
4954
4955 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4956 toString(mFocusedWindowRequestedPointerCapture));
4957
4958 std::string windowName = "None";
4959 if (mWindowTokenWithPointerCapture) {
chaviw98318de2021-05-19 16:45:23 -05004960 const sp<WindowInfoHandle> captureWindowHandle =
Prabir Pradhan99987712020-11-10 18:43:05 -08004961 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4962 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4963 : "token has capture without window";
4964 }
4965 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4966
4967 return dump;
4968}
4969
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004970void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004971 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4972 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4973 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004974 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004975
Tiger Huang721e26f2018-07-24 22:26:19 +08004976 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4977 dump += StringPrintf(INDENT "FocusedApplications:\n");
4978 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4979 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004980 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004981 const std::chrono::duration timeout =
4982 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004983 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004984 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004985 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004986 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004987 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004988 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004989 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004990
Vishnu Nairc519ff72021-01-21 08:23:08 -08004991 dump += mFocusResolver.dump();
Prabir Pradhan99987712020-11-10 18:43:05 -08004992 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004993
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004994 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004995 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004996 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4997 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004998 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004999 state.displayId, toString(state.down), toString(state.split),
5000 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005001 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005002 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005003 for (size_t i = 0; i < state.windows.size(); i++) {
5004 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005005 dump += StringPrintf(INDENT4
5006 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
5007 i, touchedWindow.windowHandle->getName().c_str(),
5008 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08005009 }
5010 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005011 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08005012 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005013 }
5014 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005015 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005016 }
5017
arthurhung6d4bed92021-03-17 11:59:33 +08005018 if (mDragState) {
5019 dump += StringPrintf(INDENT "DragState:\n");
5020 mDragState->dump(dump, INDENT2);
5021 }
5022
Arthur Hungb92218b2018-08-14 12:00:21 +08005023 if (!mWindowHandlesByDisplay.empty()) {
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005024 for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5025 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", displayId);
5026 if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
5027 const auto& displayInfo = it->second;
5028 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
5029 displayInfo.logicalHeight);
5030 displayInfo.transform.dump(dump, "transform", INDENT4);
5031 } else {
5032 dump += INDENT2 "No DisplayInfo found!\n";
5033 }
5034
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08005035 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08005036 dump += INDENT2 "Windows:\n";
5037 for (size_t i = 0; i < windowHandles.size(); i++) {
chaviw98318de2021-05-19 16:45:23 -05005038 const sp<WindowInfoHandle>& windowHandle = windowHandles[i];
5039 const WindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08005040
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005041 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005042 "paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005043 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005044 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005045 "frame=[%d,%d][%d,%d], globalScale=%f, "
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005046 "applicationInfo.name=%s, "
5047 "applicationInfo.token=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07005048 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005049 i, windowInfo->name.c_str(), windowInfo->id,
Siarhei Vishniakou64452932020-11-06 17:51:32 -06005050 windowInfo->displayId, toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07005051 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005052 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00005053 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01005054 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005055 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01005056 windowInfo->frameLeft, windowInfo->frameTop,
5057 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05005058 windowInfo->globalScaleFactor,
Bernardo Rufino49d99e42021-01-18 15:16:59 +00005059 windowInfo->applicationInfo.name.c_str(),
5060 toString(windowInfo->applicationInfo.token).c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00005061 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01005062 dump += StringPrintf(", inputFeatures=%s",
5063 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005064 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005065 "ms, trustedOverlay=%s, hasToken=%s, "
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005066 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005067 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00005068 millis(windowInfo->dispatchingTimeout),
5069 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00005070 toString(windowInfo->token != nullptr),
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07005071 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07005072 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08005073 }
5074 } else {
5075 dump += INDENT2 "Windows: <none>\n";
5076 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005077 }
5078 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08005079 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005080 }
5081
Michael Wright3dd60e22019-03-27 22:06:44 +00005082 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005083 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005084 const std::vector<Monitor>& monitors = it.second;
5085 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
5086 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005087 }
5088 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005089 const std::vector<Monitor>& monitors = it.second;
5090 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
5091 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005092 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005093 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00005094 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005095 }
5096
5097 nsecs_t currentTime = now();
5098
5099 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005100 if (!mRecentQueue.empty()) {
5101 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005102 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005103 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005104 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005105 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005106 }
5107 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005108 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005109 }
5110
5111 // Dump event currently being dispatched.
5112 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005113 dump += INDENT "PendingEvent:\n";
5114 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005115 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005116 dump += StringPrintf(", age=%" PRId64 "ms\n",
5117 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005118 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005119 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005120 }
5121
5122 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005123 if (!mInboundQueue.empty()) {
5124 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005125 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005126 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005127 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005128 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005129 }
5130 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005131 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005132 }
5133
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005134 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005135 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005136 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
5137 const KeyReplacement& replacement = pair.first;
5138 int32_t newKeyCode = pair.second;
5139 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005140 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07005141 }
5142 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005143 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07005144 }
5145
Prabir Pradhancef936d2021-07-21 16:17:52 +00005146 if (!mCommandQueue.empty()) {
5147 dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
5148 } else {
5149 dump += INDENT "CommandQueue: <empty>\n";
5150 }
5151
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005152 if (!mConnectionsByToken.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005153 dump += INDENT "Connections:\n";
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005154 for (const auto& [token, connection] : mConnectionsByToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005155 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005156 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005157 connection->inputChannel->getFd().get(),
5158 connection->getInputChannelName().c_str(),
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005159 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005160 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005161
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005162 if (!connection->outboundQueue.empty()) {
5163 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
5164 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005165 dump += dumpQueue(connection->outboundQueue, currentTime);
5166
Michael Wrightd02c5b62014-02-10 15:10:22 -08005167 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005168 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005169 }
5170
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005171 if (!connection->waitQueue.empty()) {
5172 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
5173 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05005174 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005175 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005176 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005177 }
5178 }
5179 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005180 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005181 }
5182
5183 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005184 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
5185 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005186 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005187 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005188 }
5189
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005190 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005191 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
5192 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
5193 ns2ms(mConfig.keyRepeatTimeout));
Siarhei Vishniakouf2652122021-03-05 21:39:46 +00005194 dump += mLatencyTracker.dump(INDENT2);
Siarhei Vishniakoua04181f2021-03-26 05:56:49 +00005195 dump += mLatencyAggregator.dump(INDENT2);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005196}
5197
Michael Wright3dd60e22019-03-27 22:06:44 +00005198void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
5199 const size_t numMonitors = monitors.size();
5200 for (size_t i = 0; i < numMonitors; i++) {
5201 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005202 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005203 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
5204 dump += "\n";
5205 }
5206}
5207
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005208class LooperEventCallback : public LooperCallback {
5209public:
5210 LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
5211 int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
5212
5213private:
5214 std::function<int(int events)> mCallback;
5215};
5216
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005217Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005218 if (DEBUG_CHANNEL_CREATION) {
5219 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
5220 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005221
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005222 std::unique_ptr<InputChannel> serverChannel;
Garfield Tan15601662020-09-22 15:32:38 -07005223 std::unique_ptr<InputChannel> clientChannel;
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005224 status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
Garfield Tan15601662020-09-22 15:32:38 -07005225
5226 if (result) {
5227 return base::Error(result) << "Failed to open input channel pair with name " << name;
5228 }
5229
Michael Wrightd02c5b62014-02-10 15:10:22 -08005230 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005231 std::scoped_lock _l(mLock);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005232 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005233 int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005234 sp<Connection> connection =
5235 new Connection(std::move(serverChannel), false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005236
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005237 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5238 ALOGE("Created a new connection, but the token %p is already known", token.get());
5239 }
5240 mConnectionsByToken.emplace(token, connection);
5241
5242 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5243 this, std::placeholders::_1, token);
5244
5245 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005246 } // release lock
5247
5248 // Wake the looper because some connections have changed.
5249 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005250 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005251}
5252
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +00005253Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
5254 bool isGestureMonitor,
5255 const std::string& name,
5256 int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07005257 std::shared_ptr<InputChannel> serverChannel;
5258 std::unique_ptr<InputChannel> clientChannel;
5259 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
5260 if (result) {
5261 return base::Error(result) << "Failed to open input channel pair with name " << name;
5262 }
5263
Michael Wright3dd60e22019-03-27 22:06:44 +00005264 { // acquire lock
5265 std::scoped_lock _l(mLock);
5266
5267 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07005268 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
5269 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00005270 }
5271
Garfield Tan15601662020-09-22 15:32:38 -07005272 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005273 const sp<IBinder>& token = serverChannel->getConnectionToken();
Garfield Tan15601662020-09-22 15:32:38 -07005274 const int fd = serverChannel->getFd();
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005275
5276 if (mConnectionsByToken.find(token) != mConnectionsByToken.end()) {
5277 ALOGE("Created a new connection, but the token %p is already known", token.get());
5278 }
5279 mConnectionsByToken.emplace(token, connection);
5280 std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
5281 this, std::placeholders::_1, token);
Michael Wright3dd60e22019-03-27 22:06:44 +00005282
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005283 auto& monitorsByDisplay =
5284 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005285 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005286
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005287 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
Siarhei Vishniakouc961c742021-05-19 19:16:59 +00005288 ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
5289 displayId, toString(isGestureMonitor), pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005290 }
Garfield Tan15601662020-09-22 15:32:38 -07005291
Michael Wright3dd60e22019-03-27 22:06:44 +00005292 // Wake the looper because some connections have changed.
5293 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005294 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005295}
5296
Garfield Tan15601662020-09-22 15:32:38 -07005297status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005298 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005299 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005300
Garfield Tan15601662020-09-22 15:32:38 -07005301 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005302 if (status) {
5303 return status;
5304 }
5305 } // release lock
5306
5307 // Wake the poll loop because removing the connection may have changed the current
5308 // synchronization state.
5309 mLooper->wake();
5310 return OK;
5311}
5312
Garfield Tan15601662020-09-22 15:32:38 -07005313status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5314 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005315 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005316 if (connection == nullptr) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005317 // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
Michael Wrightd02c5b62014-02-10 15:10:22 -08005318 return BAD_VALUE;
5319 }
5320
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005321 removeConnectionLocked(connection);
Robert Carr5c8a0262018-10-03 16:30:44 -07005322
Michael Wrightd02c5b62014-02-10 15:10:22 -08005323 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005324 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005325 }
5326
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005327 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005328
5329 nsecs_t currentTime = now();
5330 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5331
5332 connection->status = Connection::STATUS_ZOMBIE;
5333 return OK;
5334}
5335
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005336void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5337 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5338 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005339}
5340
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005341void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005342 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005343 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005344 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005345 std::vector<Monitor>& monitors = it->second;
5346 const size_t numMonitors = monitors.size();
5347 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005348 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Siarhei Vishniakou59a9f292021-04-22 18:43:28 +00005349 ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
5350 monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005351 monitors.erase(monitors.begin() + i);
5352 break;
5353 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005354 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005355 if (monitors.empty()) {
5356 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005357 } else {
5358 ++it;
5359 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005360 }
5361}
5362
Michael Wright3dd60e22019-03-27 22:06:44 +00005363status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5364 { // acquire lock
5365 std::scoped_lock _l(mLock);
5366 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5367
5368 if (!foundDisplayId) {
5369 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5370 return BAD_VALUE;
5371 }
5372 int32_t displayId = foundDisplayId.value();
5373
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005374 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5375 mTouchStatesByDisplay.find(displayId);
5376 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005377 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5378 return BAD_VALUE;
5379 }
5380
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005381 TouchState& state = stateIt->second;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005382 std::shared_ptr<InputChannel> requestingChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005383 std::optional<int32_t> foundDeviceId;
5384 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005385 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005386 requestingChannel = touchedMonitor.monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005387 foundDeviceId = state.deviceId;
5388 }
5389 }
5390 if (!foundDeviceId || !state.down) {
5391 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005392 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005393 return BAD_VALUE;
5394 }
5395 int32_t deviceId = foundDeviceId.value();
5396
5397 // Send cancel events to all the input channels we're stealing from.
5398 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005399 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005400 options.deviceId = deviceId;
5401 options.displayId = displayId;
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005402 std::string canceledWindows = "[";
Michael Wright3dd60e22019-03-27 22:06:44 +00005403 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005404 std::shared_ptr<InputChannel> channel =
5405 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005406 if (channel != nullptr) {
5407 synthesizeCancelationEventsForInputChannelLocked(channel, options);
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005408 canceledWindows += channel->getName() + ", ";
Michael Wright3a240c42019-12-10 20:53:41 +00005409 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005410 }
Siarhei Vishniakoud706a282021-02-13 00:08:48 +00005411 canceledWindows += "]";
5412 ALOGI("Monitor %s is stealing touch from %s", requestingChannel->getName().c_str(),
5413 canceledWindows.c_str());
5414
Michael Wright3dd60e22019-03-27 22:06:44 +00005415 // Then clear the current touch state so we stop dispatching to them as well.
5416 state.filterNonMonitors();
5417 }
5418 return OK;
5419}
5420
Prabir Pradhan99987712020-11-10 18:43:05 -08005421void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5422 { // acquire lock
5423 std::scoped_lock _l(mLock);
5424 if (DEBUG_FOCUS) {
chaviw98318de2021-05-19 16:45:23 -05005425 const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
Prabir Pradhan99987712020-11-10 18:43:05 -08005426 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5427 windowHandle != nullptr ? windowHandle->getName().c_str()
5428 : "token without window");
5429 }
5430
Vishnu Nairc519ff72021-01-21 08:23:08 -08005431 const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
Prabir Pradhan99987712020-11-10 18:43:05 -08005432 if (focusedToken != windowToken) {
5433 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5434 enabled ? "enable" : "disable");
5435 return;
5436 }
5437
5438 if (enabled == mFocusedWindowRequestedPointerCapture) {
5439 ALOGW("Ignoring request to %s Pointer Capture: "
5440 "window has %s requested pointer capture.",
5441 enabled ? "enable" : "disable", enabled ? "already" : "not");
5442 return;
5443 }
5444
5445 mFocusedWindowRequestedPointerCapture = enabled;
5446 setPointerCaptureLocked(enabled);
5447 } // release lock
5448
5449 // Wake the thread to process command entries.
5450 mLooper->wake();
5451}
5452
Michael Wright3dd60e22019-03-27 22:06:44 +00005453std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5454 const sp<IBinder>& token) {
5455 for (const auto& it : mGestureMonitorsByDisplay) {
5456 const std::vector<Monitor>& monitors = it.second;
5457 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005458 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005459 return it.first;
5460 }
5461 }
5462 }
5463 return std::nullopt;
5464}
5465
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005466std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5467 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5468 if (gesturePid.has_value()) {
5469 return gesturePid;
5470 }
5471 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5472}
5473
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005474sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005475 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005476 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005477 }
5478
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005479 for (const auto& [token, connection] : mConnectionsByToken) {
5480 if (token == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005481 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005482 }
5483 }
Robert Carr4e670e52018-08-15 13:26:12 -07005484
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005485 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005486}
5487
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005488std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5489 sp<Connection> connection = getConnectionLocked(connectionToken);
5490 if (connection == nullptr) {
5491 return "<nullptr>";
5492 }
5493 return connection->getInputChannelName();
5494}
5495
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005496void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005497 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakouae02a1f2021-05-01 23:14:04 +00005498 mConnectionsByToken.erase(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005499}
5500
Prabir Pradhancef936d2021-07-21 16:17:52 +00005501void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
5502 const sp<Connection>& connection, uint32_t seq,
5503 bool handled, nsecs_t consumeTime) {
5504 // Handle post-event policy actions.
5505 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
5506 if (dispatchEntryIt == connection->waitQueue.end()) {
5507 return;
5508 }
5509 DispatchEntry* dispatchEntry = *dispatchEntryIt;
5510 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
5511 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
5512 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5513 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
5514 }
5515 if (shouldReportFinishedEvent(*dispatchEntry, *connection)) {
5516 mLatencyTracker.trackFinishedEvent(dispatchEntry->eventEntry->id,
5517 connection->inputChannel->getConnectionToken(),
5518 dispatchEntry->deliveryTime, consumeTime, finishTime);
5519 }
5520
5521 bool restartEvent;
5522 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
5523 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
5524 restartEvent =
5525 afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled);
5526 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
5527 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
5528 restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry,
5529 handled);
5530 } else {
5531 restartEvent = false;
5532 }
5533
5534 // Dequeue the event and start the next cycle.
5535 // Because the lock might have been released, it is possible that the
5536 // contents of the wait queue to have been drained, so we need to double-check
5537 // a few things.
5538 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5539 if (dispatchEntryIt != connection->waitQueue.end()) {
5540 dispatchEntry = *dispatchEntryIt;
5541 connection->waitQueue.erase(dispatchEntryIt);
5542 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5543 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
5544 if (!connection->responsive) {
5545 connection->responsive = isConnectionResponsive(*connection);
5546 if (connection->responsive) {
5547 // The connection was unresponsive, and now it's responsive.
5548 processConnectionResponsiveLocked(*connection);
5549 }
5550 }
5551 traceWaitQueueLength(*connection);
5552 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
5553 connection->outboundQueue.push_front(dispatchEntry);
5554 traceOutboundQueueLength(*connection);
5555 } else {
5556 releaseDispatchEntry(dispatchEntry);
5557 }
5558 }
5559
5560 // Start the next dispatch cycle for this connection.
5561 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005562}
5563
Prabir Pradhancef936d2021-07-21 16:17:52 +00005564void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
5565 const sp<IBinder>& newToken) {
5566 auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
5567 scoped_unlock unlock(mLock);
5568 mPolicy->notifyFocusChanged(oldToken, newToken);
5569 };
5570 postCommandLocked(std::move(command));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005571}
5572
Prabir Pradhancef936d2021-07-21 16:17:52 +00005573void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
5574 auto command = [this, token, x, y]() REQUIRES(mLock) {
5575 scoped_unlock unlock(mLock);
5576 mPolicy->notifyDropWindow(token, x, y);
5577 };
5578 postCommandLocked(std::move(command));
Robert Carrf759f162018-11-13 12:57:11 -08005579}
5580
Prabir Pradhancef936d2021-07-21 16:17:52 +00005581void InputDispatcher::sendUntrustedTouchCommandLocked(const std::string& obscuringPackage) {
5582 auto command = [this, obscuringPackage]() REQUIRES(mLock) {
5583 scoped_unlock unlock(mLock);
5584 mPolicy->notifyUntrustedTouch(obscuringPackage);
5585 };
5586 postCommandLocked(std::move(command));
arthurhungf452d0b2021-01-06 00:19:52 +08005587}
5588
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005589void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5590 if (connection == nullptr) {
5591 LOG_ALWAYS_FATAL("Caller must check for nullness");
5592 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005593 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5594 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005595 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005596 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005597 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005598 return;
5599 }
5600 /**
5601 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5602 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5603 * has changed. This could cause newer entries to time out before the already dispatched
5604 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5605 * processes the events linearly. So providing information about the oldest entry seems to be
5606 * most useful.
5607 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005608 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005609 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5610 std::string reason =
5611 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005612 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005613 ns2ms(currentWait),
5614 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005615 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005616 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005617
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005618 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5619
5620 // Stop waking up for events on this connection, it is already unresponsive
5621 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005622}
5623
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005624void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5625 std::string reason =
5626 StringPrintf("%s does not have a focused window", application->getName().c_str());
5627 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005628
Prabir Pradhancef936d2021-07-21 16:17:52 +00005629 auto command = [this, application = std::move(application)]() REQUIRES(mLock) {
5630 scoped_unlock unlock(mLock);
5631 mPolicy->notifyNoFocusedWindowAnr(application);
5632 };
5633 postCommandLocked(std::move(command));
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005634}
5635
chaviw98318de2021-05-19 16:45:23 -05005636void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005637 const std::string& reason) {
5638 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5639 updateLastAnrStateLocked(windowLabel, reason);
5640}
5641
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005642void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5643 const std::string& reason) {
5644 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005645 updateLastAnrStateLocked(windowLabel, reason);
5646}
5647
5648void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5649 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005650 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005651 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005652 struct tm tm;
5653 localtime_r(&t, &tm);
5654 char timestr[64];
5655 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005656 mLastAnrState.clear();
5657 mLastAnrState += INDENT "ANR:\n";
5658 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005659 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5660 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005661 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005662}
5663
Prabir Pradhancef936d2021-07-21 16:17:52 +00005664void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
5665 KeyEntry& entry) {
5666 const KeyEvent event = createKeyEvent(entry);
5667 nsecs_t delay = 0;
5668 { // release lock
5669 scoped_unlock unlock(mLock);
5670 android::base::Timer t;
5671 delay = mPolicy->interceptKeyBeforeDispatching(focusedWindowToken, &event,
5672 entry.policyFlags);
5673 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5674 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
5675 std::to_string(t.duration().count()).c_str());
5676 }
5677 } // acquire lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08005678
5679 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005680 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Prabir Pradhancef936d2021-07-21 16:17:52 +00005681 } else if (delay == 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005682 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005683 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005684 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5685 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005686 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005687}
5688
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005689void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005690 auto command = [this, pid, reason = std::move(reason)]() REQUIRES(mLock) {
5691 scoped_unlock unlock(mLock);
5692 mPolicy->notifyMonitorUnresponsive(pid, reason);
5693 };
5694 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005695}
5696
Prabir Pradhancef936d2021-07-21 16:17:52 +00005697void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005698 std::string reason) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005699 auto command = [this, token, reason = std::move(reason)]() REQUIRES(mLock) {
5700 scoped_unlock unlock(mLock);
5701 mPolicy->notifyWindowUnresponsive(token, reason);
5702 };
5703 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005704}
5705
5706void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00005707 auto command = [this, pid]() REQUIRES(mLock) {
5708 scoped_unlock unlock(mLock);
5709 mPolicy->notifyMonitorResponsive(pid);
5710 };
5711 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005712}
5713
Prabir Pradhancef936d2021-07-21 16:17:52 +00005714void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& connectionToken) {
5715 auto command = [this, connectionToken]() REQUIRES(mLock) {
5716 scoped_unlock unlock(mLock);
5717 mPolicy->notifyWindowResponsive(connectionToken);
5718 };
5719 postCommandLocked(std::move(command));
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005720}
5721
5722/**
5723 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5724 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5725 * command entry to the command queue.
5726 */
5727void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5728 std::string reason) {
5729 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5730 if (connection.monitor) {
5731 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5732 reason.c_str());
5733 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5734 if (!pid.has_value()) {
5735 ALOGE("Could not find unresponsive monitor for connection %s",
5736 connection.inputChannel->getName().c_str());
5737 return;
5738 }
5739 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5740 return;
5741 }
5742 // If not a monitor, must be a window
5743 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5744 reason.c_str());
5745 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5746}
5747
5748/**
5749 * Tell the policy that a connection has become responsive so that it can stop ANR.
5750 */
5751void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5752 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5753 if (connection.monitor) {
5754 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5755 if (!pid.has_value()) {
5756 ALOGE("Could not find responsive monitor for connection %s",
5757 connection.inputChannel->getName().c_str());
5758 return;
5759 }
5760 sendMonitorResponsiveCommandLocked(pid.value());
5761 return;
5762 }
5763 // If not a monitor, must be a window
5764 sendWindowResponsiveCommandLocked(connectionToken);
5765}
5766
Prabir Pradhancef936d2021-07-21 16:17:52 +00005767bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005768 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005769 KeyEntry& keyEntry, bool handled) {
5770 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005771 if (!handled) {
5772 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005773 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005774 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005775 return false;
5776 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005777
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005778 // Get the fallback key state.
5779 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005780 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005781 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005782 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005783 connection->inputState.removeFallbackKey(originalKeyCode);
5784 }
5785
5786 if (handled || !dispatchEntry->hasForegroundTarget()) {
5787 // If the application handles the original key for which we previously
5788 // generated a fallback or if the window is not a foreground window,
5789 // then cancel the associated fallback key, if any.
5790 if (fallbackKeyCode != -1) {
5791 // Dispatch the unhandled key to the policy with the cancel flag.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005792 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5793 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
5794 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5795 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
5796 keyEntry.policyFlags);
5797 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005798 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005799 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005800
5801 mLock.unlock();
5802
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005803 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005804 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005805
5806 mLock.lock();
5807
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005808 // Cancel the fallback key.
5809 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005810 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005811 "application handled the original non-fallback key "
5812 "or is no longer a foreground target, "
5813 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005814 options.keyCode = fallbackKeyCode;
5815 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005816 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005817 connection->inputState.removeFallbackKey(originalKeyCode);
5818 }
5819 } else {
5820 // If the application did not handle a non-fallback key, first check
5821 // that we are in a good state to perform unhandled key event processing
5822 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005823 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005824 if (fallbackKeyCode == -1 && !initialDown) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005825 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5826 ALOGD("Unhandled key event: Skipping unhandled key event processing "
5827 "since this is not an initial down. "
5828 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5829 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5830 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005831 return false;
5832 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005833
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005834 // Dispatch the unhandled key to the policy.
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005835 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5836 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
5837 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
5838 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
5839 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005840 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005841
5842 mLock.unlock();
5843
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005844 bool fallback =
5845 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005846 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005847
5848 mLock.lock();
5849
5850 if (connection->status != Connection::STATUS_NORMAL) {
5851 connection->inputState.removeFallbackKey(originalKeyCode);
5852 return false;
5853 }
5854
5855 // Latch the fallback keycode for this key on an initial down.
5856 // The fallback keycode cannot change at any other point in the lifecycle.
5857 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005858 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005859 fallbackKeyCode = event.getKeyCode();
5860 } else {
5861 fallbackKeyCode = AKEYCODE_UNKNOWN;
5862 }
5863 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5864 }
5865
5866 ALOG_ASSERT(fallbackKeyCode != -1);
5867
5868 // Cancel the fallback key if the policy decides not to send it anymore.
5869 // We will continue to dispatch the key to the policy but we will no
5870 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005871 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5872 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005873 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5874 if (fallback) {
5875 ALOGD("Unhandled key event: Policy requested to send key %d"
5876 "as a fallback for %d, but on the DOWN it had requested "
5877 "to send %d instead. Fallback canceled.",
5878 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
5879 } else {
5880 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
5881 "but on the DOWN it had requested to send %d. "
5882 "Fallback canceled.",
5883 originalKeyCode, fallbackKeyCode);
5884 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005885 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005886
5887 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5888 "canceling fallback, policy no longer desires it");
5889 options.keyCode = fallbackKeyCode;
5890 synthesizeCancelationEventsForConnectionLocked(connection, options);
5891
5892 fallback = false;
5893 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005894 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005895 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005896 }
5897 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005898
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005899 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5900 {
5901 std::string msg;
5902 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5903 connection->inputState.getFallbackKeys();
5904 for (size_t i = 0; i < fallbackKeys.size(); i++) {
5905 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
5906 }
5907 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
5908 fallbackKeys.size(), msg.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005909 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005910 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005911
5912 if (fallback) {
5913 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005914 keyEntry.eventTime = event.getEventTime();
5915 keyEntry.deviceId = event.getDeviceId();
5916 keyEntry.source = event.getSource();
5917 keyEntry.displayId = event.getDisplayId();
5918 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5919 keyEntry.keyCode = fallbackKeyCode;
5920 keyEntry.scanCode = event.getScanCode();
5921 keyEntry.metaState = event.getMetaState();
5922 keyEntry.repeatCount = event.getRepeatCount();
5923 keyEntry.downTime = event.getDownTime();
5924 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005925
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005926 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5927 ALOGD("Unhandled key event: Dispatching fallback key. "
5928 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
5929 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
5930 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005931 return true; // restart the event
5932 } else {
Prabir Pradhan61a5d242021-07-26 16:41:09 +00005933 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
5934 ALOGD("Unhandled key event: No fallback key.");
5935 }
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005936
5937 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005938 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005939 }
5940 }
5941 return false;
5942}
5943
Prabir Pradhancef936d2021-07-21 16:17:52 +00005944bool InputDispatcher::afterMotionEventLockedInterruptable(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005945 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005946 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005947 return false;
5948}
5949
Michael Wrightd02c5b62014-02-10 15:10:22 -08005950void InputDispatcher::traceInboundQueueLengthLocked() {
5951 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005952 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005953 }
5954}
5955
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005956void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005957 if (ATRACE_ENABLED()) {
5958 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005959 snprintf(counterName, sizeof(counterName), "oq:%s", connection.getWindowName().c_str());
5960 ATRACE_INT(counterName, connection.outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005961 }
5962}
5963
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005964void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005965 if (ATRACE_ENABLED()) {
5966 char counterName[40];
Siarhei Vishniakou060a7272021-02-03 19:40:10 +00005967 snprintf(counterName, sizeof(counterName), "wq:%s", connection.getWindowName().c_str());
5968 ATRACE_INT(counterName, connection.waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005969 }
5970}
5971
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005972void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005973 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005974
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005975 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005976 dumpDispatchStateLocked(dump);
5977
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005978 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005979 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005980 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005981 }
5982}
5983
5984void InputDispatcher::monitor() {
5985 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005986 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005987 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005988 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005989}
5990
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005991/**
5992 * Wake up the dispatcher and wait until it processes all events and commands.
5993 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5994 * this method can be safely called from any thread, as long as you've ensured that
5995 * the work you are interested in completing has already been queued.
5996 */
5997bool InputDispatcher::waitForIdle() {
5998 /**
5999 * Timeout should represent the longest possible time that a device might spend processing
6000 * events and commands.
6001 */
6002 constexpr std::chrono::duration TIMEOUT = 100ms;
6003 std::unique_lock lock(mLock);
6004 mLooper->wake();
6005 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6006 return result == std::cv_status::no_timeout;
6007}
6008
Vishnu Naire798b472020-07-23 13:52:21 -07006009/**
6010 * Sets focus to the window identified by the token. This must be called
6011 * after updating any input window handles.
6012 *
6013 * Params:
6014 * request.token - input channel token used to identify the window that should gain focus.
6015 * request.focusedToken - the token that the caller expects currently to be focused. If the
6016 * specified token does not match the currently focused window, this request will be dropped.
6017 * If the specified focused token matches the currently focused window, the call will succeed.
6018 * Set this to "null" if this call should succeed no matter what the currently focused token is.
6019 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6020 * when requesting the focus change. This determines which request gets
6021 * precedence if there is a focus change request from another source such as pointer down.
6022 */
Vishnu Nair958da932020-08-21 17:12:37 -07006023void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6024 { // acquire lock
6025 std::scoped_lock _l(mLock);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006026 std::optional<FocusResolver::FocusChanges> changes =
6027 mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId));
6028 if (changes) {
6029 onFocusChangedLocked(*changes);
Vishnu Nair958da932020-08-21 17:12:37 -07006030 }
6031 } // release lock
6032 // Wake up poll loop since it may need to make new input dispatching choices.
6033 mLooper->wake();
6034}
6035
Vishnu Nairc519ff72021-01-21 08:23:08 -08006036void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes) {
6037 if (changes.oldFocus) {
6038 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(changes.oldFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006039 if (focusedInputChannel) {
6040 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
6041 "focus left window");
6042 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairc519ff72021-01-21 08:23:08 -08006043 enqueueFocusEventLocked(changes.oldFocus, false /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006044 }
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006045 }
Vishnu Nairc519ff72021-01-21 08:23:08 -08006046 if (changes.newFocus) {
6047 enqueueFocusEventLocked(changes.newFocus, true /*hasFocus*/, changes.reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006048 }
6049
Prabir Pradhan99987712020-11-10 18:43:05 -08006050 // If a window has pointer capture, then it must have focus. We need to ensure that this
6051 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
6052 // If the window loses focus before it loses pointer capture, then the window can be in a state
6053 // where it has pointer capture but not focus, violating the contract. Therefore we must
6054 // dispatch the pointer capture event before the focus event. Since focus events are added to
6055 // the front of the queue (above), we add the pointer capture event to the front of the queue
6056 // after the focus events are added. This ensures the pointer capture event ends up at the
6057 // front.
6058 disablePointerCaptureForcedLocked();
6059
Vishnu Nairc519ff72021-01-21 08:23:08 -08006060 if (mFocusedDisplayId == changes.displayId) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006061 sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07006062 }
6063}
Vishnu Nair958da932020-08-21 17:12:37 -07006064
Prabir Pradhan99987712020-11-10 18:43:05 -08006065void InputDispatcher::disablePointerCaptureForcedLocked() {
6066 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
6067 return;
6068 }
6069
6070 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
6071
6072 if (mFocusedWindowRequestedPointerCapture) {
6073 mFocusedWindowRequestedPointerCapture = false;
6074 setPointerCaptureLocked(false);
6075 }
6076
6077 if (!mWindowTokenWithPointerCapture) {
6078 // No need to send capture changes because no window has capture.
6079 return;
6080 }
6081
6082 if (mPendingEvent != nullptr) {
6083 // Move the pending event to the front of the queue. This will give the chance
6084 // for the pending event to be dropped if it is a captured event.
6085 mInboundQueue.push_front(mPendingEvent);
6086 mPendingEvent = nullptr;
6087 }
6088
6089 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
6090 false /* hasCapture */);
6091 mInboundQueue.push_front(std::move(entry));
6092}
6093
Prabir Pradhan99987712020-11-10 18:43:05 -08006094void InputDispatcher::setPointerCaptureLocked(bool enabled) {
Prabir Pradhancef936d2021-07-21 16:17:52 +00006095 auto command = [this, enabled]() REQUIRES(mLock) {
6096 scoped_unlock unlock(mLock);
6097 mPolicy->setPointerCapture(enabled);
6098 };
6099 postCommandLocked(std::move(command));
Prabir Pradhan99987712020-11-10 18:43:05 -08006100}
6101
Vishnu Nair599f1412021-06-21 10:39:58 -07006102void InputDispatcher::displayRemoved(int32_t displayId) {
6103 { // acquire lock
6104 std::scoped_lock _l(mLock);
6105 // Set an empty list to remove all handles from the specific display.
6106 setInputWindowsLocked(/* window handles */ {}, displayId);
6107 setFocusedApplicationLocked(displayId, nullptr);
6108 // Call focus resolver to clean up stale requests. This must be called after input windows
6109 // have been removed for the removed display.
6110 mFocusResolver.displayRemoved(displayId);
6111 } // release lock
6112
6113 // Wake up poll loop since it may need to make new input dispatching choices.
6114 mLooper->wake();
6115}
6116
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006117void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos,
6118 const std::vector<DisplayInfo>& displayInfos) {
chaviw15fab6f2021-06-07 14:15:52 -05006119 // The listener sends the windows as a flattened array. Separate the windows by display for
6120 // more convenient parsing.
6121 std::unordered_map<int32_t, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
chaviw15fab6f2021-06-07 14:15:52 -05006122 for (const auto& info : windowInfos) {
6123 handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
6124 handlesPerDisplay[info.displayId].push_back(new WindowInfoHandle(info));
6125 }
Prabir Pradhan48f8cb92021-08-26 14:05:36 -07006126
6127 { // acquire lock
6128 std::scoped_lock _l(mLock);
6129 mDisplayInfos.clear();
6130 for (const auto& displayInfo : displayInfos) {
6131 mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
6132 }
6133
6134 for (const auto& [displayId, handles] : handlesPerDisplay) {
6135 setInputWindowsLocked(handles, displayId);
6136 }
6137 }
6138 // Wake up poll loop since it may need to make new input dispatching choices.
6139 mLooper->wake();
chaviw15fab6f2021-06-07 14:15:52 -05006140}
6141
Garfield Tane84e6f92019-08-29 17:28:41 -07006142} // namespace android::inputdispatcher