blob: cdc74f3fa9aa92f8c9c2a9a21ac0e2a7532a9f23 [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
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
Michael Wright2b3c3302018-03-02 17:19:13 +000050#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080051#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050052#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070053#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100054#include <binder/IServiceManager.h>
55#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080056#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010057#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070058#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000059#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010061#include <statslog.h>
62#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080064
Michael Wright44753b12020-07-08 13:48:11 +010065#include <cerrno>
66#include <cinttypes>
67#include <climits>
68#include <cstddef>
69#include <ctime>
70#include <queue>
71#include <sstream>
72
73#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070074#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010075
Michael Wrightd02c5b62014-02-10 15:10:22 -080076#define INDENT " "
77#define INDENT2 " "
78#define INDENT3 " "
79#define INDENT4 " "
80
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080081using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080082using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100083using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080084using android::os::InputEventInjectionResult;
85using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100086using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080087
Garfield Tane84e6f92019-08-29 17:28:41 -070088namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080089
90// Default input dispatching timeout if there is no focused application or paused window
91// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050092constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
93 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080094
95// Amount of time to allow for all pending events to be processed when an app switch
96// key is on the way. This is used to preempt input dispatch and drop input events
97// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080099
100// Amount of time to allow for an event to be dispatched (measured since its eventTime)
101// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104// 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 +0000105constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
106
107// Log a warning when an interception call takes longer than this to process.
108constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800109
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700110// Additional key latency in case a connection is still processing some motion events.
111// This will help with the case when a user touched a button that opens a new window,
112// and gives us the chance to dispatch the key to this new window.
113constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
114
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000116constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
117
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000118// Event log tags. See EventLogTags.logtags for reference
119constexpr int LOGTAG_INPUT_INTERACTION = 62000;
120constexpr int LOGTAG_INPUT_FOCUS = 62001;
121
Michael Wrightd02c5b62014-02-10 15:10:22 -0800122static inline nsecs_t now() {
123 return systemTime(SYSTEM_TIME_MONOTONIC);
124}
125
126static inline const char* toString(bool value) {
127 return value ? "true" : "false";
128}
129
130static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700131 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
132 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800133}
134
135static bool isValidKeyAction(int32_t action) {
136 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700137 case AKEY_EVENT_ACTION_DOWN:
138 case AKEY_EVENT_ACTION_UP:
139 return true;
140 default:
141 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 }
143}
144
145static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700146 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800147 ALOGE("Key event has invalid action code 0x%x", action);
148 return false;
149 }
150 return true;
151}
152
Michael Wright7b159c92015-05-14 14:48:03 +0100153static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700155 case AMOTION_EVENT_ACTION_DOWN:
156 case AMOTION_EVENT_ACTION_UP:
157 case AMOTION_EVENT_ACTION_CANCEL:
158 case AMOTION_EVENT_ACTION_MOVE:
159 case AMOTION_EVENT_ACTION_OUTSIDE:
160 case AMOTION_EVENT_ACTION_HOVER_ENTER:
161 case AMOTION_EVENT_ACTION_HOVER_MOVE:
162 case AMOTION_EVENT_ACTION_HOVER_EXIT:
163 case AMOTION_EVENT_ACTION_SCROLL:
164 return true;
165 case AMOTION_EVENT_ACTION_POINTER_DOWN:
166 case AMOTION_EVENT_ACTION_POINTER_UP: {
167 int32_t index = getMotionEventActionPointerIndex(action);
168 return index >= 0 && index < pointerCount;
169 }
170 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
171 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
172 return actionButton != 0;
173 default:
174 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175 }
176}
177
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500178static int64_t millis(std::chrono::nanoseconds t) {
179 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
180}
181
Michael Wright7b159c92015-05-14 14:48:03 +0100182static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700183 const PointerProperties* pointerProperties) {
184 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 ALOGE("Motion event has invalid action code 0x%x", action);
186 return false;
187 }
188 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000189 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700190 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 return false;
192 }
193 BitSet32 pointerIdBits;
194 for (size_t i = 0; i < pointerCount; i++) {
195 int32_t id = pointerProperties[i].id;
196 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700197 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
198 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 return false;
200 }
201 if (pointerIdBits.hasBit(id)) {
202 ALOGE("Motion event has duplicate pointer id %d", id);
203 return false;
204 }
205 pointerIdBits.markBit(id);
206 }
207 return true;
208}
209
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000210static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000212 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 }
214
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000215 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216 bool first = true;
217 Region::const_iterator cur = region.begin();
218 Region::const_iterator const tail = region.end();
219 while (cur != tail) {
220 if (first) {
221 first = false;
222 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800223 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800225 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226 cur++;
227 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000228 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229}
230
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500231static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
232 constexpr size_t maxEntries = 50; // max events to print
233 constexpr size_t skipBegin = maxEntries / 2;
234 const size_t skipEnd = queue.size() - maxEntries / 2;
235 // skip from maxEntries / 2 ... size() - maxEntries/2
236 // only print from 0 .. skipBegin and then from skipEnd .. size()
237
238 std::string dump;
239 for (size_t i = 0; i < queue.size(); i++) {
240 const DispatchEntry& entry = *queue[i];
241 if (i >= skipBegin && i < skipEnd) {
242 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
243 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
244 continue;
245 }
246 dump.append(INDENT4);
247 dump += entry.eventEntry->getDescription();
248 dump += StringPrintf(", seq=%" PRIu32
249 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
250 entry.seq, entry.targetFlags, entry.resolvedAction,
251 ns2ms(currentTime - entry.eventEntry->eventTime));
252 if (entry.deliveryTime != 0) {
253 // This entry was delivered, so add information on how long we've been waiting
254 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
255 }
256 dump.append("\n");
257 }
258 return dump;
259}
260
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700261/**
262 * Find the entry in std::unordered_map by key, and return it.
263 * If the entry is not found, return a default constructed entry.
264 *
265 * Useful when the entries are vectors, since an empty vector will be returned
266 * if the entry is not found.
267 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
268 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700269template <typename K, typename V>
270static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700271 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700272 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800273}
274
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700275/**
276 * Find the entry in std::unordered_map by value, and remove it.
277 * If more than one entry has the same value, then all matching
278 * key-value pairs will be removed.
279 *
280 * Return true if at least one value has been removed.
281 */
282template <typename K, typename V>
283static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
284 bool removed = false;
285 for (auto it = map.begin(); it != map.end();) {
286 if (it->second == value) {
287 it = map.erase(it);
288 removed = true;
289 } else {
290 it++;
291 }
292 }
293 return removed;
294}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295
Vishnu Nair958da932020-08-21 17:12:37 -0700296/**
297 * Find the entry in std::unordered_map by key and return the value as an optional.
298 */
299template <typename K, typename V>
300static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
301 auto it = map.find(key);
302 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
303}
304
chaviwaf87b3e2019-10-01 16:59:28 -0700305static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
306 if (first == second) {
307 return true;
308 }
309
310 if (first == nullptr || second == nullptr) {
311 return false;
312 }
313
314 return first->getToken() == second->getToken();
315}
316
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800317static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
318 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
319}
320
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000321static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700322 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000323 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900324 if (eventEntry->type == EventEntry::Type::MOTION) {
325 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
326 if (motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) {
327 const ui::Transform identityTransform;
328 // Use identity transform for joystick events events because they don't depend on
329 // the window info
330 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
331 1.0f /*globalScaleFactor*/);
332 }
333 }
334
chaviw1ff3d1e2020-07-01 15:53:47 -0700335 if (inputTarget.useDefaultPointerTransform()) {
336 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700337 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700338 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000339 }
340
341 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
342 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
343
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700344 std::vector<PointerCoords> pointerCoords;
345 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000346
347 // Use the first pointer information to normalize all other pointers. This could be any pointer
348 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700349 // uses the transform for the normalized pointer.
350 const ui::Transform& firstPointerTransform =
351 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
352 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000353
354 // Iterate through all pointers in the event to normalize against the first.
355 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
356 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
357 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700358 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000359
360 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700361 // First, apply the current pointer's transform to update the coordinates into
362 // window space.
363 pointerCoords[pointerIndex].transform(currTransform);
364 // Next, apply the inverse transform of the normalized coordinates so the
365 // current coordinates are transformed into the normalized coordinate space.
366 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000367 }
368
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700369 std::unique_ptr<MotionEntry> combinedMotionEntry =
370 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
371 motionEntry.deviceId, motionEntry.source,
372 motionEntry.displayId, motionEntry.policyFlags,
373 motionEntry.action, motionEntry.actionButton,
374 motionEntry.flags, motionEntry.metaState,
375 motionEntry.buttonState, motionEntry.classification,
376 motionEntry.edgeFlags, motionEntry.xPrecision,
377 motionEntry.yPrecision, motionEntry.xCursorPosition,
378 motionEntry.yCursorPosition, motionEntry.downTime,
379 motionEntry.pointerCount, motionEntry.pointerProperties,
380 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000381
382 if (motionEntry.injectionState) {
383 combinedMotionEntry->injectionState = motionEntry.injectionState;
384 combinedMotionEntry->injectionState->refCount += 1;
385 }
386
387 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700388 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
389 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000390 return dispatchEntry;
391}
392
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700393static void addGestureMonitors(const std::vector<Monitor>& monitors,
394 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
395 float yOffset = 0) {
396 if (monitors.empty()) {
397 return;
398 }
399 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
400 for (const Monitor& monitor : monitors) {
401 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
402 }
403}
404
Garfield Tan15601662020-09-22 15:32:38 -0700405static status_t openInputChannelPair(const std::string& name,
406 std::shared_ptr<InputChannel>& serverChannel,
407 std::unique_ptr<InputChannel>& clientChannel) {
408 std::unique_ptr<InputChannel> uniqueServerChannel;
409 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
410
411 serverChannel = std::move(uniqueServerChannel);
412 return result;
413}
414
Vishnu Nair958da932020-08-21 17:12:37 -0700415const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
416 switch (result) {
417 case InputDispatcher::FocusResult::OK:
418 return "Ok";
419 case InputDispatcher::FocusResult::NO_WINDOW:
420 return "Window not found";
421 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
422 return "Window not focusable";
423 case InputDispatcher::FocusResult::NOT_VISIBLE:
424 return "Window not visible";
425 }
426}
427
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500428template <typename T>
429static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
430 if (lhs == nullptr && rhs == nullptr) {
431 return true;
432 }
433 if (lhs == nullptr || rhs == nullptr) {
434 return false;
435 }
436 return *lhs == *rhs;
437}
438
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000439static sp<IPlatformCompatNative> getCompatService() {
440 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
441 if (service == nullptr) {
442 ALOGE("Failed to link to compat service");
443 return nullptr;
444 }
445 return interface_cast<IPlatformCompatNative>(service);
446}
447
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000448static KeyEvent createKeyEvent(const KeyEntry& entry) {
449 KeyEvent event;
450 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
451 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
452 entry.repeatCount, entry.downTime, entry.eventTime);
453 return event;
454}
455
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000456static std::optional<int32_t> findMonitorPidByToken(
457 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
458 const sp<IBinder>& token) {
459 for (const auto& it : monitorsByDisplay) {
460 const std::vector<Monitor>& monitors = it.second;
461 for (const Monitor& monitor : monitors) {
462 if (monitor.inputChannel->getConnectionToken() == token) {
463 return monitor.pid;
464 }
465 }
466 }
467 return std::nullopt;
468}
469
Michael Wrightd02c5b62014-02-10 15:10:22 -0800470// --- InputDispatcher ---
471
Garfield Tan00f511d2019-06-12 16:55:40 -0700472InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
473 : mPolicy(policy),
474 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700475 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800476 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700477 mAppSwitchSawKeyDown(false),
478 mAppSwitchDueTime(LONG_LONG_MAX),
479 mNextUnblockedEvent(nullptr),
480 mDispatchEnabled(false),
481 mDispatchFrozen(false),
482 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800483 // mInTouchMode will be initialized by the WindowManager to the default device config.
484 // To avoid leaking stack in case that call never comes, and for tests,
485 // initialize it here anyways.
486 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100487 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000488 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800489 mFocusedWindowRequestedPointerCapture(false),
490 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000491 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800492 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800493 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800494
Yi Kong9b14ac62018-07-17 13:48:38 -0700495 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800496
497 policy->getDispatcherConfiguration(&mConfig);
498}
499
500InputDispatcher::~InputDispatcher() {
501 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800502 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800503
504 resetKeyRepeatLocked();
505 releasePendingEventLocked();
506 drainInboundQueueLocked();
507 }
508
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700509 while (!mConnectionsByFd.empty()) {
510 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700511 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800512 }
513}
514
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700515status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700516 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700517 return ALREADY_EXISTS;
518 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700519 mThread = std::make_unique<InputThread>(
520 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
521 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700522}
523
524status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700525 if (mThread && mThread->isCallingThread()) {
526 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700527 return INVALID_OPERATION;
528 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700529 mThread.reset();
530 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700531}
532
Michael Wrightd02c5b62014-02-10 15:10:22 -0800533void InputDispatcher::dispatchOnce() {
534 nsecs_t nextWakeupTime = LONG_LONG_MAX;
535 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800536 std::scoped_lock _l(mLock);
537 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800538
539 // Run a dispatch loop if there are no pending commands.
540 // The dispatch loop might enqueue commands to run afterwards.
541 if (!haveCommandsLocked()) {
542 dispatchOnceInnerLocked(&nextWakeupTime);
543 }
544
545 // Run all pending commands if there are any.
546 // If any commands were run then force the next poll to wake up immediately.
547 if (runCommandsLockedInterruptible()) {
548 nextWakeupTime = LONG_LONG_MIN;
549 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800550
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700551 // If we are still waiting for ack on some events,
552 // we might have to wake up earlier to check if an app is anr'ing.
553 const nsecs_t nextAnrCheck = processAnrsLocked();
554 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
555
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800556 // We are about to enter an infinitely long sleep, because we have no commands or
557 // pending or queued events
558 if (nextWakeupTime == LONG_LONG_MAX) {
559 mDispatcherEnteredIdle.notify_all();
560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561 } // release lock
562
563 // Wait for callback or timeout or wake. (make sure we round up, not down)
564 nsecs_t currentTime = now();
565 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
566 mLooper->pollOnce(timeoutMillis);
567}
568
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700569/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500570 * Raise ANR if there is no focused window.
571 * Before the ANR is raised, do a final state check:
572 * 1. The currently focused application must be the same one we are waiting for.
573 * 2. Ensure we still don't have a focused window.
574 */
575void InputDispatcher::processNoFocusedWindowAnrLocked() {
576 // Check if the application that we are waiting for is still focused.
577 std::shared_ptr<InputApplicationHandle> focusedApplication =
578 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
579 if (focusedApplication == nullptr ||
580 focusedApplication->getApplicationToken() !=
581 mAwaitedFocusedApplication->getApplicationToken()) {
582 // Unexpected because we should have reset the ANR timer when focused application changed
583 ALOGE("Waited for a focused window, but focused application has already changed to %s",
584 focusedApplication->getName().c_str());
585 return; // The focused application has changed.
586 }
587
588 const sp<InputWindowHandle>& focusedWindowHandle =
589 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
590 if (focusedWindowHandle != nullptr) {
591 return; // We now have a focused window. No need for ANR.
592 }
593 onAnrLocked(mAwaitedFocusedApplication);
594}
595
596/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700597 * Check if any of the connections' wait queues have events that are too old.
598 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
599 * Return the time at which we should wake up next.
600 */
601nsecs_t InputDispatcher::processAnrsLocked() {
602 const nsecs_t currentTime = now();
603 nsecs_t nextAnrCheck = LONG_LONG_MAX;
604 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
605 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
606 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500607 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700608 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500609 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700610 return LONG_LONG_MIN;
611 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500612 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700613 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
614 }
615 }
616
617 // Check if any connection ANRs are due
618 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
619 if (currentTime < nextAnrCheck) { // most likely scenario
620 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
621 }
622
623 // If we reached here, we have an unresponsive connection.
624 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
625 if (connection == nullptr) {
626 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
627 return nextAnrCheck;
628 }
629 connection->responsive = false;
630 // Stop waking up for this unresponsive connection
631 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000632 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700633 return LONG_LONG_MIN;
634}
635
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500636std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700637 sp<InputWindowHandle> window = getWindowHandleLocked(token);
638 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500639 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700640 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500641 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700642}
643
Michael Wrightd02c5b62014-02-10 15:10:22 -0800644void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
645 nsecs_t currentTime = now();
646
Jeff Browndc5992e2014-04-11 01:27:26 -0700647 // Reset the key repeat timer whenever normal dispatch is suspended while the
648 // device is in a non-interactive state. This is to ensure that we abort a key
649 // repeat if the device is just coming out of sleep.
650 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651 resetKeyRepeatLocked();
652 }
653
654 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
655 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100656 if (DEBUG_FOCUS) {
657 ALOGD("Dispatch frozen. Waiting some more.");
658 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800659 return;
660 }
661
662 // Optimize latency of app switches.
663 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
664 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
665 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
666 if (mAppSwitchDueTime < *nextWakeupTime) {
667 *nextWakeupTime = mAppSwitchDueTime;
668 }
669
670 // Ready to start a new event.
671 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700672 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700673 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 if (isAppSwitchDue) {
675 // The inbound queue is empty so the app switch key we were waiting
676 // for will never arrive. Stop waiting for it.
677 resetPendingAppSwitchLocked(false);
678 isAppSwitchDue = false;
679 }
680
681 // Synthesize a key repeat if appropriate.
682 if (mKeyRepeatState.lastKeyEntry) {
683 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
684 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
685 } else {
686 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
687 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
688 }
689 }
690 }
691
692 // Nothing to do if there is no pending event.
693 if (!mPendingEvent) {
694 return;
695 }
696 } else {
697 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700698 mPendingEvent = mInboundQueue.front();
699 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700 traceInboundQueueLengthLocked();
701 }
702
703 // Poke user activity for this event.
704 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700705 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800707 }
708
709 // Now we have an event to dispatch.
710 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700711 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800712 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700713 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800714 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700715 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800716 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700717 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800718 }
719
720 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700721 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800722 }
723
724 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700725 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700726 const ConfigurationChangedEntry& typedEntry =
727 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700729 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700730 break;
731 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800732
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700733 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700734 const DeviceResetEntry& typedEntry =
735 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700736 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700737 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 break;
739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800740
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100741 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700742 std::shared_ptr<FocusEntry> typedEntry =
743 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100744 dispatchFocusLocked(currentTime, typedEntry);
745 done = true;
746 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
747 break;
748 }
749
Prabir Pradhan99987712020-11-10 18:43:05 -0800750 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
751 const auto typedEntry =
752 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
753 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
754 done = true;
755 break;
756 }
757
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700758 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700759 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700760 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700761 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700762 resetPendingAppSwitchLocked(true);
763 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700764 } else if (dropReason == DropReason::NOT_DROPPED) {
765 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700766 }
767 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700768 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700769 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700770 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700771 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
772 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700773 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700774 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700775 break;
776 }
777
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700778 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700779 std::shared_ptr<MotionEntry> motionEntry =
780 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700781 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
782 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800783 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700784 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700785 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700786 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700787 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
788 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700789 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700790 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700791 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 }
Chris Yef59a2f42020-10-16 12:55:26 -0700793
794 case EventEntry::Type::SENSOR: {
795 std::shared_ptr<SensorEntry> sensorEntry =
796 std::static_pointer_cast<SensorEntry>(mPendingEvent);
797 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
798 dropReason = DropReason::APP_SWITCH;
799 }
800 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
801 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
802 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
803 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
804 dropReason = DropReason::STALE;
805 }
806 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
807 done = true;
808 break;
809 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800810 }
811
812 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700813 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700814 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815 }
Michael Wright3a981722015-06-10 15:26:13 +0100816 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817
818 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700819 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800820 }
821}
822
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700823/**
824 * Return true if the events preceding this incoming motion event should be dropped
825 * Return false otherwise (the default behaviour)
826 */
827bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700828 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700829 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700830
831 // Optimize case where the current application is unresponsive and the user
832 // decides to touch a window in a different application.
833 // If the application takes too long to catch up then we drop all events preceding
834 // the touch into the other window.
835 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700836 int32_t displayId = motionEntry.displayId;
837 int32_t x = static_cast<int32_t>(
838 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
839 int32_t y = static_cast<int32_t>(
840 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
841 sp<InputWindowHandle> touchedWindowHandle =
842 findTouchedWindowAtLocked(displayId, x, y, nullptr);
843 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700844 touchedWindowHandle->getApplicationToken() !=
845 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700846 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700847 ALOGI("Pruning input queue because user touched a different application while waiting "
848 "for %s",
849 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700850 return true;
851 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700852
853 // Alternatively, maybe there's a gesture monitor that could handle this event
854 std::vector<TouchedMonitor> gestureMonitors =
855 findTouchedGestureMonitorsLocked(displayId, {});
856 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
857 sp<Connection> connection =
858 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000859 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700860 // This monitor could take more input. Drop all events preceding this
861 // event, so that gesture monitor could get a chance to receive the stream
862 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
863 "responsive gesture monitor that may handle the event",
864 mAwaitedFocusedApplication->getName().c_str());
865 return true;
866 }
867 }
868 }
869
870 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
871 // yet been processed by some connections, the dispatcher will wait for these motion
872 // events to be processed before dispatching the key event. This is because these motion events
873 // may cause a new window to be launched, which the user might expect to receive focus.
874 // To prevent waiting forever for such events, just send the key to the currently focused window
875 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
876 ALOGD("Received a new pointer down event, stop waiting for events to process and "
877 "just send the pending key event to the focused window.");
878 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700879 }
880 return false;
881}
882
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700883bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700884 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700885 mInboundQueue.push_back(std::move(newEntry));
886 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800887 traceInboundQueueLengthLocked();
888
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700889 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700890 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700891 // Optimize app switch latency.
892 // If the application takes too long to catch up then we drop all events preceding
893 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700894 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700895 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700896 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700897 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700898 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700899 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800902#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700903 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 mAppSwitchSawKeyDown = false;
905 needWake = true;
906 }
907 }
908 }
909 break;
910 }
911
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700912 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700913 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
914 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700915 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700917 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800918 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100919 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700920 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
921 break;
922 }
923 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800924 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700925 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -0800926 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700927 // nothing to do
928 break;
929 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800930 }
931
932 return needWake;
933}
934
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700935void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700936 // Do not store sensor event in recent queue to avoid flooding the queue.
937 if (entry->type != EventEntry::Type::SENSOR) {
938 mRecentQueue.push_back(entry);
939 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700940 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700941 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 }
943}
944
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700945sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700946 int32_t y, TouchState* touchState,
947 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700948 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700949 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
950 LOG_ALWAYS_FATAL(
951 "Must provide a valid touch state if adding portal windows or outside targets");
952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700954 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800955 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800956 const InputWindowInfo* windowInfo = windowHandle->getInfo();
957 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100958 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800959
960 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100961 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
962 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
963 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800965 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700966 if (portalToDisplayId != ADISPLAY_ID_NONE &&
967 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800968 if (addPortalWindows) {
969 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700970 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800971 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700972 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700973 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800974 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800975 // Found window.
976 return windowHandle;
977 }
978 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800979
Michael Wright44753b12020-07-08 13:48:11 +0100980 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700981 touchState->addOrUpdateWindow(windowHandle,
982 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
983 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800986 }
987 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700988 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989}
990
Garfield Tane84e6f92019-08-29 17:28:41 -0700991std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700992 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000993 std::vector<TouchedMonitor> touchedMonitors;
994
995 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
996 addGestureMonitors(monitors, touchedMonitors);
997 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
998 const InputWindowInfo* windowInfo = portalWindow->getInfo();
999 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001000 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
1001 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +00001002 }
1003 return touchedMonitors;
1004}
1005
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001006void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001007 const char* reason;
1008 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001009 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001010#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001011 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001012#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001013 reason = "inbound event was dropped because the policy consumed it";
1014 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001015 case DropReason::DISABLED:
1016 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001017 ALOGI("Dropped event because input dispatch is disabled.");
1018 }
1019 reason = "inbound event was dropped because input dispatch is disabled";
1020 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001021 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001022 ALOGI("Dropped event because of pending overdue app switch.");
1023 reason = "inbound event was dropped because of pending overdue app switch";
1024 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001025 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001026 ALOGI("Dropped event because the current application is not responding and the user "
1027 "has started interacting with a different application.");
1028 reason = "inbound event was dropped because the current application is not responding "
1029 "and the user has started interacting with a different application";
1030 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001031 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001032 ALOGI("Dropped event because it is stale.");
1033 reason = "inbound event was dropped because it is stale";
1034 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001035 case DropReason::NO_POINTER_CAPTURE:
1036 ALOGI("Dropped event because there is no window with Pointer Capture.");
1037 reason = "inbound event was dropped because there is no window with Pointer Capture";
1038 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001039 case DropReason::NOT_DROPPED: {
1040 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001041 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001042 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043 }
1044
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001045 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001046 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1048 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001049 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001051 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001052 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1053 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001054 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1055 synthesizeCancelationEventsForAllConnectionsLocked(options);
1056 } else {
1057 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1058 synthesizeCancelationEventsForAllConnectionsLocked(options);
1059 }
1060 break;
1061 }
Chris Yef59a2f42020-10-16 12:55:26 -07001062 case EventEntry::Type::SENSOR: {
1063 break;
1064 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001065 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1066 break;
1067 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001068 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001069 case EventEntry::Type::CONFIGURATION_CHANGED:
1070 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001071 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001072 break;
1073 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001074 }
1075}
1076
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001077static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001078 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1079 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080}
1081
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001082bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1083 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1084 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1085 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001086}
1087
1088bool InputDispatcher::isAppSwitchPendingLocked() {
1089 return mAppSwitchDueTime != LONG_LONG_MAX;
1090}
1091
1092void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1093 mAppSwitchDueTime = LONG_LONG_MAX;
1094
1095#if DEBUG_APP_SWITCH
1096 if (handled) {
1097 ALOGD("App switch has arrived.");
1098 } else {
1099 ALOGD("App switch was abandoned.");
1100 }
1101#endif
1102}
1103
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001105 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001106}
1107
1108bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001109 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110 return false;
1111 }
1112
1113 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001114 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001115 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001117 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118
1119 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001120 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001121 return true;
1122}
1123
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001124void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1125 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001126}
1127
1128void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001129 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001130 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001131 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132 releaseInboundEventLocked(entry);
1133 }
1134 traceInboundQueueLengthLocked();
1135}
1136
1137void InputDispatcher::releasePendingEventLocked() {
1138 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001139 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001140 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141 }
1142}
1143
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001144void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001146 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001147#if DEBUG_DISPATCH_CYCLE
1148 ALOGD("Injected inbound event was dropped.");
1149#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001150 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001151 }
1152 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001153 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154 }
1155 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001156}
1157
1158void InputDispatcher::resetKeyRepeatLocked() {
1159 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001160 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001161 }
1162}
1163
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001164std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1165 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001166
Michael Wright2e732952014-09-24 13:26:59 -07001167 uint32_t policyFlags = entry->policyFlags &
1168 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001170 std::shared_ptr<KeyEntry> newEntry =
1171 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1172 entry->source, entry->displayId, policyFlags, entry->action,
1173 entry->flags, entry->keyCode, entry->scanCode,
1174 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001175
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001176 newEntry->syntheticRepeat = true;
1177 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001178 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001179 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180}
1181
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001182bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001183 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001184#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001185 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186#endif
1187
1188 // Reset key repeating in case a keyboard device was added or removed or something.
1189 resetKeyRepeatLocked();
1190
1191 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001192 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1193 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001194 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001195 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001196 return true;
1197}
1198
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001199bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1200 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001202 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1203 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204#endif
1205
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001206 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001207 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208 synthesizeCancelationEventsForAllConnectionsLocked(options);
1209 return true;
1210}
1211
Vishnu Nairad321cd2020-08-20 16:40:21 -07001212void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001213 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001214 if (mPendingEvent != nullptr) {
1215 // Move the pending event to the front of the queue. This will give the chance
1216 // for the pending event to get dispatched to the newly focused window
1217 mInboundQueue.push_front(mPendingEvent);
1218 mPendingEvent = nullptr;
1219 }
1220
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001221 std::unique_ptr<FocusEntry> focusEntry =
1222 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1223 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001224
1225 // This event should go to the front of the queue, but behind all other focus events
1226 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001227 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001228 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001229 [](const std::shared_ptr<EventEntry>& event) {
1230 return event->type == EventEntry::Type::FOCUS;
1231 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001232
1233 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001234 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001235}
1236
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001237void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001238 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001239 if (channel == nullptr) {
1240 return; // Window has gone away
1241 }
1242 InputTarget target;
1243 target.inputChannel = channel;
1244 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1245 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001246 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1247 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001248 std::string reason = std::string("reason=").append(entry->reason);
1249 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001250 dispatchEventLocked(currentTime, entry, {target});
1251}
1252
Prabir Pradhan99987712020-11-10 18:43:05 -08001253void InputDispatcher::dispatchPointerCaptureChangedLocked(
1254 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1255 DropReason& dropReason) {
1256 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1257 if (entry->pointerCaptureEnabled == haveWindowWithPointerCapture) {
1258 LOG_ALWAYS_FATAL_IF(mFocusedWindowRequestedPointerCapture,
1259 "The Pointer Capture state has already been dispatched to the window.");
1260 // Pointer capture was already forcefully disabled because of focus change.
1261 dropReason = DropReason::NOT_DROPPED;
1262 return;
1263 }
1264
1265 // Set drop reason for early returns
1266 dropReason = DropReason::NO_POINTER_CAPTURE;
1267
1268 sp<IBinder> token;
1269 if (entry->pointerCaptureEnabled) {
1270 // Enable Pointer Capture
1271 if (!mFocusedWindowRequestedPointerCapture) {
1272 // This can happen if a window requests capture and immediately releases capture.
1273 ALOGW("No window requested Pointer Capture.");
1274 return;
1275 }
1276 token = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
1277 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1278 mWindowTokenWithPointerCapture = token;
1279 } else {
1280 // Disable Pointer Capture
1281 token = mWindowTokenWithPointerCapture;
1282 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001283 if (mFocusedWindowRequestedPointerCapture) {
1284 mFocusedWindowRequestedPointerCapture = false;
1285 setPointerCaptureLocked(false);
1286 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001287 }
1288
1289 auto channel = getInputChannelLocked(token);
1290 if (channel == nullptr) {
1291 // Window has gone away, clean up Pointer Capture state.
1292 mWindowTokenWithPointerCapture = nullptr;
Prabir Pradhan7d030382020-12-21 07:58:35 -08001293 if (mFocusedWindowRequestedPointerCapture) {
1294 mFocusedWindowRequestedPointerCapture = false;
1295 setPointerCaptureLocked(false);
1296 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001297 return;
1298 }
1299 InputTarget target;
1300 target.inputChannel = channel;
1301 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1302 entry->dispatchInProgress = true;
1303 dispatchEventLocked(currentTime, entry, {target});
1304
1305 dropReason = DropReason::NOT_DROPPED;
1306}
1307
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001308bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001309 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001310 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001311 if (!entry->dispatchInProgress) {
1312 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1313 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1314 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1315 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001316 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001317 // We have seen two identical key downs in a row which indicates that the device
1318 // driver is automatically generating key repeats itself. We take note of the
1319 // repeat here, but we disable our own next key repeat timer since it is clear that
1320 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001321 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1322 // Make sure we don't get key down from a different device. If a different
1323 // device Id has same key pressed down, the new device Id will replace the
1324 // current one to hold the key repeat with repeat count reset.
1325 // In the future when got a KEY_UP on the device id, drop it and do not
1326 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1328 resetKeyRepeatLocked();
1329 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1330 } else {
1331 // Not a repeat. Save key down state in case we do see a repeat later.
1332 resetKeyRepeatLocked();
1333 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1334 }
1335 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001336 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1337 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001338 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001339#if DEBUG_INBOUND_EVENT_DETAILS
1340 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1341#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001342 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001343 resetKeyRepeatLocked();
1344 }
1345
1346 if (entry->repeatCount == 1) {
1347 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1348 } else {
1349 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1350 }
1351
1352 entry->dispatchInProgress = true;
1353
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001354 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001355 }
1356
1357 // Handle case where the policy asked us to try again later last time.
1358 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1359 if (currentTime < entry->interceptKeyWakeupTime) {
1360 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1361 *nextWakeupTime = entry->interceptKeyWakeupTime;
1362 }
1363 return false; // wait until next wakeup
1364 }
1365 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1366 entry->interceptKeyWakeupTime = 0;
1367 }
1368
1369 // Give the policy a chance to intercept the key.
1370 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1371 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001372 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001373 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001374 sp<IBinder> focusedWindowToken =
1375 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001376 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001377 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001378 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001379 return false; // wait for the command to run
1380 } else {
1381 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1382 }
1383 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001384 if (*dropReason == DropReason::NOT_DROPPED) {
1385 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001386 }
1387 }
1388
1389 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001390 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001391 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001392 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1393 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001394 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001395 return true;
1396 }
1397
1398 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001399 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001400 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001401 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001402 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001403 return false;
1404 }
1405
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001406 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001407 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001408 return true;
1409 }
1410
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001411 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001412 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001413
1414 // Dispatch the key.
1415 dispatchEventLocked(currentTime, entry, inputTargets);
1416 return true;
1417}
1418
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001419void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001420#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001421 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001422 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1423 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001424 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1425 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1426 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001427#endif
1428}
1429
Chris Yef59a2f42020-10-16 12:55:26 -07001430void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1431 mLock.unlock();
1432
1433 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1434 if (entry->accuracyChanged) {
1435 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1436 }
1437 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1438 entry->hwTimestamp, entry->values);
1439 mLock.lock();
1440}
1441
1442void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1443 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1444#if DEBUG_OUTBOUND_EVENT_DETAILS
1445 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1446 "source=0x%x, sensorType=%s",
1447 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
1448 NamedEnum::string(sensorType).c_str());
1449#endif
1450 std::unique_ptr<CommandEntry> commandEntry =
1451 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1452 commandEntry->sensorEntry = entry;
1453 postCommandLocked(std::move(commandEntry));
1454}
1455
1456bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1457#if DEBUG_OUTBOUND_EVENT_DETAILS
1458 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1459 NamedEnum::string(sensorType).c_str());
1460#endif
1461 { // acquire lock
1462 std::scoped_lock _l(mLock);
1463
1464 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1465 std::shared_ptr<EventEntry> entry = *it;
1466 if (entry->type == EventEntry::Type::SENSOR) {
1467 it = mInboundQueue.erase(it);
1468 releaseInboundEventLocked(entry);
1469 }
1470 }
1471 }
1472 return true;
1473}
1474
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001475bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001476 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001477 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001478 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001479 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001480 entry->dispatchInProgress = true;
1481
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001482 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 }
1484
1485 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001486 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001487 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001488 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1489 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001490 return true;
1491 }
1492
1493 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1494
1495 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001496 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001497
1498 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001499 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001500 if (isPointerEvent) {
1501 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001502 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001503 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001504 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001505 } else {
1506 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001507 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001508 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001509 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001510 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001511 return false;
1512 }
1513
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001514 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001515 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001516 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1517 return true;
1518 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001519 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001520 CancelationOptions::Mode mode(isPointerEvent
1521 ? CancelationOptions::CANCEL_POINTER_EVENTS
1522 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1523 CancelationOptions options(mode, "input event injection failed");
1524 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001525 return true;
1526 }
1527
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001528 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001529 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001530
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001531 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001532 std::unordered_map<int32_t, TouchState>::iterator it =
1533 mTouchStatesByDisplay.find(entry->displayId);
1534 if (it != mTouchStatesByDisplay.end()) {
1535 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001536 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001537 // The event has gone through these portal windows, so we add monitoring targets of
1538 // the corresponding displays as well.
1539 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001540 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001541 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001542 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001543 }
1544 }
1545 }
1546 }
1547
Michael Wrightd02c5b62014-02-10 15:10:22 -08001548 // Dispatch the motion.
1549 if (conflictingPointerActions) {
1550 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001551 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001552 synthesizeCancelationEventsForAllConnectionsLocked(options);
1553 }
1554 dispatchEventLocked(currentTime, entry, inputTargets);
1555 return true;
1556}
1557
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001558void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001559#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001560 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001561 ", policyFlags=0x%x, "
1562 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1563 "metaState=0x%x, buttonState=0x%x,"
1564 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001565 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1566 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1567 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001568
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001569 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001570 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001571 "x=%f, y=%f, pressure=%f, size=%f, "
1572 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1573 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001574 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1575 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1576 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1577 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1578 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1579 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1580 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1581 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1582 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1583 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001584 }
1585#endif
1586}
1587
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001588void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1589 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001590 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001591 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001592#if DEBUG_DISPATCH_CYCLE
1593 ALOGD("dispatchEventToCurrentInputTargets");
1594#endif
1595
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001596 updateInteractionTokensLocked(*eventEntry, inputTargets);
1597
Michael Wrightd02c5b62014-02-10 15:10:22 -08001598 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1599
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001600 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001602 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001603 sp<Connection> connection =
1604 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001605 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001606 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001607 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001608 if (DEBUG_FOCUS) {
1609 ALOGD("Dropping event delivery to target with channel '%s' because it "
1610 "is no longer registered with the input dispatcher.",
1611 inputTarget.inputChannel->getName().c_str());
1612 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001613 }
1614 }
1615}
1616
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001617void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1618 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1619 // If the policy decides to close the app, we will get a channel removal event via
1620 // unregisterInputChannel, and will clean up the connection that way. We are already not
1621 // sending new pointers to the connection when it blocked, but focused events will continue to
1622 // pile up.
1623 ALOGW("Canceling events for %s because it is unresponsive",
1624 connection->inputChannel->getName().c_str());
1625 if (connection->status == Connection::STATUS_NORMAL) {
1626 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1627 "application not responding");
1628 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001629 }
1630}
1631
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001632void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001633 if (DEBUG_FOCUS) {
1634 ALOGD("Resetting ANR timeouts.");
1635 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001636
1637 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001638 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001639 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001640}
1641
Tiger Huang721e26f2018-07-24 22:26:19 +08001642/**
1643 * Get the display id that the given event should go to. If this event specifies a valid display id,
1644 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1645 * Focused display is the display that the user most recently interacted with.
1646 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001647int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001648 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001649 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001650 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001651 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1652 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001653 break;
1654 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001655 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001656 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1657 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001658 break;
1659 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001660 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001661 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001662 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001663 case EventEntry::Type::DEVICE_RESET:
1664 case EventEntry::Type::SENSOR: {
1665 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001666 return ADISPLAY_ID_NONE;
1667 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001668 }
1669 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1670}
1671
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001672bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1673 const char* focusedWindowName) {
1674 if (mAnrTracker.empty()) {
1675 // already processed all events that we waited for
1676 mKeyIsWaitingForEventsTimeout = std::nullopt;
1677 return false;
1678 }
1679
1680 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1681 // Start the timer
1682 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1683 "focus to change",
1684 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001685 mKeyIsWaitingForEventsTimeout = currentTime +
1686 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1687 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001688 return true;
1689 }
1690
1691 // We still have pending events, and already started the timer
1692 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1693 return true; // Still waiting
1694 }
1695
1696 // Waited too long, and some connection still hasn't processed all motions
1697 // Just send the key to the focused window
1698 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1699 focusedWindowName);
1700 mKeyIsWaitingForEventsTimeout = std::nullopt;
1701 return false;
1702}
1703
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001704InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1705 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1706 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001707 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001708
Tiger Huang721e26f2018-07-24 22:26:19 +08001709 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001710 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001711 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001712 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1713
Michael Wrightd02c5b62014-02-10 15:10:22 -08001714 // If there is no currently focused window and no focused application
1715 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001716 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1717 ALOGI("Dropping %s event because there is no focused window or focused application in "
1718 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001719 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001720 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001721 }
1722
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001723 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1724 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1725 // start interacting with another application via touch (app switch). This code can be removed
1726 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1727 // an app is expected to have a focused window.
1728 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1729 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1730 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001731 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1732 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1733 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001734 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001735 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001736 ALOGW("Waiting because no window has focus but %s may eventually add a "
1737 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001738 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001739 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001740 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001741 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1742 // Already raised ANR. Drop the event
1743 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001744 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001745 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001746 } else {
1747 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001748 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001749 }
1750 }
1751
1752 // we have a valid, non-null focused window
1753 resetNoFocusedWindowTimeoutLocked();
1754
Michael Wrightd02c5b62014-02-10 15:10:22 -08001755 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001756 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001757 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001758 }
1759
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001760 if (focusedWindowHandle->getInfo()->paused) {
1761 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001762 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001763 }
1764
1765 // If the event is a key event, then we must wait for all previous events to
1766 // complete before delivering it because previous events may have the
1767 // side-effect of transferring focus to a different window and we want to
1768 // ensure that the following keys are sent to the new window.
1769 //
1770 // Suppose the user touches a button in a window then immediately presses "A".
1771 // If the button causes a pop-up window to appear then we want to ensure that
1772 // the "A" key is delivered to the new pop-up window. This is because users
1773 // often anticipate pending UI changes when typing on a keyboard.
1774 // To obtain this behavior, we must serialize key events with respect to all
1775 // prior input events.
1776 if (entry.type == EventEntry::Type::KEY) {
1777 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1778 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001779 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001780 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001781 }
1782
1783 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001784 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001785 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1786 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001787
1788 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001789 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001790}
1791
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001792/**
1793 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1794 * that are currently unresponsive.
1795 */
1796std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1797 const std::vector<TouchedMonitor>& monitors) const {
1798 std::vector<TouchedMonitor> responsiveMonitors;
1799 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1800 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1801 sp<Connection> connection = getConnectionLocked(
1802 monitor.monitor.inputChannel->getConnectionToken());
1803 if (connection == nullptr) {
1804 ALOGE("Could not find connection for monitor %s",
1805 monitor.monitor.inputChannel->getName().c_str());
1806 return false;
1807 }
1808 if (!connection->responsive) {
1809 ALOGW("Unresponsive monitor %s will not get the new gesture",
1810 connection->inputChannel->getName().c_str());
1811 return false;
1812 }
1813 return true;
1814 });
1815 return responsiveMonitors;
1816}
1817
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001818InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1819 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1820 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001821 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001822 enum InjectionPermission {
1823 INJECTION_PERMISSION_UNKNOWN,
1824 INJECTION_PERMISSION_GRANTED,
1825 INJECTION_PERMISSION_DENIED
1826 };
1827
Michael Wrightd02c5b62014-02-10 15:10:22 -08001828 // For security reasons, we defer updating the touch state until we are sure that
1829 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001830 int32_t displayId = entry.displayId;
1831 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001832 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1833
1834 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001835 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001836 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001837 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1838 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001839
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001840 // Copy current touch state into tempTouchState.
1841 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1842 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001843 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001844 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001845 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1846 mTouchStatesByDisplay.find(displayId);
1847 if (oldStateIt != mTouchStatesByDisplay.end()) {
1848 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001849 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001850 }
1851
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001852 bool isSplit = tempTouchState.split;
1853 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1854 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1855 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001856 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1857 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1858 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1859 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1860 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001861 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862 bool wrongDevice = false;
1863 if (newGesture) {
1864 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001865 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001866 ALOGI("Dropping event because a pointer for a different device is already down "
1867 "in display %" PRId32,
1868 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001869 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001870 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001871 switchedDevice = false;
1872 wrongDevice = true;
1873 goto Failed;
1874 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001875 tempTouchState.reset();
1876 tempTouchState.down = down;
1877 tempTouchState.deviceId = entry.deviceId;
1878 tempTouchState.source = entry.source;
1879 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001880 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001881 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001882 ALOGI("Dropping move event because a pointer for a different device is already active "
1883 "in display %" PRId32,
1884 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001885 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001886 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001887 switchedDevice = false;
1888 wrongDevice = true;
1889 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001890 }
1891
1892 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1893 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1894
Garfield Tan00f511d2019-06-12 16:55:40 -07001895 int32_t x;
1896 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001897 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001898 // Always dispatch mouse events to cursor position.
1899 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001900 x = int32_t(entry.xCursorPosition);
1901 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001902 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001903 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1904 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001905 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001906 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001907 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001908 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1909 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001910
1911 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001912 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001913 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001914
Michael Wrightd02c5b62014-02-10 15:10:22 -08001915 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001916 if (newTouchedWindowHandle != nullptr &&
1917 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001918 // New window supports splitting, but we should never split mouse events.
1919 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001920 } else if (isSplit) {
1921 // New window does not support splitting but we have already split events.
1922 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001923 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001924 }
1925
1926 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001927 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001928 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001929 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001930 }
1931
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001932 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1933 ALOGI("Not sending touch event to %s because it is paused",
1934 newTouchedWindowHandle->getName().c_str());
1935 newTouchedWindowHandle = nullptr;
1936 }
1937
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001938 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001939 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001940 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1941 if (!isResponsive) {
1942 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001943 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1944 newTouchedWindowHandle = nullptr;
1945 }
1946 }
1947
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001948 // Drop events that can't be trusted due to occlusion
1949 if (newTouchedWindowHandle != nullptr &&
1950 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1951 TouchOcclusionInfo occlusionInfo =
1952 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001953 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001954 if (DEBUG_TOUCH_OCCLUSION) {
1955 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1956 for (const auto& log : occlusionInfo.debugInfo) {
1957 ALOGD("%s", log.c_str());
1958 }
1959 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001960 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1961 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1962 ALOGW("Dropping untrusted touch event due to %s/%d",
1963 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1964 newTouchedWindowHandle = nullptr;
1965 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001966 }
1967 }
1968
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001969 // Also don't send the new touch event to unresponsive gesture monitors
1970 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1971
Michael Wright3dd60e22019-03-27 22:06:44 +00001972 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1973 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001974 "(%d, %d) in display %" PRId32 ".",
1975 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001976 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001977 goto Failed;
1978 }
1979
1980 if (newTouchedWindowHandle != nullptr) {
1981 // Set target flags.
1982 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1983 if (isSplit) {
1984 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001985 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001986 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1987 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1988 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1989 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1990 }
1991
1992 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001993 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1994 newHoverWindowHandle = nullptr;
1995 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001996 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001997 }
1998
1999 // Update the temporary touch state.
2000 BitSet32 pointerIds;
2001 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002002 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00002003 pointerIds.markBit(pointerId);
2004 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002005 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002006 }
2007
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002008 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002009 } else {
2010 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2011
2012 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002013 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002014 if (DEBUG_FOCUS) {
2015 ALOGD("Dropping event because the pointer is not down or we previously "
2016 "dropped the pointer down event in display %" PRId32,
2017 displayId);
2018 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002019 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002020 goto Failed;
2021 }
2022
2023 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002024 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002025 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002026 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2027 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002028
2029 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002030 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002031 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002032 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2033 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002034 if (DEBUG_FOCUS) {
2035 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2036 oldTouchedWindowHandle->getName().c_str(),
2037 newTouchedWindowHandle->getName().c_str(), displayId);
2038 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002039 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002040 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2041 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2042 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002043
2044 // Make a slippery entrance into the new window.
2045 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2046 isSplit = true;
2047 }
2048
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002049 int32_t targetFlags =
2050 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002051 if (isSplit) {
2052 targetFlags |= InputTarget::FLAG_SPLIT;
2053 }
2054 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2055 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002056 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2057 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002058 }
2059
2060 BitSet32 pointerIds;
2061 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002062 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002063 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002064 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002065 }
2066 }
2067 }
2068
2069 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002070 // Let the previous window know that the hover sequence is over, unless we already did it
2071 // when dispatching it as is to newTouchedWindowHandle.
2072 if (mLastHoverWindowHandle != nullptr &&
2073 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2074 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075#if DEBUG_HOVER
2076 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002077 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002078#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002079 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2080 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002081 }
2082
Garfield Tandf26e862020-07-01 20:18:19 -07002083 // Let the new window know that the hover sequence is starting, unless we already did it
2084 // when dispatching it as is to newTouchedWindowHandle.
2085 if (newHoverWindowHandle != nullptr &&
2086 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2087 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002088#if DEBUG_HOVER
2089 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002090 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002091#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002092 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2093 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2094 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002095 }
2096 }
2097
2098 // Check permission to inject into all touched foreground windows and ensure there
2099 // is at least one touched foreground window.
2100 {
2101 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002102 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002103 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2104 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002105 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002106 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002107 injectionPermission = INJECTION_PERMISSION_DENIED;
2108 goto Failed;
2109 }
2110 }
2111 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002112 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002113 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002114 ALOGI("Dropping event because there is no touched foreground window in display "
2115 "%" PRId32 " or gesture monitor to receive it.",
2116 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002117 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002118 goto Failed;
2119 }
2120
2121 // Permission granted to injection into all touched foreground windows.
2122 injectionPermission = INJECTION_PERMISSION_GRANTED;
2123 }
2124
2125 // Check whether windows listening for outside touches are owned by the same UID. If it is
2126 // set the policy flag that we will not reveal coordinate information to this window.
2127 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2128 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002129 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002130 if (foregroundWindowHandle) {
2131 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002132 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002133 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2134 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2135 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002136 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2137 InputTarget::FLAG_ZERO_COORDS,
2138 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002139 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002140 }
2141 }
2142 }
2143 }
2144
Michael Wrightd02c5b62014-02-10 15:10:22 -08002145 // If this is the first pointer going down and the touched window has a wallpaper
2146 // then also add the touched wallpaper windows so they are locked in for the duration
2147 // of the touch gesture.
2148 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2149 // engine only supports touch events. We would need to add a mechanism similar
2150 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2151 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2152 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002153 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002154 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002155 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002156 getWindowHandlesLocked(displayId);
2157 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002158 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002159 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002160 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002161 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002162 .addOrUpdateWindow(windowHandle,
2163 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2164 InputTarget::
2165 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2166 InputTarget::FLAG_DISPATCH_AS_IS,
2167 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002168 }
2169 }
2170 }
2171 }
2172
2173 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002174 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002175
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002176 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002177 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002178 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002179 }
2180
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002181 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002182 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002183 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002184 }
2185
Michael Wrightd02c5b62014-02-10 15:10:22 -08002186 // Drop the outside or hover touch windows since we will not care about them
2187 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002188 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002189
2190Failed:
2191 // Check injection permission once and for all.
2192 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002193 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002194 injectionPermission = INJECTION_PERMISSION_GRANTED;
2195 } else {
2196 injectionPermission = INJECTION_PERMISSION_DENIED;
2197 }
2198 }
2199
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002200 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2201 return injectionResult;
2202 }
2203
Michael Wrightd02c5b62014-02-10 15:10:22 -08002204 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002205 if (!wrongDevice) {
2206 if (switchedDevice) {
2207 if (DEBUG_FOCUS) {
2208 ALOGD("Conflicting pointer actions: Switched to a different device.");
2209 }
2210 *outConflictingPointerActions = true;
2211 }
2212
2213 if (isHoverAction) {
2214 // Started hovering, therefore no longer down.
2215 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002216 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002217 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2218 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002219 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002220 *outConflictingPointerActions = true;
2221 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002222 tempTouchState.reset();
2223 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2224 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2225 tempTouchState.deviceId = entry.deviceId;
2226 tempTouchState.source = entry.source;
2227 tempTouchState.displayId = displayId;
2228 }
2229 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2230 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2231 // All pointers up or canceled.
2232 tempTouchState.reset();
2233 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2234 // First pointer went down.
2235 if (oldState && oldState->down) {
2236 if (DEBUG_FOCUS) {
2237 ALOGD("Conflicting pointer actions: Down received while already down.");
2238 }
2239 *outConflictingPointerActions = true;
2240 }
2241 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2242 // One pointer went up.
2243 if (isSplit) {
2244 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2245 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002246
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002247 for (size_t i = 0; i < tempTouchState.windows.size();) {
2248 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2249 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2250 touchedWindow.pointerIds.clearBit(pointerId);
2251 if (touchedWindow.pointerIds.isEmpty()) {
2252 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2253 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002254 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002255 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002256 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002257 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002258 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002259 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002260
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002261 // Save changes unless the action was scroll in which case the temporary touch
2262 // state was only valid for this one action.
2263 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2264 if (tempTouchState.displayId >= 0) {
2265 mTouchStatesByDisplay[displayId] = tempTouchState;
2266 } else {
2267 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002268 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002269 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002270
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002271 // Update hover state.
2272 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002273 }
2274
Michael Wrightd02c5b62014-02-10 15:10:22 -08002275 return injectionResult;
2276}
2277
2278void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002279 int32_t targetFlags, BitSet32 pointerIds,
2280 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002281 std::vector<InputTarget>::iterator it =
2282 std::find_if(inputTargets.begin(), inputTargets.end(),
2283 [&windowHandle](const InputTarget& inputTarget) {
2284 return inputTarget.inputChannel->getConnectionToken() ==
2285 windowHandle->getToken();
2286 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002287
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002288 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002289
2290 if (it == inputTargets.end()) {
2291 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002292 std::shared_ptr<InputChannel> inputChannel =
2293 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002294 if (inputChannel == nullptr) {
2295 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2296 return;
2297 }
2298 inputTarget.inputChannel = inputChannel;
2299 inputTarget.flags = targetFlags;
2300 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2301 inputTargets.push_back(inputTarget);
2302 it = inputTargets.end() - 1;
2303 }
2304
2305 ALOG_ASSERT(it->flags == targetFlags);
2306 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2307
chaviw1ff3d1e2020-07-01 15:53:47 -07002308 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002309}
2310
Michael Wright3dd60e22019-03-27 22:06:44 +00002311void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002312 int32_t displayId, float xOffset,
2313 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002314 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2315 mGlobalMonitorsByDisplay.find(displayId);
2316
2317 if (it != mGlobalMonitorsByDisplay.end()) {
2318 const std::vector<Monitor>& monitors = it->second;
2319 for (const Monitor& monitor : monitors) {
2320 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002321 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002322 }
2323}
2324
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002325void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2326 float yOffset,
2327 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002328 InputTarget target;
2329 target.inputChannel = monitor.inputChannel;
2330 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002331 ui::Transform t;
2332 t.set(xOffset, yOffset);
2333 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002334 inputTargets.push_back(target);
2335}
2336
Michael Wrightd02c5b62014-02-10 15:10:22 -08002337bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002338 const InjectionState* injectionState) {
2339 if (injectionState &&
2340 (windowHandle == nullptr ||
2341 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2342 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002343 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002344 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002345 "owned by uid %d",
2346 injectionState->injectorPid, injectionState->injectorUid,
2347 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002348 } else {
2349 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002350 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002351 }
2352 return false;
2353 }
2354 return true;
2355}
2356
Robert Carrc9bf1d32020-04-13 17:21:08 -07002357/**
2358 * Indicate whether one window handle should be considered as obscuring
2359 * another window handle. We only check a few preconditions. Actually
2360 * checking the bounds is left to the caller.
2361 */
2362static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2363 const sp<InputWindowHandle>& otherHandle) {
2364 // Compare by token so cloned layers aren't counted
2365 if (haveSameToken(windowHandle, otherHandle)) {
2366 return false;
2367 }
2368 auto info = windowHandle->getInfo();
2369 auto otherInfo = otherHandle->getInfo();
2370 if (!otherInfo->visible) {
2371 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002372 } else if (otherInfo->alpha == 0 &&
2373 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2374 // Those act as if they were invisible, so we don't need to flag them.
2375 // We do want to potentially flag touchable windows even if they have 0
2376 // opacity, since they can consume touches and alter the effects of the
2377 // user interaction (eg. apps that rely on
2378 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2379 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2380 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002381 } else if (info->ownerUid == otherInfo->ownerUid) {
2382 // If ownerUid is the same we don't generate occlusion events as there
2383 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002384 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002385 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002386 return false;
2387 } else if (otherInfo->displayId != info->displayId) {
2388 return false;
2389 }
2390 return true;
2391}
2392
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002393/**
2394 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2395 * untrusted, one should check:
2396 *
2397 * 1. If result.hasBlockingOcclusion is true.
2398 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2399 * BLOCK_UNTRUSTED.
2400 *
2401 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2402 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2403 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2404 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2405 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2406 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2407 *
2408 * If neither of those is true, then it means the touch can be allowed.
2409 */
2410InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2411 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002412 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2413 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002414 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2415 TouchOcclusionInfo info;
2416 info.hasBlockingOcclusion = false;
2417 info.obscuringOpacity = 0;
2418 info.obscuringUid = -1;
2419 std::map<int32_t, float> opacityByUid;
2420 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2421 if (windowHandle == otherHandle) {
2422 break; // All future windows are below us. Exit early.
2423 }
2424 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2425 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002426 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2427 if (DEBUG_TOUCH_OCCLUSION) {
2428 info.debugInfo.push_back(
2429 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2430 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002431 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2432 // we perform the checks below to see if the touch can be propagated or not based on the
2433 // window's touch occlusion mode
2434 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2435 info.hasBlockingOcclusion = true;
2436 info.obscuringUid = otherInfo->ownerUid;
2437 info.obscuringPackage = otherInfo->packageName;
2438 break;
2439 }
2440 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2441 uint32_t uid = otherInfo->ownerUid;
2442 float opacity =
2443 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2444 // Given windows A and B:
2445 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2446 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2447 opacityByUid[uid] = opacity;
2448 if (opacity > info.obscuringOpacity) {
2449 info.obscuringOpacity = opacity;
2450 info.obscuringUid = uid;
2451 info.obscuringPackage = otherInfo->packageName;
2452 }
2453 }
2454 }
2455 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002456 if (DEBUG_TOUCH_OCCLUSION) {
2457 info.debugInfo.push_back(
2458 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2459 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002460 return info;
2461}
2462
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002463std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2464 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002465 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2466 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002467 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2468 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2469 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002470 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002471 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002472 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002473 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2474 info->frameTop, info->frameRight, info->frameBottom,
2475 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002476 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2477 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002478}
2479
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002480bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2481 if (occlusionInfo.hasBlockingOcclusion) {
2482 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2483 occlusionInfo.obscuringUid);
2484 return false;
2485 }
2486 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2487 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2488 "%.2f, maximum allowed = %.2f)",
2489 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2490 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2491 return false;
2492 }
2493 return true;
2494}
2495
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002496bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2497 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002498 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002499 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002500 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002501 if (windowHandle == otherHandle) {
2502 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002503 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002505 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002506 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002507 return true;
2508 }
2509 }
2510 return false;
2511}
2512
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002513bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2514 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002515 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002516 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002517 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002518 if (windowHandle == otherHandle) {
2519 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002520 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002521 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002522 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002523 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002524 return true;
2525 }
2526 }
2527 return false;
2528}
2529
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002530std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002531 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002532 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002533 if (applicationHandle != nullptr) {
2534 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002535 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002536 } else {
2537 return applicationHandle->getName();
2538 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002539 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002540 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002541 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002542 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002543 }
2544}
2545
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002546void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002547 if (eventEntry.type == EventEntry::Type::FOCUS ||
2548 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2549 // Focus or pointer capture changed events are passed to apps, but do not represent user
2550 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002551 return;
2552 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002553 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002554 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002555 if (focusedWindowHandle != nullptr) {
2556 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002557 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002558#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002559 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002560#endif
2561 return;
2562 }
2563 }
2564
2565 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002566 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002567 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002568 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2569 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002570 return;
2571 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002572
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002573 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002574 eventType = USER_ACTIVITY_EVENT_TOUCH;
2575 }
2576 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002577 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002578 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002579 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2580 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002581 return;
2582 }
2583 eventType = USER_ACTIVITY_EVENT_BUTTON;
2584 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002585 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002586 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002587 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002588 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002589 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -08002590 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002591 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002592 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002593 break;
2594 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002595 }
2596
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002597 std::unique_ptr<CommandEntry> commandEntry =
2598 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002599 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002601 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002602}
2603
2604void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002605 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002606 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002607 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002608 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002609 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002610 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002611 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002612 ATRACE_NAME(message.c_str());
2613 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614#if DEBUG_DISPATCH_CYCLE
2615 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002616 "globalScaleFactor=%f, pointerIds=0x%x %s",
2617 connection->getInputChannelName().c_str(), inputTarget.flags,
2618 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2619 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002620#endif
2621
2622 // Skip this event if the connection status is not normal.
2623 // We don't want to enqueue additional outbound events if the connection is broken.
2624 if (connection->status != Connection::STATUS_NORMAL) {
2625#if DEBUG_DISPATCH_CYCLE
2626 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002627 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002628#endif
2629 return;
2630 }
2631
2632 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002633 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2634 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2635 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002636 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002637
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002638 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002639 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002640 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002641 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002642 if (!splitMotionEntry) {
2643 return; // split event was dropped
2644 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002645 if (DEBUG_FOCUS) {
2646 ALOGD("channel '%s' ~ Split motion event.",
2647 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002648 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002649 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002650 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2651 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002652 return;
2653 }
2654 }
2655
2656 // Not splitting. Enqueue dispatch entries for the event as is.
2657 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2658}
2659
2660void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002661 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002662 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002663 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002664 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002665 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002666 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002667 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002668 ATRACE_NAME(message.c_str());
2669 }
2670
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002671 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002672
2673 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002674 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002675 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002676 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002677 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002678 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002679 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002680 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002681 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002682 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002683 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002684 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002685 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002686
2687 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002688 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002689 startDispatchCycleLocked(currentTime, connection);
2690 }
2691}
2692
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002693void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002694 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002695 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002696 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002697 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002698 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2699 connection->getInputChannelName().c_str(),
2700 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002701 ATRACE_NAME(message.c_str());
2702 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002703 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002704 if (!(inputTargetFlags & dispatchMode)) {
2705 return;
2706 }
2707 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2708
2709 // This is a new event.
2710 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002711 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002712 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002713
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002714 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2715 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002716 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002717 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002718 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002719 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002720 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002721 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002722 dispatchEntry->resolvedAction = keyEntry.action;
2723 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002724
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002725 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2726 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002727#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002728 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2729 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002730#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002731 return; // skip the inconsistent event
2732 }
2733 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002734 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002735
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002736 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002737 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002738 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2739 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2740 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2741 static_cast<int32_t>(IdGenerator::Source::OTHER);
2742 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002743 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2744 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2745 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2746 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2747 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2748 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2749 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2750 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2751 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2752 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2753 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002754 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002755 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002756 }
2757 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002758 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2759 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002760#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002761 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2762 "event",
2763 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002764#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002765 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2766 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002767
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002768 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002769 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2770 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2771 }
2772 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2773 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002775
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002776 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2777 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002778#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002779 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2780 "event",
2781 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002782#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002783 return; // skip the inconsistent event
2784 }
2785
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002786 dispatchEntry->resolvedEventId =
2787 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2788 ? mIdGenerator.nextId()
2789 : motionEntry.id;
2790 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2791 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2792 ") to MotionEvent(id=0x%" PRIx32 ").",
2793 motionEntry.id, dispatchEntry->resolvedEventId);
2794 ATRACE_NAME(message.c_str());
2795 }
2796
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002797 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002798 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002799
2800 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002801 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002802 case EventEntry::Type::FOCUS:
2803 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002804 break;
2805 }
Chris Yef59a2f42020-10-16 12:55:26 -07002806 case EventEntry::Type::SENSOR: {
2807 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2808 break;
2809 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002810 case EventEntry::Type::CONFIGURATION_CHANGED:
2811 case EventEntry::Type::DEVICE_RESET: {
2812 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002813 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002814 break;
2815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002816 }
2817
2818 // Remember that we are waiting for this dispatch to complete.
2819 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002820 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002821 }
2822
2823 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002824 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002825 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002826}
2827
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002828/**
2829 * This function is purely for debugging. It helps us understand where the user interaction
2830 * was taking place. For example, if user is touching launcher, we will see a log that user
2831 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2832 * We will see both launcher and wallpaper in that list.
2833 * Once the interaction with a particular set of connections starts, no new logs will be printed
2834 * until the set of interacted connections changes.
2835 *
2836 * The following items are skipped, to reduce the logspam:
2837 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2838 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2839 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2840 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2841 * Both of those ACTION_UP events would not be logged
2842 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2843 * will not be logged. This is omitted to reduce the amount of data printed.
2844 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2845 * gesture monitor is the only connection receiving the remainder of the gesture.
2846 */
2847void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2848 const std::vector<InputTarget>& targets) {
2849 // Skip ACTION_UP events, and all events other than keys and motions
2850 if (entry.type == EventEntry::Type::KEY) {
2851 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2852 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2853 return;
2854 }
2855 } else if (entry.type == EventEntry::Type::MOTION) {
2856 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2857 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2858 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2859 return;
2860 }
2861 } else {
2862 return; // Not a key or a motion
2863 }
2864
2865 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2866 std::vector<sp<Connection>> newConnections;
2867 for (const InputTarget& target : targets) {
2868 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2869 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2870 continue; // Skip windows that receive ACTION_OUTSIDE
2871 }
2872
2873 sp<IBinder> token = target.inputChannel->getConnectionToken();
2874 sp<Connection> connection = getConnectionLocked(token);
2875 if (connection == nullptr || connection->monitor) {
2876 continue; // We only need to keep track of the non-monitor connections.
2877 }
2878 newConnectionTokens.insert(std::move(token));
2879 newConnections.emplace_back(connection);
2880 }
2881 if (newConnectionTokens == mInteractionConnectionTokens) {
2882 return; // no change
2883 }
2884 mInteractionConnectionTokens = newConnectionTokens;
2885
2886 std::string windowList;
2887 for (const sp<Connection>& connection : newConnections) {
2888 windowList += connection->getWindowName() + ", ";
2889 }
2890 std::string message = "Interaction with windows: " + windowList;
2891 if (windowList.empty()) {
2892 message += "<none>";
2893 }
2894 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2895}
2896
chaviwfd6d3512019-03-25 13:23:49 -07002897void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002898 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002899 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002900 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2901 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002902 return;
2903 }
2904
Vishnu Nairad321cd2020-08-20 16:40:21 -07002905 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2906 if (focusedToken == token) {
2907 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002908 return;
2909 }
2910
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002911 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2912 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002913 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002914 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002915}
2916
2917void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002918 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002919 if (ATRACE_ENABLED()) {
2920 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002921 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002922 ATRACE_NAME(message.c_str());
2923 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002925 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002926#endif
2927
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002928 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2929 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002930 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002931 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002932 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002933 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002934
2935 // Publish the event.
2936 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002937 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2938 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002939 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002940 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2941 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002942
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002943 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002944 status = connection->inputPublisher
2945 .publishKeyEvent(dispatchEntry->seq,
2946 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2947 keyEntry.source, keyEntry.displayId,
2948 std::move(hmac), dispatchEntry->resolvedAction,
2949 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2950 keyEntry.scanCode, keyEntry.metaState,
2951 keyEntry.repeatCount, keyEntry.downTime,
2952 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002953 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002954 }
2955
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002956 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002957 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002958
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002959 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002960 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002961
chaviw82357092020-01-28 13:13:06 -08002962 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002963 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002964 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2965 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002966 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002967 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2968 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002969 // Don't apply window scale here since we don't want scale to affect raw
2970 // coordinates. The scale will be sent back to the client and applied
2971 // later when requesting relative coordinates.
2972 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2973 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002974 }
2975 usingCoords = scaledCoords;
2976 }
2977 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002978 // We don't want the dispatch target to know.
2979 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002980 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002981 scaledCoords[i].clear();
2982 }
2983 usingCoords = scaledCoords;
2984 }
2985 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002986
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002987 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002988
2989 // Publish the motion event.
2990 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002991 .publishMotionEvent(dispatchEntry->seq,
2992 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002993 motionEntry.deviceId, motionEntry.source,
2994 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002995 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002996 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002997 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002998 motionEntry.edgeFlags, motionEntry.metaState,
2999 motionEntry.buttonState,
3000 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07003001 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003002 motionEntry.xPrecision, motionEntry.yPrecision,
3003 motionEntry.xCursorPosition,
3004 motionEntry.yCursorPosition,
3005 motionEntry.downTime, motionEntry.eventTime,
3006 motionEntry.pointerCount,
3007 motionEntry.pointerProperties, usingCoords);
3008 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003009 break;
3010 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003011
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003012 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003013 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003014 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003015 focusEntry.id,
3016 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003017 mInTouchMode);
3018 break;
3019 }
3020
Prabir Pradhan99987712020-11-10 18:43:05 -08003021 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3022 const auto& captureEntry =
3023 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3024 status = connection->inputPublisher
3025 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3026 captureEntry.pointerCaptureEnabled);
3027 break;
3028 }
3029
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003030 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003031 case EventEntry::Type::DEVICE_RESET:
3032 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003033 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003034 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003035 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003036 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003037 }
3038
3039 // Check the result.
3040 if (status) {
3041 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003042 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003043 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003044 "This is unexpected because the wait queue is empty, so the pipe "
3045 "should be empty and we shouldn't have any problems writing an "
3046 "event to it, status=%d",
3047 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003048 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3049 } else {
3050 // Pipe is full and we are waiting for the app to finish process some events
3051 // before sending more events to it.
3052#if DEBUG_DISPATCH_CYCLE
3053 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003054 "waiting for the application to catch up",
3055 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003056#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003057 }
3058 } else {
3059 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003060 "status=%d",
3061 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003062 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3063 }
3064 return;
3065 }
3066
3067 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003068 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3069 connection->outboundQueue.end(),
3070 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003071 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003072 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003073 if (connection->responsive) {
3074 mAnrTracker.insert(dispatchEntry->timeoutTime,
3075 connection->inputChannel->getConnectionToken());
3076 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003077 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003078 }
3079}
3080
chaviw09c8d2d2020-08-24 15:48:26 -07003081std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3082 size_t size;
3083 switch (event.type) {
3084 case VerifiedInputEvent::Type::KEY: {
3085 size = sizeof(VerifiedKeyEvent);
3086 break;
3087 }
3088 case VerifiedInputEvent::Type::MOTION: {
3089 size = sizeof(VerifiedMotionEvent);
3090 break;
3091 }
3092 }
3093 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3094 return mHmacKeyManager.sign(start, size);
3095}
3096
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003097const std::array<uint8_t, 32> InputDispatcher::getSignature(
3098 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3099 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3100 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3101 // Only sign events up and down events as the purely move events
3102 // are tied to their up/down counterparts so signing would be redundant.
3103 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3104 verifiedEvent.actionMasked = actionMasked;
3105 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003106 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003107 }
3108 return INVALID_HMAC;
3109}
3110
3111const std::array<uint8_t, 32> InputDispatcher::getSignature(
3112 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3113 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3114 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3115 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003116 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003117}
3118
Michael Wrightd02c5b62014-02-10 15:10:22 -08003119void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003120 const sp<Connection>& connection, uint32_t seq,
3121 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003122#if DEBUG_DISPATCH_CYCLE
3123 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003124 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003125#endif
3126
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003127 if (connection->status == Connection::STATUS_BROKEN ||
3128 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003129 return;
3130 }
3131
3132 // Notify other system components and prepare to start the next dispatch cycle.
3133 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
3134}
3135
3136void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003137 const sp<Connection>& connection,
3138 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003139#if DEBUG_DISPATCH_CYCLE
3140 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003141 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003142#endif
3143
3144 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003145 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003146 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003147 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003148 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003149
3150 // The connection appears to be unrecoverably broken.
3151 // Ignore already broken or zombie connections.
3152 if (connection->status == Connection::STATUS_NORMAL) {
3153 connection->status = Connection::STATUS_BROKEN;
3154
3155 if (notify) {
3156 // Notify other system components.
3157 onDispatchCycleBrokenLocked(currentTime, connection);
3158 }
3159 }
3160}
3161
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003162void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3163 while (!queue.empty()) {
3164 DispatchEntry* dispatchEntry = queue.front();
3165 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003166 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167 }
3168}
3169
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003170void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003171 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003172 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003173 }
3174 delete dispatchEntry;
3175}
3176
3177int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3178 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3179
3180 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003181 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003182
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003183 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003184 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003185 "fd=%d, events=0x%x",
3186 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003187 return 0; // remove the callback
3188 }
3189
3190 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003191 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003192 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3193 if (!(events & ALOOPER_EVENT_INPUT)) {
3194 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003195 "events=0x%x",
3196 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003197 return 1;
3198 }
3199
3200 nsecs_t currentTime = now();
3201 bool gotOne = false;
3202 status_t status;
3203 for (;;) {
3204 uint32_t seq;
3205 bool handled;
3206 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3207 if (status) {
3208 break;
3209 }
3210 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3211 gotOne = true;
3212 }
3213 if (gotOne) {
3214 d->runCommandsLockedInterruptible();
3215 if (status == WOULD_BLOCK) {
3216 return 1;
3217 }
3218 }
3219
3220 notify = status != DEAD_OBJECT || !connection->monitor;
3221 if (notify) {
3222 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003223 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003224 }
3225 } else {
3226 // Monitor channels are never explicitly unregistered.
3227 // We do it automatically when the remote endpoint is closed so don't warn
3228 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003229 const bool stillHaveWindowHandle =
3230 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3231 nullptr;
3232 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003233 if (notify) {
3234 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003235 "events=0x%x",
3236 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003237 }
3238 }
3239
Garfield Tan15601662020-09-22 15:32:38 -07003240 // Remove the channel.
3241 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003242 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003243 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244}
3245
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003246void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 const CancelationOptions& options) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003248 for (const auto& [fd, connection] : mConnectionsByFd) {
3249 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003250 }
3251}
3252
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003253void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003254 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003255 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3256 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3257}
3258
3259void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3260 const CancelationOptions& options,
3261 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3262 for (const auto& it : monitorsByDisplay) {
3263 const std::vector<Monitor>& monitors = it.second;
3264 for (const Monitor& monitor : monitors) {
3265 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003266 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003267 }
3268}
3269
Michael Wrightd02c5b62014-02-10 15:10:22 -08003270void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003271 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003272 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003273 if (connection == nullptr) {
3274 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003275 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003276
3277 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003278}
3279
3280void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3281 const sp<Connection>& connection, const CancelationOptions& options) {
3282 if (connection->status == Connection::STATUS_BROKEN) {
3283 return;
3284 }
3285
3286 nsecs_t currentTime = now();
3287
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003288 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003289 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003290
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003291 if (cancelationEvents.empty()) {
3292 return;
3293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003294#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003295 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3296 "with reality: %s, mode=%d.",
3297 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3298 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003299#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003300
3301 InputTarget target;
3302 sp<InputWindowHandle> windowHandle =
3303 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3304 if (windowHandle != nullptr) {
3305 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003306 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003307 target.globalScaleFactor = windowInfo->globalScaleFactor;
3308 }
3309 target.inputChannel = connection->inputChannel;
3310 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3311
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003312 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003313 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003314 switch (cancelationEventEntry->type) {
3315 case EventEntry::Type::KEY: {
3316 logOutboundKeyDetails("cancel - ",
3317 static_cast<const KeyEntry&>(*cancelationEventEntry));
3318 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003319 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003320 case EventEntry::Type::MOTION: {
3321 logOutboundMotionDetails("cancel - ",
3322 static_cast<const MotionEntry&>(*cancelationEventEntry));
3323 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003324 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003325 case EventEntry::Type::FOCUS:
3326 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3327 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003328 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003329 break;
3330 }
3331 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003332 case EventEntry::Type::DEVICE_RESET:
3333 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003334 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003335 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003336 break;
3337 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003338 }
3339
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003340 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3341 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003342 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003343
3344 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003345}
3346
Svet Ganov5d3bc372020-01-26 23:11:07 -08003347void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3348 const sp<Connection>& connection) {
3349 if (connection->status == Connection::STATUS_BROKEN) {
3350 return;
3351 }
3352
3353 nsecs_t currentTime = now();
3354
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003355 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003356 connection->inputState.synthesizePointerDownEvents(currentTime);
3357
3358 if (downEvents.empty()) {
3359 return;
3360 }
3361
3362#if DEBUG_OUTBOUND_EVENT_DETAILS
3363 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3364 connection->getInputChannelName().c_str(), downEvents.size());
3365#endif
3366
3367 InputTarget target;
3368 sp<InputWindowHandle> windowHandle =
3369 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3370 if (windowHandle != nullptr) {
3371 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003372 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003373 target.globalScaleFactor = windowInfo->globalScaleFactor;
3374 }
3375 target.inputChannel = connection->inputChannel;
3376 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3377
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003378 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003379 switch (downEventEntry->type) {
3380 case EventEntry::Type::MOTION: {
3381 logOutboundMotionDetails("down - ",
3382 static_cast<const MotionEntry&>(*downEventEntry));
3383 break;
3384 }
3385
3386 case EventEntry::Type::KEY:
3387 case EventEntry::Type::FOCUS:
3388 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003389 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003390 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3391 case EventEntry::Type::SENSOR: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003392 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003393 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003394 break;
3395 }
3396 }
3397
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003398 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3399 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003400 }
3401
3402 startDispatchCycleLocked(currentTime, connection);
3403}
3404
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003405std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3406 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003407 ALOG_ASSERT(pointerIds.value != 0);
3408
3409 uint32_t splitPointerIndexMap[MAX_POINTERS];
3410 PointerProperties splitPointerProperties[MAX_POINTERS];
3411 PointerCoords splitPointerCoords[MAX_POINTERS];
3412
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003413 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003414 uint32_t splitPointerCount = 0;
3415
3416 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003417 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003418 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003419 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003420 uint32_t pointerId = uint32_t(pointerProperties.id);
3421 if (pointerIds.hasBit(pointerId)) {
3422 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3423 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3424 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003425 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003426 splitPointerCount += 1;
3427 }
3428 }
3429
3430 if (splitPointerCount != pointerIds.count()) {
3431 // This is bad. We are missing some of the pointers that we expected to deliver.
3432 // Most likely this indicates that we received an ACTION_MOVE events that has
3433 // different pointer ids than we expected based on the previous ACTION_DOWN
3434 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3435 // in this way.
3436 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003437 "we expected there to be %d pointers. This probably means we received "
3438 "a broken sequence of pointer ids from the input device.",
3439 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003440 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003441 }
3442
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003443 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003445 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3446 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003447 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3448 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003449 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003450 uint32_t pointerId = uint32_t(pointerProperties.id);
3451 if (pointerIds.hasBit(pointerId)) {
3452 if (pointerIds.count() == 1) {
3453 // The first/last pointer went down/up.
3454 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003455 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003456 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3457 ? AMOTION_EVENT_ACTION_CANCEL
3458 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003459 } else {
3460 // A secondary pointer went down/up.
3461 uint32_t splitPointerIndex = 0;
3462 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3463 splitPointerIndex += 1;
3464 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003465 action = maskedAction |
3466 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467 }
3468 } else {
3469 // An unrelated pointer changed.
3470 action = AMOTION_EVENT_ACTION_MOVE;
3471 }
3472 }
3473
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003474 int32_t newId = mIdGenerator.nextId();
3475 if (ATRACE_ENABLED()) {
3476 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3477 ") to MotionEvent(id=0x%" PRIx32 ").",
3478 originalMotionEntry.id, newId);
3479 ATRACE_NAME(message.c_str());
3480 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003481 std::unique_ptr<MotionEntry> splitMotionEntry =
3482 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3483 originalMotionEntry.deviceId, originalMotionEntry.source,
3484 originalMotionEntry.displayId,
3485 originalMotionEntry.policyFlags, action,
3486 originalMotionEntry.actionButton,
3487 originalMotionEntry.flags, originalMotionEntry.metaState,
3488 originalMotionEntry.buttonState,
3489 originalMotionEntry.classification,
3490 originalMotionEntry.edgeFlags,
3491 originalMotionEntry.xPrecision,
3492 originalMotionEntry.yPrecision,
3493 originalMotionEntry.xCursorPosition,
3494 originalMotionEntry.yCursorPosition,
3495 originalMotionEntry.downTime, splitPointerCount,
3496 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003497
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003498 if (originalMotionEntry.injectionState) {
3499 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003500 splitMotionEntry->injectionState->refCount += 1;
3501 }
3502
3503 return splitMotionEntry;
3504}
3505
3506void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3507#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003508 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003509#endif
3510
3511 bool needWake;
3512 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003513 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003514
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003515 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3516 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3517 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003518 } // release lock
3519
3520 if (needWake) {
3521 mLooper->wake();
3522 }
3523}
3524
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003525/**
3526 * If one of the meta shortcuts is detected, process them here:
3527 * Meta + Backspace -> generate BACK
3528 * Meta + Enter -> generate HOME
3529 * This will potentially overwrite keyCode and metaState.
3530 */
3531void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003532 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003533 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3534 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3535 if (keyCode == AKEYCODE_DEL) {
3536 newKeyCode = AKEYCODE_BACK;
3537 } else if (keyCode == AKEYCODE_ENTER) {
3538 newKeyCode = AKEYCODE_HOME;
3539 }
3540 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003541 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003542 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003543 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003544 keyCode = newKeyCode;
3545 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3546 }
3547 } else if (action == AKEY_EVENT_ACTION_UP) {
3548 // In order to maintain a consistent stream of up and down events, check to see if the key
3549 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3550 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003551 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003552 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003553 auto replacementIt = mReplacedKeys.find(replacement);
3554 if (replacementIt != mReplacedKeys.end()) {
3555 keyCode = replacementIt->second;
3556 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003557 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3558 }
3559 }
3560}
3561
Michael Wrightd02c5b62014-02-10 15:10:22 -08003562void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3563#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003564 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3565 "policyFlags=0x%x, action=0x%x, "
3566 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3567 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3568 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3569 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003570#endif
3571 if (!validateKeyEvent(args->action)) {
3572 return;
3573 }
3574
3575 uint32_t policyFlags = args->policyFlags;
3576 int32_t flags = args->flags;
3577 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003578 // InputDispatcher tracks and generates key repeats on behalf of
3579 // whatever notifies it, so repeatCount should always be set to 0
3580 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003581 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3582 policyFlags |= POLICY_FLAG_VIRTUAL;
3583 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3584 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003585 if (policyFlags & POLICY_FLAG_FUNCTION) {
3586 metaState |= AMETA_FUNCTION_ON;
3587 }
3588
3589 policyFlags |= POLICY_FLAG_TRUSTED;
3590
Michael Wright78f24442014-08-06 15:55:28 -07003591 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003592 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003593
Michael Wrightd02c5b62014-02-10 15:10:22 -08003594 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003595 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003596 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3597 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003598
Michael Wright2b3c3302018-03-02 17:19:13 +00003599 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003601 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3602 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003603 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003604 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003605
Michael Wrightd02c5b62014-02-10 15:10:22 -08003606 bool needWake;
3607 { // acquire lock
3608 mLock.lock();
3609
3610 if (shouldSendKeyToInputFilterLocked(args)) {
3611 mLock.unlock();
3612
3613 policyFlags |= POLICY_FLAG_FILTERED;
3614 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3615 return; // event was consumed by the filter
3616 }
3617
3618 mLock.lock();
3619 }
3620
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003621 std::unique_ptr<KeyEntry> newEntry =
3622 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3623 args->displayId, policyFlags, args->action, flags,
3624 keyCode, args->scanCode, metaState, repeatCount,
3625 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003626
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003627 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003628 mLock.unlock();
3629 } // release lock
3630
3631 if (needWake) {
3632 mLooper->wake();
3633 }
3634}
3635
3636bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3637 return mInputFilterEnabled;
3638}
3639
3640void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3641#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003642 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3643 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003644 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3645 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003646 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003647 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3648 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3649 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3650 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003651 for (uint32_t i = 0; i < args->pointerCount; i++) {
3652 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003653 "x=%f, y=%f, pressure=%f, size=%f, "
3654 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3655 "orientation=%f",
3656 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3657 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3658 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3659 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3660 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3661 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3662 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3663 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3664 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3665 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003666 }
3667#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003668 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3669 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003670 return;
3671 }
3672
3673 uint32_t policyFlags = args->policyFlags;
3674 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003675
3676 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003677 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003678 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3679 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003680 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003681 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003682
3683 bool needWake;
3684 { // acquire lock
3685 mLock.lock();
3686
3687 if (shouldSendMotionToInputFilterLocked(args)) {
3688 mLock.unlock();
3689
3690 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003691 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003692 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3693 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003694 args->metaState, args->buttonState, args->classification, transform,
3695 args->xPrecision, args->yPrecision, args->xCursorPosition,
3696 args->yCursorPosition, args->downTime, args->eventTime,
3697 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003698
3699 policyFlags |= POLICY_FLAG_FILTERED;
3700 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3701 return; // event was consumed by the filter
3702 }
3703
3704 mLock.lock();
3705 }
3706
3707 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003708 std::unique_ptr<MotionEntry> newEntry =
3709 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3710 args->source, args->displayId, policyFlags,
3711 args->action, args->actionButton, args->flags,
3712 args->metaState, args->buttonState,
3713 args->classification, args->edgeFlags,
3714 args->xPrecision, args->yPrecision,
3715 args->xCursorPosition, args->yCursorPosition,
3716 args->downTime, args->pointerCount,
3717 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003718
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003719 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003720 mLock.unlock();
3721 } // release lock
3722
3723 if (needWake) {
3724 mLooper->wake();
3725 }
3726}
3727
Chris Yef59a2f42020-10-16 12:55:26 -07003728void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3729#if DEBUG_INBOUND_EVENT_DETAILS
3730 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3731 " sensorType=%s",
3732 args->id, args->eventTime, args->deviceId, args->source,
3733 NamedEnum::string(args->sensorType).c_str());
3734#endif
3735
3736 bool needWake;
3737 { // acquire lock
3738 mLock.lock();
3739
3740 // Just enqueue a new sensor event.
3741 std::unique_ptr<SensorEntry> newEntry =
3742 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3743 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3744 args->sensorType, args->accuracy,
3745 args->accuracyChanged, args->values);
3746
3747 needWake = enqueueInboundEventLocked(std::move(newEntry));
3748 mLock.unlock();
3749 } // release lock
3750
3751 if (needWake) {
3752 mLooper->wake();
3753 }
3754}
3755
Michael Wrightd02c5b62014-02-10 15:10:22 -08003756bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003757 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003758}
3759
3760void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3761#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003762 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003763 "switchMask=0x%08x",
3764 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003765#endif
3766
3767 uint32_t policyFlags = args->policyFlags;
3768 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003769 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003770}
3771
3772void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3773#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003774 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3775 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003776#endif
3777
3778 bool needWake;
3779 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003780 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003781
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003782 std::unique_ptr<DeviceResetEntry> newEntry =
3783 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3784 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003785 } // release lock
3786
3787 if (needWake) {
3788 mLooper->wake();
3789 }
3790}
3791
Prabir Pradhan7e186182020-11-10 13:56:45 -08003792void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3793#if DEBUG_INBOUND_EVENT_DETAILS
3794 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3795 args->enabled ? "true" : "false");
3796#endif
3797
Prabir Pradhan99987712020-11-10 18:43:05 -08003798 bool needWake;
3799 { // acquire lock
3800 std::scoped_lock _l(mLock);
3801 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3802 args->enabled);
3803 needWake = enqueueInboundEventLocked(std::move(entry));
3804 } // release lock
3805
3806 if (needWake) {
3807 mLooper->wake();
3808 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003809}
3810
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003811InputEventInjectionResult InputDispatcher::injectInputEvent(
3812 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3813 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814#if DEBUG_INBOUND_EVENT_DETAILS
3815 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003816 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3817 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003818#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003819 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003820
3821 policyFlags |= POLICY_FLAG_INJECTED;
3822 if (hasInjectionPermission(injectorPid, injectorUid)) {
3823 policyFlags |= POLICY_FLAG_TRUSTED;
3824 }
3825
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003826 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003827 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003828 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003829 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3830 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003831 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003832 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003833 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003834
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003835 int32_t flags = incomingKey.getFlags();
3836 int32_t keyCode = incomingKey.getKeyCode();
3837 int32_t metaState = incomingKey.getMetaState();
3838 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003839 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003840 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003841 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003842 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3843 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3844 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003845
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003846 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3847 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003848 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003849
3850 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3851 android::base::Timer t;
3852 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3853 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3854 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3855 std::to_string(t.duration().count()).c_str());
3856 }
3857 }
3858
3859 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003860 std::unique_ptr<KeyEntry> injectedEntry =
3861 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3862 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3863 incomingKey.getDisplayId(), policyFlags, action,
3864 flags, keyCode, incomingKey.getScanCode(), metaState,
3865 incomingKey.getRepeatCount(),
3866 incomingKey.getDownTime());
3867 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003868 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003869 }
3870
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003871 case AINPUT_EVENT_TYPE_MOTION: {
3872 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3873 int32_t action = motionEvent->getAction();
3874 size_t pointerCount = motionEvent->getPointerCount();
3875 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3876 int32_t actionButton = motionEvent->getActionButton();
3877 int32_t displayId = motionEvent->getDisplayId();
3878 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003879 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003880 }
3881
3882 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3883 nsecs_t eventTime = motionEvent->getEventTime();
3884 android::base::Timer t;
3885 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3886 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3887 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3888 std::to_string(t.duration().count()).c_str());
3889 }
3890 }
3891
3892 mLock.lock();
3893 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3894 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003895 std::unique_ptr<MotionEntry> injectedEntry =
3896 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3897 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3898 motionEvent->getDisplayId(), policyFlags, action,
3899 actionButton, motionEvent->getFlags(),
3900 motionEvent->getMetaState(),
3901 motionEvent->getButtonState(),
3902 motionEvent->getClassification(),
3903 motionEvent->getEdgeFlags(),
3904 motionEvent->getXPrecision(),
3905 motionEvent->getYPrecision(),
3906 motionEvent->getRawXCursorPosition(),
3907 motionEvent->getRawYCursorPosition(),
3908 motionEvent->getDownTime(),
3909 uint32_t(pointerCount), pointerProperties,
3910 samplePointerCoords, motionEvent->getXOffset(),
3911 motionEvent->getYOffset());
3912 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003913 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3914 sampleEventTimes += 1;
3915 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003916 std::unique_ptr<MotionEntry> nextInjectedEntry =
3917 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3918 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3919 motionEvent->getDisplayId(), policyFlags,
3920 action, actionButton, motionEvent->getFlags(),
3921 motionEvent->getMetaState(),
3922 motionEvent->getButtonState(),
3923 motionEvent->getClassification(),
3924 motionEvent->getEdgeFlags(),
3925 motionEvent->getXPrecision(),
3926 motionEvent->getYPrecision(),
3927 motionEvent->getRawXCursorPosition(),
3928 motionEvent->getRawYCursorPosition(),
3929 motionEvent->getDownTime(),
3930 uint32_t(pointerCount), pointerProperties,
3931 samplePointerCoords,
3932 motionEvent->getXOffset(),
3933 motionEvent->getYOffset());
3934 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003935 }
3936 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003937 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003938
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003939 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003940 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003941 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003942 }
3943
3944 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003945 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003946 injectionState->injectionIsAsync = true;
3947 }
3948
3949 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003950 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003951
3952 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003953 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003954 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003955 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003956 }
3957
3958 mLock.unlock();
3959
3960 if (needWake) {
3961 mLooper->wake();
3962 }
3963
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003964 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003965 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003966 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003967
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003968 if (syncMode == InputEventInjectionSync::NONE) {
3969 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003970 } else {
3971 for (;;) {
3972 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003973 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974 break;
3975 }
3976
3977 nsecs_t remainingTimeout = endTime - now();
3978 if (remainingTimeout <= 0) {
3979#if DEBUG_INJECTION
3980 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003981 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003983 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003984 break;
3985 }
3986
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003987 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988 }
3989
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003990 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3991 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003992 while (injectionState->pendingForegroundDispatches != 0) {
3993#if DEBUG_INJECTION
3994 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003995 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003996#endif
3997 nsecs_t remainingTimeout = endTime - now();
3998 if (remainingTimeout <= 0) {
3999#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004000 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
4001 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004002#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004003 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004004 break;
4005 }
4006
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004007 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004008 }
4009 }
4010 }
4011
4012 injectionState->release();
4013 } // release lock
4014
4015#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004016 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004017 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004018#endif
4019
4020 return injectionResult;
4021}
4022
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004023std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004024 std::array<uint8_t, 32> calculatedHmac;
4025 std::unique_ptr<VerifiedInputEvent> result;
4026 switch (event.getType()) {
4027 case AINPUT_EVENT_TYPE_KEY: {
4028 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4029 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4030 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004031 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004032 break;
4033 }
4034 case AINPUT_EVENT_TYPE_MOTION: {
4035 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4036 VerifiedMotionEvent verifiedMotionEvent =
4037 verifiedMotionEventFromMotionEvent(motionEvent);
4038 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004039 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004040 break;
4041 }
4042 default: {
4043 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4044 return nullptr;
4045 }
4046 }
4047 if (calculatedHmac == INVALID_HMAC) {
4048 return nullptr;
4049 }
4050 if (calculatedHmac != event.getHmac()) {
4051 return nullptr;
4052 }
4053 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004054}
4055
Michael Wrightd02c5b62014-02-10 15:10:22 -08004056bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004057 return injectorUid == 0 ||
4058 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059}
4060
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004061void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004062 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004063 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004064 if (injectionState) {
4065#if DEBUG_INJECTION
4066 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004067 "injectorPid=%d, injectorUid=%d",
4068 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069#endif
4070
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004071 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004072 // Log the outcome since the injector did not wait for the injection result.
4073 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004074 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004075 ALOGV("Asynchronous input event injection succeeded.");
4076 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004077 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004078 ALOGW("Asynchronous input event injection failed.");
4079 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004080 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004081 ALOGW("Asynchronous input event injection permission denied.");
4082 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004083 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004084 ALOGW("Asynchronous input event injection timed out.");
4085 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004086 case InputEventInjectionResult::PENDING:
4087 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4088 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004089 }
4090 }
4091
4092 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004093 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004094 }
4095}
4096
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004097void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4098 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004099 if (injectionState) {
4100 injectionState->pendingForegroundDispatches += 1;
4101 }
4102}
4103
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004104void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4105 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004106 if (injectionState) {
4107 injectionState->pendingForegroundDispatches -= 1;
4108
4109 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004110 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004111 }
4112 }
4113}
4114
Vishnu Nairad321cd2020-08-20 16:40:21 -07004115const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004116 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004117 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4118 auto it = mWindowHandlesByDisplay.find(displayId);
4119 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004120}
4121
Michael Wrightd02c5b62014-02-10 15:10:22 -08004122sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004123 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004124 if (windowHandleToken == nullptr) {
4125 return nullptr;
4126 }
4127
Arthur Hungb92218b2018-08-14 12:00:21 +08004128 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004129 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004130 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004131 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004132 return windowHandle;
4133 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004134 }
4135 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004136 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004137}
4138
Vishnu Nairad321cd2020-08-20 16:40:21 -07004139sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4140 int displayId) const {
4141 if (windowHandleToken == nullptr) {
4142 return nullptr;
4143 }
4144
4145 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4146 if (windowHandle->getToken() == windowHandleToken) {
4147 return windowHandle;
4148 }
4149 }
4150 return nullptr;
4151}
4152
4153sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4154 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4155 return getWindowHandleLocked(focusedToken, displayId);
4156}
4157
Mady Mellor017bcd12020-06-23 19:12:00 +00004158bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4159 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004160 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004161 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004162 if (handle->getId() == windowHandle->getId() &&
4163 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004164 if (windowHandle->getInfo()->displayId != it.first) {
4165 ALOGE("Found window %s in display %" PRId32
4166 ", but it should belong to display %" PRId32,
4167 windowHandle->getName().c_str(), it.first,
4168 windowHandle->getInfo()->displayId);
4169 }
4170 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004171 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004172 }
4173 }
4174 return false;
4175}
4176
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004177bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4178 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4179 const bool noInputChannel =
4180 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4181 if (connection != nullptr && noInputChannel) {
4182 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4183 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4184 return false;
4185 }
4186
4187 if (connection == nullptr) {
4188 if (!noInputChannel) {
4189 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4190 }
4191 return false;
4192 }
4193 if (!connection->responsive) {
4194 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4195 return false;
4196 }
4197 return true;
4198}
4199
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004200std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4201 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004202 size_t count = mInputChannelsByToken.count(token);
4203 if (count == 0) {
4204 return nullptr;
4205 }
4206 return mInputChannelsByToken.at(token);
4207}
4208
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004209void InputDispatcher::updateWindowHandlesForDisplayLocked(
4210 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4211 if (inputWindowHandles.empty()) {
4212 // Remove all handles on a display if there are no windows left.
4213 mWindowHandlesByDisplay.erase(displayId);
4214 return;
4215 }
4216
4217 // Since we compare the pointer of input window handles across window updates, we need
4218 // to make sure the handle object for the same window stays unchanged across updates.
4219 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004220 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004221 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004222 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004223 }
4224
4225 std::vector<sp<InputWindowHandle>> newHandles;
4226 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4227 if (!handle->updateInfo()) {
4228 // handle no longer valid
4229 continue;
4230 }
4231
4232 const InputWindowInfo* info = handle->getInfo();
4233 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4234 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4235 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004236 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4237 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4238 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004239 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004240 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004241 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004242 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004243 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004244 }
4245
4246 if (info->displayId != displayId) {
4247 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4248 handle->getName().c_str(), displayId, info->displayId);
4249 continue;
4250 }
4251
Robert Carredd13602020-04-13 17:24:34 -07004252 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4253 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004254 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004255 oldHandle->updateFrom(handle);
4256 newHandles.push_back(oldHandle);
4257 } else {
4258 newHandles.push_back(handle);
4259 }
4260 }
4261
4262 // Insert or replace
4263 mWindowHandlesByDisplay[displayId] = newHandles;
4264}
4265
Arthur Hung72d8dc32020-03-28 00:48:39 +00004266void InputDispatcher::setInputWindows(
4267 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4268 { // acquire lock
4269 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004270 for (const auto& [displayId, handles] : handlesPerDisplay) {
4271 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004272 }
4273 }
4274 // Wake up poll loop since it may need to make new input dispatching choices.
4275 mLooper->wake();
4276}
4277
Arthur Hungb92218b2018-08-14 12:00:21 +08004278/**
4279 * Called from InputManagerService, update window handle list by displayId that can receive input.
4280 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4281 * If set an empty list, remove all handles from the specific display.
4282 * For focused handle, check if need to change and send a cancel event to previous one.
4283 * For removed handle, check if need to send a cancel event if already in touch.
4284 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004285void InputDispatcher::setInputWindowsLocked(
4286 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004287 if (DEBUG_FOCUS) {
4288 std::string windowList;
4289 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4290 windowList += iwh->getName() + " ";
4291 }
4292 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004294
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004295 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4296 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4297 const bool noInputWindow =
4298 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4299 if (noInputWindow && window->getToken() != nullptr) {
4300 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4301 window->getName().c_str());
4302 window->releaseChannel();
4303 }
4304 }
4305
Arthur Hung72d8dc32020-03-28 00:48:39 +00004306 // Copy old handles for release if they are no longer present.
4307 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004308
Arthur Hung72d8dc32020-03-28 00:48:39 +00004309 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004310
Vishnu Nair958da932020-08-21 17:12:37 -07004311 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4312 if (mLastHoverWindowHandle &&
4313 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4314 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004315 mLastHoverWindowHandle = nullptr;
4316 }
4317
Vishnu Nair958da932020-08-21 17:12:37 -07004318 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4319 if (focusedToken) {
4320 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4321 if (result != FocusResult::OK) {
4322 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4323 }
4324 }
4325
4326 std::optional<FocusRequest> focusRequest =
4327 getOptionalValueByKey(mPendingFocusRequests, displayId);
4328 if (focusRequest) {
4329 // If the window from the pending request is now visible, provide it focus.
4330 FocusResult result = handleFocusRequestLocked(*focusRequest);
4331 if (result != FocusResult::NOT_VISIBLE) {
4332 // Drop the request if we were able to change the focus or we cannot change
4333 // it for another reason.
4334 mPendingFocusRequests.erase(displayId);
4335 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004336 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004337
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004338 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4339 mTouchStatesByDisplay.find(displayId);
4340 if (stateIt != mTouchStatesByDisplay.end()) {
4341 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004342 for (size_t i = 0; i < state.windows.size();) {
4343 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004344 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004345 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004346 ALOGD("Touched window was removed: %s in display %" PRId32,
4347 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004348 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004349 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004350 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4351 if (touchedInputChannel != nullptr) {
4352 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4353 "touched window was removed");
4354 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004355 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004356 state.windows.erase(state.windows.begin() + i);
4357 } else {
4358 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004359 }
4360 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004361 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004362
Arthur Hung72d8dc32020-03-28 00:48:39 +00004363 // Release information for windows that are no longer present.
4364 // This ensures that unused input channels are released promptly.
4365 // Otherwise, they might stick around until the window handle is destroyed
4366 // which might not happen until the next GC.
4367 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004368 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004369 if (DEBUG_FOCUS) {
4370 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004371 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004372 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004373 // To avoid making too many calls into the compat framework, only
4374 // check for window flags when windows are going away.
4375 // TODO(b/157929241) : delete this. This is only needed temporarily
4376 // in order to gather some data about the flag usage
4377 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4378 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4379 oldWindowHandle->getName().c_str());
4380 if (mCompatService != nullptr) {
4381 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4382 oldWindowHandle->getInfo()->ownerUid);
4383 }
4384 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004385 }
chaviw291d88a2019-02-14 10:33:58 -08004386 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004387}
4388
4389void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004390 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004391 if (DEBUG_FOCUS) {
4392 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4393 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4394 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004395 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004396 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004397
Chris Yea209fde2020-07-22 13:54:51 -07004398 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004399 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004400
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004401 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4402 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004403 }
4404
Chris Yea209fde2020-07-22 13:54:51 -07004405 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004406 if (inputApplicationHandle != nullptr) {
4407 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4408 } else {
4409 mFocusedApplicationHandlesByDisplay.erase(displayId);
4410 }
4411
4412 // No matter what the old focused application was, stop waiting on it because it is
4413 // no longer focused.
4414 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004415 } // release lock
4416
4417 // Wake up poll loop since it may need to make new input dispatching choices.
4418 mLooper->wake();
4419}
4420
Tiger Huang721e26f2018-07-24 22:26:19 +08004421/**
4422 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4423 * the display not specified.
4424 *
4425 * We track any unreleased events for each window. If a window loses the ability to receive the
4426 * released event, we will send a cancel event to it. So when the focused display is changed, we
4427 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4428 * display. The display-specified events won't be affected.
4429 */
4430void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004431 if (DEBUG_FOCUS) {
4432 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4433 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004434 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004435 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004436
4437 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004438 sp<IBinder> oldFocusedWindowToken =
4439 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4440 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004441 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004442 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004443 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004444 CancelationOptions
4445 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4446 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004447 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004448 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4449 }
4450 }
4451 mFocusedDisplayId = displayId;
4452
Chris Ye3c2d6f52020-08-09 10:39:48 -07004453 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004454 sp<IBinder> newFocusedWindowToken =
4455 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4456 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004457
Vishnu Nairad321cd2020-08-20 16:40:21 -07004458 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004459 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004460 if (!mFocusedWindowTokenByDisplay.empty()) {
4461 ALOGE("But another display has a focused window\n%s",
4462 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004463 }
4464 }
4465 }
4466
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004467 if (DEBUG_FOCUS) {
4468 logDispatchStateLocked();
4469 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004470 } // release lock
4471
4472 // Wake up poll loop since it may need to make new input dispatching choices.
4473 mLooper->wake();
4474}
4475
Michael Wrightd02c5b62014-02-10 15:10:22 -08004476void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004477 if (DEBUG_FOCUS) {
4478 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4479 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004480
4481 bool changed;
4482 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004483 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004484
4485 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4486 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004487 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004488 }
4489
4490 if (mDispatchEnabled && !enabled) {
4491 resetAndDropEverythingLocked("dispatcher is being disabled");
4492 }
4493
4494 mDispatchEnabled = enabled;
4495 mDispatchFrozen = frozen;
4496 changed = true;
4497 } else {
4498 changed = false;
4499 }
4500
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004501 if (DEBUG_FOCUS) {
4502 logDispatchStateLocked();
4503 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004504 } // release lock
4505
4506 if (changed) {
4507 // Wake up poll loop since it may need to make new input dispatching choices.
4508 mLooper->wake();
4509 }
4510}
4511
4512void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004513 if (DEBUG_FOCUS) {
4514 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4515 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004516
4517 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004518 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004519
4520 if (mInputFilterEnabled == enabled) {
4521 return;
4522 }
4523
4524 mInputFilterEnabled = enabled;
4525 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4526 } // release lock
4527
4528 // Wake up poll loop since there might be work to do to drop everything.
4529 mLooper->wake();
4530}
4531
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004532void InputDispatcher::setInTouchMode(bool inTouchMode) {
4533 std::scoped_lock lock(mLock);
4534 mInTouchMode = inTouchMode;
4535}
4536
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004537void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4538 if (opacity < 0 || opacity > 1) {
4539 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4540 return;
4541 }
4542
4543 std::scoped_lock lock(mLock);
4544 mMaximumObscuringOpacityForTouch = opacity;
4545}
4546
4547void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4548 std::scoped_lock lock(mLock);
4549 mBlockUntrustedTouchesMode = mode;
4550}
4551
chaviwfbe5d9c2018-12-26 12:23:37 -08004552bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4553 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004554 if (DEBUG_FOCUS) {
4555 ALOGD("Trivial transfer to same window.");
4556 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004557 return true;
4558 }
4559
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004561 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004562
chaviwfbe5d9c2018-12-26 12:23:37 -08004563 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4564 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004565 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004566 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567 return false;
4568 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004569 if (DEBUG_FOCUS) {
4570 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4571 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4572 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004573 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004574 if (DEBUG_FOCUS) {
4575 ALOGD("Cannot transfer focus because windows are on different displays.");
4576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577 return false;
4578 }
4579
4580 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004581 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4582 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004583 for (size_t i = 0; i < state.windows.size(); i++) {
4584 const TouchedWindow& touchedWindow = state.windows[i];
4585 if (touchedWindow.windowHandle == fromWindowHandle) {
4586 int32_t oldTargetFlags = touchedWindow.targetFlags;
4587 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004588
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004589 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004590
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004591 int32_t newTargetFlags = oldTargetFlags &
4592 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4593 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004594 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004595
Jeff Brownf086ddb2014-02-11 14:28:48 -08004596 found = true;
4597 goto Found;
4598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004599 }
4600 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004601 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004602
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004603 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004604 if (DEBUG_FOCUS) {
4605 ALOGD("Focus transfer failed because from window did not have focus.");
4606 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004607 return false;
4608 }
4609
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004610 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4611 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004612 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004613 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004614 CancelationOptions
4615 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4616 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004617 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004618 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004619 }
4620
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004621 if (DEBUG_FOCUS) {
4622 logDispatchStateLocked();
4623 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004624 } // release lock
4625
4626 // Wake up poll loop since it may need to make new input dispatching choices.
4627 mLooper->wake();
4628 return true;
4629}
4630
4631void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004632 if (DEBUG_FOCUS) {
4633 ALOGD("Resetting and dropping all events (%s).", reason);
4634 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004635
4636 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4637 synthesizeCancelationEventsForAllConnectionsLocked(options);
4638
4639 resetKeyRepeatLocked();
4640 releasePendingEventLocked();
4641 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004642 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004643
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004644 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004645 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004647 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004648}
4649
4650void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004651 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004652 dumpDispatchStateLocked(dump);
4653
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004654 std::istringstream stream(dump);
4655 std::string line;
4656
4657 while (std::getline(stream, line, '\n')) {
4658 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004659 }
4660}
4661
Vishnu Nairad321cd2020-08-20 16:40:21 -07004662std::string InputDispatcher::dumpFocusedWindowsLocked() {
4663 if (mFocusedWindowTokenByDisplay.empty()) {
4664 return INDENT "FocusedWindows: <none>\n";
4665 }
4666
4667 std::string dump;
4668 dump += INDENT "FocusedWindows:\n";
4669 for (auto& it : mFocusedWindowTokenByDisplay) {
4670 const int32_t displayId = it.first;
4671 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4672 if (windowHandle) {
4673 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4674 windowHandle->getName().c_str());
4675 } else {
4676 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4677 " has focused token without a window'\n",
4678 displayId);
4679 }
4680 }
4681 return dump;
4682}
4683
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004684std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4685 if (mPendingFocusRequests.empty()) {
4686 return INDENT "mPendingFocusRequests: <none>\n";
4687 }
4688
4689 std::string dump;
4690 dump += INDENT "mPendingFocusRequests:\n";
4691 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4692 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4693 // try to resolve them to actual windows.
4694 std::string windowName = getConnectionNameLocked(focusRequest.token);
4695 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4696 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4697 displayId, windowName.c_str(), focusedWindowName.c_str());
4698 }
4699 return dump;
4700}
4701
Prabir Pradhan99987712020-11-10 18:43:05 -08004702std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4703 std::string dump;
4704
4705 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4706 toString(mFocusedWindowRequestedPointerCapture));
4707
4708 std::string windowName = "None";
4709 if (mWindowTokenWithPointerCapture) {
4710 const sp<InputWindowHandle> captureWindowHandle =
4711 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4712 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4713 : "token has capture without window";
4714 }
4715 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4716
4717 return dump;
4718}
4719
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004720void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004721 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4722 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4723 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004724 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004725
Tiger Huang721e26f2018-07-24 22:26:19 +08004726 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4727 dump += StringPrintf(INDENT "FocusedApplications:\n");
4728 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4729 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004730 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004731 const std::chrono::duration timeout =
4732 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004733 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004734 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004735 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004736 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004737 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004738 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004739 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004740
Vishnu Nairad321cd2020-08-20 16:40:21 -07004741 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004742 dump += dumpPendingFocusRequestsLocked();
Prabir Pradhan99987712020-11-10 18:43:05 -08004743 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004744
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004745 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004746 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004747 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4748 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004749 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004750 state.displayId, toString(state.down), toString(state.split),
4751 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004752 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004753 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004754 for (size_t i = 0; i < state.windows.size(); i++) {
4755 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004756 dump += StringPrintf(INDENT4
4757 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4758 i, touchedWindow.windowHandle->getName().c_str(),
4759 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004760 }
4761 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004762 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004763 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004764 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004765 dump += INDENT3 "Portal windows:\n";
4766 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004767 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004768 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4769 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004770 }
4771 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004772 }
4773 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004774 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004775 }
4776
Arthur Hungb92218b2018-08-14 12:00:21 +08004777 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004778 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004779 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004780 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004781 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004782 dump += INDENT2 "Windows:\n";
4783 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004784 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004785 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004786
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004787 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004788 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004789 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004790 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004791 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004792 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004793 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004794 i, windowInfo->name.c_str(), windowInfo->id,
4795 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004796 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004797 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004798 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004799 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004800 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004801 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004802 windowInfo->frameLeft, windowInfo->frameTop,
4803 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004804 windowInfo->globalScaleFactor,
4805 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004806 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004807 dump += StringPrintf(", inputFeatures=%s",
4808 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004809 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004810 "ms, trustedOverlay=%s, hasToken=%s, "
4811 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004812 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004813 millis(windowInfo->dispatchingTimeout),
4814 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004815 toString(windowInfo->token != nullptr),
4816 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004817 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004818 }
4819 } else {
4820 dump += INDENT2 "Windows: <none>\n";
4821 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004822 }
4823 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004824 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004825 }
4826
Michael Wright3dd60e22019-03-27 22:06:44 +00004827 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004828 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004829 const std::vector<Monitor>& monitors = it.second;
4830 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4831 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004832 }
4833 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004834 const std::vector<Monitor>& monitors = it.second;
4835 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4836 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004837 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004838 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004839 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004840 }
4841
4842 nsecs_t currentTime = now();
4843
4844 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004845 if (!mRecentQueue.empty()) {
4846 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004847 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004848 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004849 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004850 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004851 }
4852 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004853 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004854 }
4855
4856 // Dump event currently being dispatched.
4857 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004858 dump += INDENT "PendingEvent:\n";
4859 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004860 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004861 dump += StringPrintf(", age=%" PRId64 "ms\n",
4862 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004863 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004864 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004865 }
4866
4867 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004868 if (!mInboundQueue.empty()) {
4869 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004870 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004871 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004872 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004873 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004874 }
4875 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004876 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004877 }
4878
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004879 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004880 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004881 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4882 const KeyReplacement& replacement = pair.first;
4883 int32_t newKeyCode = pair.second;
4884 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004885 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004886 }
4887 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004888 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004889 }
4890
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004891 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004892 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004893 for (const auto& pair : mConnectionsByFd) {
4894 const sp<Connection>& connection = pair.second;
4895 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004896 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004897 pair.first, connection->getInputChannelName().c_str(),
4898 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004899 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004901 if (!connection->outboundQueue.empty()) {
4902 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4903 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004904 dump += dumpQueue(connection->outboundQueue, currentTime);
4905
Michael Wrightd02c5b62014-02-10 15:10:22 -08004906 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004907 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004908 }
4909
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004910 if (!connection->waitQueue.empty()) {
4911 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4912 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004913 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004914 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004915 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004916 }
4917 }
4918 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004919 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004920 }
4921
4922 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004923 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4924 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004925 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004926 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004927 }
4928
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004929 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004930 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4931 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4932 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004933}
4934
Michael Wright3dd60e22019-03-27 22:06:44 +00004935void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4936 const size_t numMonitors = monitors.size();
4937 for (size_t i = 0; i < numMonitors; i++) {
4938 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004939 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004940 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4941 dump += "\n";
4942 }
4943}
4944
Garfield Tan15601662020-09-22 15:32:38 -07004945base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4946 const std::string& name) {
4947#if DEBUG_CHANNEL_CREATION
4948 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004949#endif
4950
Garfield Tan15601662020-09-22 15:32:38 -07004951 std::shared_ptr<InputChannel> serverChannel;
4952 std::unique_ptr<InputChannel> clientChannel;
4953 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4954
4955 if (result) {
4956 return base::Error(result) << "Failed to open input channel pair with name " << name;
4957 }
4958
Michael Wrightd02c5b62014-02-10 15:10:22 -08004959 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004960 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004961 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004962
Garfield Tan15601662020-09-22 15:32:38 -07004963 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004964 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004965 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004966
Michael Wrightd02c5b62014-02-10 15:10:22 -08004967 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4968 } // release lock
4969
4970 // Wake the looper because some connections have changed.
4971 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004972 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004973}
4974
Garfield Tan15601662020-09-22 15:32:38 -07004975base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004976 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004977 std::shared_ptr<InputChannel> serverChannel;
4978 std::unique_ptr<InputChannel> clientChannel;
4979 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4980 if (result) {
4981 return base::Error(result) << "Failed to open input channel pair with name " << name;
4982 }
4983
Michael Wright3dd60e22019-03-27 22:06:44 +00004984 { // acquire lock
4985 std::scoped_lock _l(mLock);
4986
4987 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004988 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4989 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004990 }
4991
Garfield Tan15601662020-09-22 15:32:38 -07004992 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004993
Garfield Tan15601662020-09-22 15:32:38 -07004994 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004995 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004996 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004997
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004998 auto& monitorsByDisplay =
4999 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00005000 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00005001
5002 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00005003 }
Garfield Tan15601662020-09-22 15:32:38 -07005004
Michael Wright3dd60e22019-03-27 22:06:44 +00005005 // Wake the looper because some connections have changed.
5006 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005007 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005008}
5009
Garfield Tan15601662020-09-22 15:32:38 -07005010status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005011 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005012 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005013
Garfield Tan15601662020-09-22 15:32:38 -07005014 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005015 if (status) {
5016 return status;
5017 }
5018 } // release lock
5019
5020 // Wake the poll loop because removing the connection may have changed the current
5021 // synchronization state.
5022 mLooper->wake();
5023 return OK;
5024}
5025
Garfield Tan15601662020-09-22 15:32:38 -07005026status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5027 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005028 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005029 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005030 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005031 return BAD_VALUE;
5032 }
5033
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005034 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005035 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07005036
Michael Wrightd02c5b62014-02-10 15:10:22 -08005037 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005038 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005039 }
5040
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005041 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005042
5043 nsecs_t currentTime = now();
5044 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5045
5046 connection->status = Connection::STATUS_ZOMBIE;
5047 return OK;
5048}
5049
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005050void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5051 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5052 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005053}
5054
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005055void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005056 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005057 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005058 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005059 std::vector<Monitor>& monitors = it->second;
5060 const size_t numMonitors = monitors.size();
5061 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005062 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005063 monitors.erase(monitors.begin() + i);
5064 break;
5065 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005066 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005067 if (monitors.empty()) {
5068 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005069 } else {
5070 ++it;
5071 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005072 }
5073}
5074
Michael Wright3dd60e22019-03-27 22:06:44 +00005075status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5076 { // acquire lock
5077 std::scoped_lock _l(mLock);
5078 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5079
5080 if (!foundDisplayId) {
5081 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5082 return BAD_VALUE;
5083 }
5084 int32_t displayId = foundDisplayId.value();
5085
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005086 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5087 mTouchStatesByDisplay.find(displayId);
5088 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005089 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5090 return BAD_VALUE;
5091 }
5092
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005093 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00005094 std::optional<int32_t> foundDeviceId;
5095 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005096 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005097 foundDeviceId = state.deviceId;
5098 }
5099 }
5100 if (!foundDeviceId || !state.down) {
5101 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005102 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005103 return BAD_VALUE;
5104 }
5105 int32_t deviceId = foundDeviceId.value();
5106
5107 // Send cancel events to all the input channels we're stealing from.
5108 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005109 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005110 options.deviceId = deviceId;
5111 options.displayId = displayId;
5112 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005113 std::shared_ptr<InputChannel> channel =
5114 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005115 if (channel != nullptr) {
5116 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5117 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005118 }
5119 // Then clear the current touch state so we stop dispatching to them as well.
5120 state.filterNonMonitors();
5121 }
5122 return OK;
5123}
5124
Prabir Pradhan99987712020-11-10 18:43:05 -08005125void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5126 { // acquire lock
5127 std::scoped_lock _l(mLock);
5128 if (DEBUG_FOCUS) {
5129 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5130 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5131 windowHandle != nullptr ? windowHandle->getName().c_str()
5132 : "token without window");
5133 }
5134
5135 const sp<IBinder> focusedToken =
5136 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
5137 if (focusedToken != windowToken) {
5138 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5139 enabled ? "enable" : "disable");
5140 return;
5141 }
5142
5143 if (enabled == mFocusedWindowRequestedPointerCapture) {
5144 ALOGW("Ignoring request to %s Pointer Capture: "
5145 "window has %s requested pointer capture.",
5146 enabled ? "enable" : "disable", enabled ? "already" : "not");
5147 return;
5148 }
5149
5150 mFocusedWindowRequestedPointerCapture = enabled;
5151 setPointerCaptureLocked(enabled);
5152 } // release lock
5153
5154 // Wake the thread to process command entries.
5155 mLooper->wake();
5156}
5157
Michael Wright3dd60e22019-03-27 22:06:44 +00005158std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5159 const sp<IBinder>& token) {
5160 for (const auto& it : mGestureMonitorsByDisplay) {
5161 const std::vector<Monitor>& monitors = it.second;
5162 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005163 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005164 return it.first;
5165 }
5166 }
5167 }
5168 return std::nullopt;
5169}
5170
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005171std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5172 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5173 if (gesturePid.has_value()) {
5174 return gesturePid;
5175 }
5176 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5177}
5178
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005179sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005180 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005181 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005182 }
5183
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005184 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005185 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005186 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005187 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005188 }
5189 }
Robert Carr4e670e52018-08-15 13:26:12 -07005190
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005191 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005192}
5193
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005194std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5195 sp<Connection> connection = getConnectionLocked(connectionToken);
5196 if (connection == nullptr) {
5197 return "<nullptr>";
5198 }
5199 return connection->getInputChannelName();
5200}
5201
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005202void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005203 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005204 removeByValue(mConnectionsByFd, connection);
5205}
5206
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005207void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5208 const sp<Connection>& connection, uint32_t seq,
5209 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005210 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5211 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005212 commandEntry->connection = connection;
5213 commandEntry->eventTime = currentTime;
5214 commandEntry->seq = seq;
5215 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005216 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005217}
5218
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005219void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5220 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005221 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005222 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005223
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005224 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5225 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005226 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005227 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005228}
5229
Vishnu Nairad321cd2020-08-20 16:40:21 -07005230void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5231 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005232 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5233 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005234 commandEntry->oldToken = oldToken;
5235 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005236 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005237}
5238
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005239void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5240 if (connection == nullptr) {
5241 LOG_ALWAYS_FATAL("Caller must check for nullness");
5242 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005243 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5244 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005245 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005246 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005247 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005248 return;
5249 }
5250 /**
5251 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5252 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5253 * has changed. This could cause newer entries to time out before the already dispatched
5254 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5255 * processes the events linearly. So providing information about the oldest entry seems to be
5256 * most useful.
5257 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005258 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005259 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5260 std::string reason =
5261 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005262 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005263 ns2ms(currentWait),
5264 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005265 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005266 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005267
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005268 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5269
5270 // Stop waking up for events on this connection, it is already unresponsive
5271 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005272}
5273
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005274void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5275 std::string reason =
5276 StringPrintf("%s does not have a focused window", application->getName().c_str());
5277 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005278
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005279 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5280 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5281 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005282 postCommandLocked(std::move(commandEntry));
5283}
5284
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005285void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5286 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5287 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5288 commandEntry->obscuringPackage = obscuringPackage;
5289 postCommandLocked(std::move(commandEntry));
5290}
5291
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005292void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5293 const std::string& reason) {
5294 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5295 updateLastAnrStateLocked(windowLabel, reason);
5296}
5297
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005298void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5299 const std::string& reason) {
5300 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005301 updateLastAnrStateLocked(windowLabel, reason);
5302}
5303
5304void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5305 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005306 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005307 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005308 struct tm tm;
5309 localtime_r(&t, &tm);
5310 char timestr[64];
5311 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005312 mLastAnrState.clear();
5313 mLastAnrState += INDENT "ANR:\n";
5314 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005315 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5316 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005317 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005318}
5319
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005320void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005321 mLock.unlock();
5322
5323 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5324
5325 mLock.lock();
5326}
5327
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005328void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329 sp<Connection> connection = commandEntry->connection;
5330
5331 if (connection->status != Connection::STATUS_ZOMBIE) {
5332 mLock.unlock();
5333
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005334 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005335
5336 mLock.lock();
5337 }
5338}
5339
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005340void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005341 sp<IBinder> oldToken = commandEntry->oldToken;
5342 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005343 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005344 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005345 mLock.lock();
5346}
5347
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005348void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005349 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005350
5351 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5352
5353 mLock.lock();
5354}
5355
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005356void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005357 mLock.unlock();
5358
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005359 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005360
5361 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005362}
5363
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005364void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005365 mLock.unlock();
5366
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005367 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5368
5369 mLock.lock();
5370}
5371
5372void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5373 mLock.unlock();
5374
5375 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5376
5377 mLock.lock();
5378}
5379
5380void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5381 mLock.unlock();
5382
5383 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005384
5385 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005386}
5387
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005388void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5389 mLock.unlock();
5390
5391 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5392
5393 mLock.lock();
5394}
5395
Michael Wrightd02c5b62014-02-10 15:10:22 -08005396void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5397 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005398 KeyEntry& entry = *(commandEntry->keyEntry);
5399 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400
5401 mLock.unlock();
5402
Michael Wright2b3c3302018-03-02 17:19:13 +00005403 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005404 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005405 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005406 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5407 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005408 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005409 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005410
5411 mLock.lock();
5412
5413 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005414 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005415 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005416 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005417 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005418 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5419 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005420 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005421}
5422
chaviwfd6d3512019-03-25 13:23:49 -07005423void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5424 mLock.unlock();
5425 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5426 mLock.lock();
5427}
5428
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005429/**
5430 * Connection is responsive if it has no events in the waitQueue that are older than the
5431 * current time.
5432 */
5433static bool isConnectionResponsive(const Connection& connection) {
5434 const nsecs_t currentTime = now();
5435 for (const DispatchEntry* entry : connection.waitQueue) {
5436 if (entry->timeoutTime < currentTime) {
5437 return false;
5438 }
5439 }
5440 return true;
5441}
5442
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005443void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005444 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005445 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005446 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005447 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005448
5449 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005450 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005451 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005452 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005453 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005454 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005455 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005456 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005457 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5458 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005459 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005460 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005461
5462 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005463 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005464 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005465 restartEvent =
5466 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005467 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005468 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005469 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5470 handled);
5471 } else {
5472 restartEvent = false;
5473 }
5474
5475 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005476 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005477 // contents of the wait queue to have been drained, so we need to double-check
5478 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005479 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5480 if (dispatchEntryIt != connection->waitQueue.end()) {
5481 dispatchEntry = *dispatchEntryIt;
5482 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005483 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5484 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005485 if (!connection->responsive) {
5486 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005487 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005488 // The connection was unresponsive, and now it's responsive.
5489 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005490 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005491 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005492 traceWaitQueueLength(connection);
5493 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005494 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005495 traceOutboundQueueLength(connection);
5496 } else {
5497 releaseDispatchEntry(dispatchEntry);
5498 }
5499 }
5500
5501 // Start the next dispatch cycle for this connection.
5502 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005503}
5504
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005505void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5506 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5507 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5508 monitorUnresponsiveCommand->pid = pid;
5509 monitorUnresponsiveCommand->reason = std::move(reason);
5510 postCommandLocked(std::move(monitorUnresponsiveCommand));
5511}
5512
5513void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5514 std::string reason) {
5515 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5516 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5517 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5518 windowUnresponsiveCommand->reason = std::move(reason);
5519 postCommandLocked(std::move(windowUnresponsiveCommand));
5520}
5521
5522void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5523 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5524 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5525 monitorResponsiveCommand->pid = pid;
5526 postCommandLocked(std::move(monitorResponsiveCommand));
5527}
5528
5529void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5530 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5531 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5532 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5533 postCommandLocked(std::move(windowResponsiveCommand));
5534}
5535
5536/**
5537 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5538 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5539 * command entry to the command queue.
5540 */
5541void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5542 std::string reason) {
5543 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5544 if (connection.monitor) {
5545 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5546 reason.c_str());
5547 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5548 if (!pid.has_value()) {
5549 ALOGE("Could not find unresponsive monitor for connection %s",
5550 connection.inputChannel->getName().c_str());
5551 return;
5552 }
5553 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5554 return;
5555 }
5556 // If not a monitor, must be a window
5557 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5558 reason.c_str());
5559 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5560}
5561
5562/**
5563 * Tell the policy that a connection has become responsive so that it can stop ANR.
5564 */
5565void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5566 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5567 if (connection.monitor) {
5568 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5569 if (!pid.has_value()) {
5570 ALOGE("Could not find responsive monitor for connection %s",
5571 connection.inputChannel->getName().c_str());
5572 return;
5573 }
5574 sendMonitorResponsiveCommandLocked(pid.value());
5575 return;
5576 }
5577 // If not a monitor, must be a window
5578 sendWindowResponsiveCommandLocked(connectionToken);
5579}
5580
Michael Wrightd02c5b62014-02-10 15:10:22 -08005581bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005582 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005583 KeyEntry& keyEntry, bool handled) {
5584 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005585 if (!handled) {
5586 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005587 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005588 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005589 return false;
5590 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005591
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005592 // Get the fallback key state.
5593 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005594 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005595 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005596 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005597 connection->inputState.removeFallbackKey(originalKeyCode);
5598 }
5599
5600 if (handled || !dispatchEntry->hasForegroundTarget()) {
5601 // If the application handles the original key for which we previously
5602 // generated a fallback or if the window is not a foreground window,
5603 // then cancel the associated fallback key, if any.
5604 if (fallbackKeyCode != -1) {
5605 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005606#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005607 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005608 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005609 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005610#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005611 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005612 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005613
5614 mLock.unlock();
5615
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005616 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005617 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005618
5619 mLock.lock();
5620
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005621 // Cancel the fallback key.
5622 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005623 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005624 "application handled the original non-fallback key "
5625 "or is no longer a foreground target, "
5626 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005627 options.keyCode = fallbackKeyCode;
5628 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005629 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005630 connection->inputState.removeFallbackKey(originalKeyCode);
5631 }
5632 } else {
5633 // If the application did not handle a non-fallback key, first check
5634 // that we are in a good state to perform unhandled key event processing
5635 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005636 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005637 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005638#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005639 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005640 "since this is not an initial down. "
5641 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005642 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005643#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005644 return false;
5645 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005646
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005647 // Dispatch the unhandled key to the policy.
5648#if DEBUG_OUTBOUND_EVENT_DETAILS
5649 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005650 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005651 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005652#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005653 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005654
5655 mLock.unlock();
5656
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005657 bool fallback =
5658 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005659 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005660
5661 mLock.lock();
5662
5663 if (connection->status != Connection::STATUS_NORMAL) {
5664 connection->inputState.removeFallbackKey(originalKeyCode);
5665 return false;
5666 }
5667
5668 // Latch the fallback keycode for this key on an initial down.
5669 // The fallback keycode cannot change at any other point in the lifecycle.
5670 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005671 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005672 fallbackKeyCode = event.getKeyCode();
5673 } else {
5674 fallbackKeyCode = AKEYCODE_UNKNOWN;
5675 }
5676 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5677 }
5678
5679 ALOG_ASSERT(fallbackKeyCode != -1);
5680
5681 // Cancel the fallback key if the policy decides not to send it anymore.
5682 // We will continue to dispatch the key to the policy but we will no
5683 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005684 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5685 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005686#if DEBUG_OUTBOUND_EVENT_DETAILS
5687 if (fallback) {
5688 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005689 "as a fallback for %d, but on the DOWN it had requested "
5690 "to send %d instead. Fallback canceled.",
5691 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005692 } else {
5693 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005694 "but on the DOWN it had requested to send %d. "
5695 "Fallback canceled.",
5696 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005697 }
5698#endif
5699
5700 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5701 "canceling fallback, policy no longer desires it");
5702 options.keyCode = fallbackKeyCode;
5703 synthesizeCancelationEventsForConnectionLocked(connection, options);
5704
5705 fallback = false;
5706 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005707 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005708 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005709 }
5710 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005711
5712#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005713 {
5714 std::string msg;
5715 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5716 connection->inputState.getFallbackKeys();
5717 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005718 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005719 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005720 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005721 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005722 }
5723#endif
5724
5725 if (fallback) {
5726 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005727 keyEntry.eventTime = event.getEventTime();
5728 keyEntry.deviceId = event.getDeviceId();
5729 keyEntry.source = event.getSource();
5730 keyEntry.displayId = event.getDisplayId();
5731 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5732 keyEntry.keyCode = fallbackKeyCode;
5733 keyEntry.scanCode = event.getScanCode();
5734 keyEntry.metaState = event.getMetaState();
5735 keyEntry.repeatCount = event.getRepeatCount();
5736 keyEntry.downTime = event.getDownTime();
5737 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005738
5739#if DEBUG_OUTBOUND_EVENT_DETAILS
5740 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005741 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005742 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005743#endif
5744 return true; // restart the event
5745 } else {
5746#if DEBUG_OUTBOUND_EVENT_DETAILS
5747 ALOGD("Unhandled key event: No fallback key.");
5748#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005749
5750 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005751 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005752 }
5753 }
5754 return false;
5755}
5756
5757bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005758 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005759 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005760 return false;
5761}
5762
5763void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5764 mLock.unlock();
5765
5766 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5767
5768 mLock.lock();
5769}
5770
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005771void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5772 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005773 // TODO Write some statistics about how long we spend waiting.
5774}
5775
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005776/**
5777 * Report the touch event latency to the statsd server.
5778 * Input events are reported for statistics if:
5779 * - This is a touchscreen event
5780 * - InputFilter is not enabled
5781 * - Event is not injected or synthesized
5782 *
5783 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5784 * from getting aggregated with the "old" data.
5785 */
5786void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5787 REQUIRES(mLock) {
5788 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5789 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5790 if (!reportForStatistics) {
5791 return;
5792 }
5793
5794 if (mTouchStatistics.shouldReport()) {
5795 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5796 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5797 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5798 mTouchStatistics.reset();
5799 }
5800 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5801 mTouchStatistics.addValue(latencyMicros);
5802}
5803
Michael Wrightd02c5b62014-02-10 15:10:22 -08005804void InputDispatcher::traceInboundQueueLengthLocked() {
5805 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005806 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005807 }
5808}
5809
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005810void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005811 if (ATRACE_ENABLED()) {
5812 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005813 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005814 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005815 }
5816}
5817
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005818void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005819 if (ATRACE_ENABLED()) {
5820 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005821 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005822 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005823 }
5824}
5825
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005826void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005827 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005828
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005829 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005830 dumpDispatchStateLocked(dump);
5831
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005832 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005833 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005834 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005835 }
5836}
5837
5838void InputDispatcher::monitor() {
5839 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005840 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005841 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005842 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005843}
5844
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005845/**
5846 * Wake up the dispatcher and wait until it processes all events and commands.
5847 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5848 * this method can be safely called from any thread, as long as you've ensured that
5849 * the work you are interested in completing has already been queued.
5850 */
5851bool InputDispatcher::waitForIdle() {
5852 /**
5853 * Timeout should represent the longest possible time that a device might spend processing
5854 * events and commands.
5855 */
5856 constexpr std::chrono::duration TIMEOUT = 100ms;
5857 std::unique_lock lock(mLock);
5858 mLooper->wake();
5859 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5860 return result == std::cv_status::no_timeout;
5861}
5862
Vishnu Naire798b472020-07-23 13:52:21 -07005863/**
5864 * Sets focus to the window identified by the token. This must be called
5865 * after updating any input window handles.
5866 *
5867 * Params:
5868 * request.token - input channel token used to identify the window that should gain focus.
5869 * request.focusedToken - the token that the caller expects currently to be focused. If the
5870 * specified token does not match the currently focused window, this request will be dropped.
5871 * If the specified focused token matches the currently focused window, the call will succeed.
5872 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5873 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5874 * when requesting the focus change. This determines which request gets
5875 * precedence if there is a focus change request from another source such as pointer down.
5876 */
Vishnu Nair958da932020-08-21 17:12:37 -07005877void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5878 { // acquire lock
5879 std::scoped_lock _l(mLock);
5880
5881 const int32_t displayId = request.displayId;
5882 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5883 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5884 ALOGD_IF(DEBUG_FOCUS,
5885 "setFocusedWindow on display %" PRId32
5886 " ignored, reason: focusedToken is not focused",
5887 displayId);
5888 return;
5889 }
5890
5891 mPendingFocusRequests.erase(displayId);
5892 FocusResult result = handleFocusRequestLocked(request);
5893 if (result == FocusResult::NOT_VISIBLE) {
5894 // The requested window is not currently visible. Wait for the window to become visible
5895 // and then provide it focus. This is to handle situations where a user action triggers
5896 // a new window to appear. We want to be able to queue any key events after the user
5897 // action and deliver it to the newly focused window. In order for this to happen, we
5898 // take focus from the currently focused window so key events can be queued.
5899 ALOGD_IF(DEBUG_FOCUS,
5900 "setFocusedWindow on display %" PRId32
5901 " pending, reason: window is not visible",
5902 displayId);
5903 mPendingFocusRequests[displayId] = request;
5904 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5905 "setFocusedWindow_AwaitingWindowVisibility");
5906 } else if (result != FocusResult::OK) {
5907 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5908 typeToString(result));
5909 }
5910 } // release lock
5911 // Wake up poll loop since it may need to make new input dispatching choices.
5912 mLooper->wake();
5913}
5914
5915InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5916 const FocusRequest& request) {
5917 const int32_t displayId = request.displayId;
5918 const sp<IBinder> newFocusedToken = request.token;
5919 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5920
5921 if (oldFocusedToken == request.token) {
5922 ALOGD_IF(DEBUG_FOCUS,
5923 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5924 displayId);
5925 return FocusResult::OK;
5926 }
5927
5928 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5929 if (result != FocusResult::OK) {
5930 return result;
5931 }
5932
5933 std::string_view reason =
5934 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5935 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5936 return FocusResult::OK;
5937}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005938
Vishnu Nairad321cd2020-08-20 16:40:21 -07005939void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5940 const sp<IBinder>& newFocusedToken, int32_t displayId,
5941 std::string_view reason) {
5942 if (oldFocusedToken) {
5943 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005944 if (focusedInputChannel) {
5945 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5946 "focus left window");
5947 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005948 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005949 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005950 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005951 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005952 if (newFocusedToken) {
5953 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5954 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005955 }
5956
Prabir Pradhan99987712020-11-10 18:43:05 -08005957 // If a window has pointer capture, then it must have focus. We need to ensure that this
5958 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5959 // If the window loses focus before it loses pointer capture, then the window can be in a state
5960 // where it has pointer capture but not focus, violating the contract. Therefore we must
5961 // dispatch the pointer capture event before the focus event. Since focus events are added to
5962 // the front of the queue (above), we add the pointer capture event to the front of the queue
5963 // after the focus events are added. This ensures the pointer capture event ends up at the
5964 // front.
5965 disablePointerCaptureForcedLocked();
5966
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005967 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005968 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005969 }
5970}
Vishnu Nair958da932020-08-21 17:12:37 -07005971
Prabir Pradhan99987712020-11-10 18:43:05 -08005972void InputDispatcher::disablePointerCaptureForcedLocked() {
5973 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5974 return;
5975 }
5976
5977 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5978
5979 if (mFocusedWindowRequestedPointerCapture) {
5980 mFocusedWindowRequestedPointerCapture = false;
5981 setPointerCaptureLocked(false);
5982 }
5983
5984 if (!mWindowTokenWithPointerCapture) {
5985 // No need to send capture changes because no window has capture.
5986 return;
5987 }
5988
5989 if (mPendingEvent != nullptr) {
5990 // Move the pending event to the front of the queue. This will give the chance
5991 // for the pending event to be dropped if it is a captured event.
5992 mInboundQueue.push_front(mPendingEvent);
5993 mPendingEvent = nullptr;
5994 }
5995
5996 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5997 false /* hasCapture */);
5998 mInboundQueue.push_front(std::move(entry));
5999}
6000
Vishnu Nair958da932020-08-21 17:12:37 -07006001/**
6002 * Checks if the window token can be focused on a display. The token can be focused if there is
6003 * at least one window handle that is visible with the same token and all window handles with the
6004 * same token are focusable.
6005 *
6006 * In the case of mirroring, two windows may share the same window token and their visibility
6007 * might be different. Example, the mirrored window can cover the window its mirroring. However,
6008 * we expect the focusability of the windows to match since its hard to reason why one window can
6009 * receive focus events and the other cannot when both are backed by the same input channel.
6010 */
6011InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
6012 int32_t displayId) const {
6013 bool allWindowsAreFocusable = true;
6014 bool visibleWindowFound = false;
6015 bool windowFound = false;
6016 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
6017 if (window->getToken() != token) {
6018 continue;
6019 }
6020 windowFound = true;
6021 if (window->getInfo()->visible) {
6022 // Check if at least a single window is visible.
6023 visibleWindowFound = true;
6024 }
6025 if (!window->getInfo()->focusable) {
6026 // Check if all windows with the window token are focusable.
6027 allWindowsAreFocusable = false;
6028 break;
6029 }
6030 }
6031
6032 if (!windowFound) {
6033 return FocusResult::NO_WINDOW;
6034 }
6035 if (!allWindowsAreFocusable) {
6036 return FocusResult::NOT_FOCUSABLE;
6037 }
6038 if (!visibleWindowFound) {
6039 return FocusResult::NOT_VISIBLE;
6040 }
6041
6042 return FocusResult::OK;
6043}
Prabir Pradhan99987712020-11-10 18:43:05 -08006044
6045void InputDispatcher::setPointerCaptureLocked(bool enabled) {
6046 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
6047 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
6048 commandEntry->enabled = enabled;
6049 postCommandLocked(std::move(commandEntry));
6050}
6051
6052void InputDispatcher::doSetPointerCaptureLockedInterruptible(
6053 android::inputdispatcher::CommandEntry* commandEntry) {
6054 mLock.unlock();
6055
6056 mPolicy->setPointerCapture(commandEntry->enabled);
6057
6058 mLock.lock();
6059}
6060
Garfield Tane84e6f92019-08-29 17:28:41 -07006061} // namespace android::inputdispatcher