blob: dcac7862712911077f5f611fe7ded7a016acebaa [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
Michael Wrightd02c5b62014-02-10 15:10:22 -0800448// --- InputDispatcher ---
449
Garfield Tan00f511d2019-06-12 16:55:40 -0700450InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
451 : mPolicy(policy),
452 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700453 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800454 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700455 mAppSwitchSawKeyDown(false),
456 mAppSwitchDueTime(LONG_LONG_MAX),
457 mNextUnblockedEvent(nullptr),
458 mDispatchEnabled(false),
459 mDispatchFrozen(false),
460 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800461 // mInTouchMode will be initialized by the WindowManager to the default device config.
462 // To avoid leaking stack in case that call never comes, and for tests,
463 // initialize it here anyways.
464 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100465 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000466 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800467 mFocusedWindowRequestedPointerCapture(false),
468 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000469 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800470 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800471 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800472
Yi Kong9b14ac62018-07-17 13:48:38 -0700473 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800474
475 policy->getDispatcherConfiguration(&mConfig);
476}
477
478InputDispatcher::~InputDispatcher() {
479 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800480 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800481
482 resetKeyRepeatLocked();
483 releasePendingEventLocked();
484 drainInboundQueueLocked();
485 }
486
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700487 while (!mConnectionsByFd.empty()) {
488 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700489 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800490 }
491}
492
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700493status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700494 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700495 return ALREADY_EXISTS;
496 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700497 mThread = std::make_unique<InputThread>(
498 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
499 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700500}
501
502status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700503 if (mThread && mThread->isCallingThread()) {
504 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700505 return INVALID_OPERATION;
506 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700507 mThread.reset();
508 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700509}
510
Michael Wrightd02c5b62014-02-10 15:10:22 -0800511void InputDispatcher::dispatchOnce() {
512 nsecs_t nextWakeupTime = LONG_LONG_MAX;
513 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800514 std::scoped_lock _l(mLock);
515 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800516
517 // Run a dispatch loop if there are no pending commands.
518 // The dispatch loop might enqueue commands to run afterwards.
519 if (!haveCommandsLocked()) {
520 dispatchOnceInnerLocked(&nextWakeupTime);
521 }
522
523 // Run all pending commands if there are any.
524 // If any commands were run then force the next poll to wake up immediately.
525 if (runCommandsLockedInterruptible()) {
526 nextWakeupTime = LONG_LONG_MIN;
527 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800528
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700529 // If we are still waiting for ack on some events,
530 // we might have to wake up earlier to check if an app is anr'ing.
531 const nsecs_t nextAnrCheck = processAnrsLocked();
532 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
533
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800534 // We are about to enter an infinitely long sleep, because we have no commands or
535 // pending or queued events
536 if (nextWakeupTime == LONG_LONG_MAX) {
537 mDispatcherEnteredIdle.notify_all();
538 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800539 } // release lock
540
541 // Wait for callback or timeout or wake. (make sure we round up, not down)
542 nsecs_t currentTime = now();
543 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
544 mLooper->pollOnce(timeoutMillis);
545}
546
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700547/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500548 * Raise ANR if there is no focused window.
549 * Before the ANR is raised, do a final state check:
550 * 1. The currently focused application must be the same one we are waiting for.
551 * 2. Ensure we still don't have a focused window.
552 */
553void InputDispatcher::processNoFocusedWindowAnrLocked() {
554 // Check if the application that we are waiting for is still focused.
555 std::shared_ptr<InputApplicationHandle> focusedApplication =
556 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
557 if (focusedApplication == nullptr ||
558 focusedApplication->getApplicationToken() !=
559 mAwaitedFocusedApplication->getApplicationToken()) {
560 // Unexpected because we should have reset the ANR timer when focused application changed
561 ALOGE("Waited for a focused window, but focused application has already changed to %s",
562 focusedApplication->getName().c_str());
563 return; // The focused application has changed.
564 }
565
566 const sp<InputWindowHandle>& focusedWindowHandle =
567 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
568 if (focusedWindowHandle != nullptr) {
569 return; // We now have a focused window. No need for ANR.
570 }
571 onAnrLocked(mAwaitedFocusedApplication);
572}
573
574/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700575 * Check if any of the connections' wait queues have events that are too old.
576 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
577 * Return the time at which we should wake up next.
578 */
579nsecs_t InputDispatcher::processAnrsLocked() {
580 const nsecs_t currentTime = now();
581 nsecs_t nextAnrCheck = LONG_LONG_MAX;
582 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
583 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
584 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500585 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700586 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500587 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700588 return LONG_LONG_MIN;
589 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500590 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700591 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
592 }
593 }
594
595 // Check if any connection ANRs are due
596 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
597 if (currentTime < nextAnrCheck) { // most likely scenario
598 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
599 }
600
601 // If we reached here, we have an unresponsive connection.
602 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
603 if (connection == nullptr) {
604 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
605 return nextAnrCheck;
606 }
607 connection->responsive = false;
608 // Stop waking up for this unresponsive connection
609 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -0500610 onAnrLocked(*connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700611 return LONG_LONG_MIN;
612}
613
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500614std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700615 sp<InputWindowHandle> window = getWindowHandleLocked(token);
616 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500617 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700618 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500619 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700620}
621
Michael Wrightd02c5b62014-02-10 15:10:22 -0800622void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
623 nsecs_t currentTime = now();
624
Jeff Browndc5992e2014-04-11 01:27:26 -0700625 // Reset the key repeat timer whenever normal dispatch is suspended while the
626 // device is in a non-interactive state. This is to ensure that we abort a key
627 // repeat if the device is just coming out of sleep.
628 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800629 resetKeyRepeatLocked();
630 }
631
632 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
633 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100634 if (DEBUG_FOCUS) {
635 ALOGD("Dispatch frozen. Waiting some more.");
636 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800637 return;
638 }
639
640 // Optimize latency of app switches.
641 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
642 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
643 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
644 if (mAppSwitchDueTime < *nextWakeupTime) {
645 *nextWakeupTime = mAppSwitchDueTime;
646 }
647
648 // Ready to start a new event.
649 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700650 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700651 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800652 if (isAppSwitchDue) {
653 // The inbound queue is empty so the app switch key we were waiting
654 // for will never arrive. Stop waiting for it.
655 resetPendingAppSwitchLocked(false);
656 isAppSwitchDue = false;
657 }
658
659 // Synthesize a key repeat if appropriate.
660 if (mKeyRepeatState.lastKeyEntry) {
661 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
662 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
663 } else {
664 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
665 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
666 }
667 }
668 }
669
670 // Nothing to do if there is no pending event.
671 if (!mPendingEvent) {
672 return;
673 }
674 } else {
675 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700676 mPendingEvent = mInboundQueue.front();
677 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800678 traceInboundQueueLengthLocked();
679 }
680
681 // Poke user activity for this event.
682 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700683 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800684 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800685 }
686
687 // Now we have an event to dispatch.
688 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700689 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800690 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700691 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800692 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700693 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800694 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700695 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800696 }
697
698 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700699 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700 }
701
702 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700703 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700704 const ConfigurationChangedEntry& typedEntry =
705 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700706 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700707 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700708 break;
709 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800710
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700711 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700712 const DeviceResetEntry& typedEntry =
713 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700714 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700715 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700716 break;
717 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800718
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100719 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700720 std::shared_ptr<FocusEntry> typedEntry =
721 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100722 dispatchFocusLocked(currentTime, typedEntry);
723 done = true;
724 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
725 break;
726 }
727
Prabir Pradhan99987712020-11-10 18:43:05 -0800728 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
729 const auto typedEntry =
730 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
731 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
732 done = true;
733 break;
734 }
735
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700736 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700737 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700739 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700740 resetPendingAppSwitchLocked(true);
741 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700742 } else if (dropReason == DropReason::NOT_DROPPED) {
743 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700744 }
745 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700746 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700747 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700748 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700749 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
750 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700751 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700752 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700753 break;
754 }
755
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700756 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700757 std::shared_ptr<MotionEntry> motionEntry =
758 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700759 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
760 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800761 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700762 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700763 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700764 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700765 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
766 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700767 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700768 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700769 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800770 }
Chris Yef59a2f42020-10-16 12:55:26 -0700771
772 case EventEntry::Type::SENSOR: {
773 std::shared_ptr<SensorEntry> sensorEntry =
774 std::static_pointer_cast<SensorEntry>(mPendingEvent);
775 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
776 dropReason = DropReason::APP_SWITCH;
777 }
778 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
779 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
780 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
781 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
782 dropReason = DropReason::STALE;
783 }
784 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
785 done = true;
786 break;
787 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800788 }
789
790 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700791 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700792 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800793 }
Michael Wright3a981722015-06-10 15:26:13 +0100794 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800795
796 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700797 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800798 }
799}
800
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700801/**
802 * Return true if the events preceding this incoming motion event should be dropped
803 * Return false otherwise (the default behaviour)
804 */
805bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700806 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700807 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700808
809 // Optimize case where the current application is unresponsive and the user
810 // decides to touch a window in a different application.
811 // If the application takes too long to catch up then we drop all events preceding
812 // the touch into the other window.
813 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700814 int32_t displayId = motionEntry.displayId;
815 int32_t x = static_cast<int32_t>(
816 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
817 int32_t y = static_cast<int32_t>(
818 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
819 sp<InputWindowHandle> touchedWindowHandle =
820 findTouchedWindowAtLocked(displayId, x, y, nullptr);
821 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700822 touchedWindowHandle->getApplicationToken() !=
823 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700824 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700825 ALOGI("Pruning input queue because user touched a different application while waiting "
826 "for %s",
827 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700828 return true;
829 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700830
831 // Alternatively, maybe there's a gesture monitor that could handle this event
832 std::vector<TouchedMonitor> gestureMonitors =
833 findTouchedGestureMonitorsLocked(displayId, {});
834 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
835 sp<Connection> connection =
836 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000837 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700838 // This monitor could take more input. Drop all events preceding this
839 // event, so that gesture monitor could get a chance to receive the stream
840 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
841 "responsive gesture monitor that may handle the event",
842 mAwaitedFocusedApplication->getName().c_str());
843 return true;
844 }
845 }
846 }
847
848 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
849 // yet been processed by some connections, the dispatcher will wait for these motion
850 // events to be processed before dispatching the key event. This is because these motion events
851 // may cause a new window to be launched, which the user might expect to receive focus.
852 // To prevent waiting forever for such events, just send the key to the currently focused window
853 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
854 ALOGD("Received a new pointer down event, stop waiting for events to process and "
855 "just send the pending key event to the focused window.");
856 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700857 }
858 return false;
859}
860
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700861bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700862 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700863 mInboundQueue.push_back(std::move(newEntry));
864 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800865 traceInboundQueueLengthLocked();
866
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700867 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700868 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700869 // Optimize app switch latency.
870 // If the application takes too long to catch up then we drop all events preceding
871 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700872 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700873 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700874 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700875 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700876 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700877 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800878#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700879 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800880#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700881 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700882 mAppSwitchSawKeyDown = false;
883 needWake = true;
884 }
885 }
886 }
887 break;
888 }
889
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700890 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700891 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
892 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700893 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800894 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700895 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800896 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100897 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700898 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
899 break;
900 }
901 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800902 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700903 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -0800904 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700905 // nothing to do
906 break;
907 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800908 }
909
910 return needWake;
911}
912
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700913void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700914 // Do not store sensor event in recent queue to avoid flooding the queue.
915 if (entry->type != EventEntry::Type::SENSOR) {
916 mRecentQueue.push_back(entry);
917 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700918 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700919 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800920 }
921}
922
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700923sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700924 int32_t y, TouchState* touchState,
925 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700926 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700927 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
928 LOG_ALWAYS_FATAL(
929 "Must provide a valid touch state if adding portal windows or outside targets");
930 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800931 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700932 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800933 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800934 const InputWindowInfo* windowInfo = windowHandle->getInfo();
935 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100936 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800937
938 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100939 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
940 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
941 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800943 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700944 if (portalToDisplayId != ADISPLAY_ID_NONE &&
945 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800946 if (addPortalWindows) {
947 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700948 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800949 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700950 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700951 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 // Found window.
954 return windowHandle;
955 }
956 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800957
Michael Wright44753b12020-07-08 13:48:11 +0100958 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700959 touchState->addOrUpdateWindow(windowHandle,
960 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
961 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800962 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800963 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 }
965 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700966 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800967}
968
Garfield Tane84e6f92019-08-29 17:28:41 -0700969std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700970 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000971 std::vector<TouchedMonitor> touchedMonitors;
972
973 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
974 addGestureMonitors(monitors, touchedMonitors);
975 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
976 const InputWindowInfo* windowInfo = portalWindow->getInfo();
977 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700978 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
979 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +0000980 }
981 return touchedMonitors;
982}
983
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700984void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 const char* reason;
986 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700987 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -0800988#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700989 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800990#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700991 reason = "inbound event was dropped because the policy consumed it";
992 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700993 case DropReason::DISABLED:
994 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700995 ALOGI("Dropped event because input dispatch is disabled.");
996 }
997 reason = "inbound event was dropped because input dispatch is disabled";
998 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700999 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001000 ALOGI("Dropped event because of pending overdue app switch.");
1001 reason = "inbound event was dropped because of pending overdue app switch";
1002 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001003 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001004 ALOGI("Dropped event because the current application is not responding and the user "
1005 "has started interacting with a different application.");
1006 reason = "inbound event was dropped because the current application is not responding "
1007 "and the user has started interacting with a different application";
1008 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001009 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001010 ALOGI("Dropped event because it is stale.");
1011 reason = "inbound event was dropped because it is stale";
1012 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001013 case DropReason::NO_POINTER_CAPTURE:
1014 ALOGI("Dropped event because there is no window with Pointer Capture.");
1015 reason = "inbound event was dropped because there is no window with Pointer Capture";
1016 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001017 case DropReason::NOT_DROPPED: {
1018 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001019 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001020 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001021 }
1022
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001023 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001024 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001025 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1026 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001027 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001028 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001029 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001030 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1031 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001032 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1033 synthesizeCancelationEventsForAllConnectionsLocked(options);
1034 } else {
1035 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1036 synthesizeCancelationEventsForAllConnectionsLocked(options);
1037 }
1038 break;
1039 }
Chris Yef59a2f42020-10-16 12:55:26 -07001040 case EventEntry::Type::SENSOR: {
1041 break;
1042 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001043 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1044 break;
1045 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001046 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001047 case EventEntry::Type::CONFIGURATION_CHANGED:
1048 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001049 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001050 break;
1051 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001052 }
1053}
1054
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001055static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001056 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1057 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001058}
1059
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001060bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1061 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1062 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1063 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001064}
1065
1066bool InputDispatcher::isAppSwitchPendingLocked() {
1067 return mAppSwitchDueTime != LONG_LONG_MAX;
1068}
1069
1070void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1071 mAppSwitchDueTime = LONG_LONG_MAX;
1072
1073#if DEBUG_APP_SWITCH
1074 if (handled) {
1075 ALOGD("App switch has arrived.");
1076 } else {
1077 ALOGD("App switch was abandoned.");
1078 }
1079#endif
1080}
1081
Michael Wrightd02c5b62014-02-10 15:10:22 -08001082bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001083 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001084}
1085
1086bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001087 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001088 return false;
1089 }
1090
1091 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001092 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001093 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001094 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001095 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001096
1097 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001098 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001099 return true;
1100}
1101
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001102void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1103 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104}
1105
1106void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001107 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001108 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001109 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110 releaseInboundEventLocked(entry);
1111 }
1112 traceInboundQueueLengthLocked();
1113}
1114
1115void InputDispatcher::releasePendingEventLocked() {
1116 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001117 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001118 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001119 }
1120}
1121
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001122void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001123 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001124 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001125#if DEBUG_DISPATCH_CYCLE
1126 ALOGD("Injected inbound event was dropped.");
1127#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001128 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001129 }
1130 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001131 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132 }
1133 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001134}
1135
1136void InputDispatcher::resetKeyRepeatLocked() {
1137 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001138 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001139 }
1140}
1141
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001142std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1143 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001144
Michael Wright2e732952014-09-24 13:26:59 -07001145 uint32_t policyFlags = entry->policyFlags &
1146 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001147
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001148 std::shared_ptr<KeyEntry> newEntry =
1149 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1150 entry->source, entry->displayId, policyFlags, entry->action,
1151 entry->flags, entry->keyCode, entry->scanCode,
1152 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001153
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001154 newEntry->syntheticRepeat = true;
1155 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001156 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001157 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001158}
1159
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001160bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001161 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001162#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001163 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001164#endif
1165
1166 // Reset key repeating in case a keyboard device was added or removed or something.
1167 resetKeyRepeatLocked();
1168
1169 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001170 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1171 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001172 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001173 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001174 return true;
1175}
1176
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001177bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1178 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001179#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001180 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1181 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001182#endif
1183
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001184 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001185 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186 synthesizeCancelationEventsForAllConnectionsLocked(options);
1187 return true;
1188}
1189
Vishnu Nairad321cd2020-08-20 16:40:21 -07001190void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001191 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001192 if (mPendingEvent != nullptr) {
1193 // Move the pending event to the front of the queue. This will give the chance
1194 // for the pending event to get dispatched to the newly focused window
1195 mInboundQueue.push_front(mPendingEvent);
1196 mPendingEvent = nullptr;
1197 }
1198
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001199 std::unique_ptr<FocusEntry> focusEntry =
1200 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1201 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001202
1203 // This event should go to the front of the queue, but behind all other focus events
1204 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001205 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001206 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001207 [](const std::shared_ptr<EventEntry>& event) {
1208 return event->type == EventEntry::Type::FOCUS;
1209 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001210
1211 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001212 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001213}
1214
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001215void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001216 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001217 if (channel == nullptr) {
1218 return; // Window has gone away
1219 }
1220 InputTarget target;
1221 target.inputChannel = channel;
1222 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1223 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001224 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1225 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001226 std::string reason = std::string("reason=").append(entry->reason);
1227 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001228 dispatchEventLocked(currentTime, entry, {target});
1229}
1230
Prabir Pradhan99987712020-11-10 18:43:05 -08001231void InputDispatcher::dispatchPointerCaptureChangedLocked(
1232 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1233 DropReason& dropReason) {
1234 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1235 if (entry->pointerCaptureEnabled == haveWindowWithPointerCapture) {
1236 LOG_ALWAYS_FATAL_IF(mFocusedWindowRequestedPointerCapture,
1237 "The Pointer Capture state has already been dispatched to the window.");
1238 // Pointer capture was already forcefully disabled because of focus change.
1239 dropReason = DropReason::NOT_DROPPED;
1240 return;
1241 }
1242
1243 // Set drop reason for early returns
1244 dropReason = DropReason::NO_POINTER_CAPTURE;
1245
1246 sp<IBinder> token;
1247 if (entry->pointerCaptureEnabled) {
1248 // Enable Pointer Capture
1249 if (!mFocusedWindowRequestedPointerCapture) {
1250 // This can happen if a window requests capture and immediately releases capture.
1251 ALOGW("No window requested Pointer Capture.");
1252 return;
1253 }
1254 token = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
1255 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1256 mWindowTokenWithPointerCapture = token;
1257 } else {
1258 // Disable Pointer Capture
1259 token = mWindowTokenWithPointerCapture;
1260 mWindowTokenWithPointerCapture = nullptr;
1261 mFocusedWindowRequestedPointerCapture = false;
1262 }
1263
1264 auto channel = getInputChannelLocked(token);
1265 if (channel == nullptr) {
1266 // Window has gone away, clean up Pointer Capture state.
1267 mWindowTokenWithPointerCapture = nullptr;
1268 mFocusedWindowRequestedPointerCapture = false;
1269 return;
1270 }
1271 InputTarget target;
1272 target.inputChannel = channel;
1273 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1274 entry->dispatchInProgress = true;
1275 dispatchEventLocked(currentTime, entry, {target});
1276
1277 dropReason = DropReason::NOT_DROPPED;
1278}
1279
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001280bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001281 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001282 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001283 if (!entry->dispatchInProgress) {
1284 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1285 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1286 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1287 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001288 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001289 // We have seen two identical key downs in a row which indicates that the device
1290 // driver is automatically generating key repeats itself. We take note of the
1291 // repeat here, but we disable our own next key repeat timer since it is clear that
1292 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001293 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1294 // Make sure we don't get key down from a different device. If a different
1295 // device Id has same key pressed down, the new device Id will replace the
1296 // current one to hold the key repeat with repeat count reset.
1297 // In the future when got a KEY_UP on the device id, drop it and do not
1298 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001299 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1300 resetKeyRepeatLocked();
1301 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1302 } else {
1303 // Not a repeat. Save key down state in case we do see a repeat later.
1304 resetKeyRepeatLocked();
1305 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1306 }
1307 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001308 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1309 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001310 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001311#if DEBUG_INBOUND_EVENT_DETAILS
1312 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1313#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001314 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001315 resetKeyRepeatLocked();
1316 }
1317
1318 if (entry->repeatCount == 1) {
1319 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1320 } else {
1321 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1322 }
1323
1324 entry->dispatchInProgress = true;
1325
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001326 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001327 }
1328
1329 // Handle case where the policy asked us to try again later last time.
1330 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1331 if (currentTime < entry->interceptKeyWakeupTime) {
1332 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1333 *nextWakeupTime = entry->interceptKeyWakeupTime;
1334 }
1335 return false; // wait until next wakeup
1336 }
1337 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1338 entry->interceptKeyWakeupTime = 0;
1339 }
1340
1341 // Give the policy a chance to intercept the key.
1342 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1343 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001344 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001345 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001346 sp<IBinder> focusedWindowToken =
1347 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001348 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001350 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001351 return false; // wait for the command to run
1352 } else {
1353 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1354 }
1355 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001356 if (*dropReason == DropReason::NOT_DROPPED) {
1357 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001358 }
1359 }
1360
1361 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001362 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001363 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001364 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1365 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001366 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001367 return true;
1368 }
1369
1370 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001371 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001372 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001373 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001374 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001375 return false;
1376 }
1377
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001378 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001379 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001380 return true;
1381 }
1382
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001383 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001384 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001385
1386 // Dispatch the key.
1387 dispatchEventLocked(currentTime, entry, inputTargets);
1388 return true;
1389}
1390
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001391void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001392#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001393 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001394 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1395 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001396 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1397 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1398 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001399#endif
1400}
1401
Chris Yef59a2f42020-10-16 12:55:26 -07001402void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1403 mLock.unlock();
1404
1405 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1406 if (entry->accuracyChanged) {
1407 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1408 }
1409 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1410 entry->hwTimestamp, entry->values);
1411 mLock.lock();
1412}
1413
1414void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1415 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1416#if DEBUG_OUTBOUND_EVENT_DETAILS
1417 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1418 "source=0x%x, sensorType=%s",
1419 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
1420 NamedEnum::string(sensorType).c_str());
1421#endif
1422 std::unique_ptr<CommandEntry> commandEntry =
1423 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1424 commandEntry->sensorEntry = entry;
1425 postCommandLocked(std::move(commandEntry));
1426}
1427
1428bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1429#if DEBUG_OUTBOUND_EVENT_DETAILS
1430 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1431 NamedEnum::string(sensorType).c_str());
1432#endif
1433 { // acquire lock
1434 std::scoped_lock _l(mLock);
1435
1436 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1437 std::shared_ptr<EventEntry> entry = *it;
1438 if (entry->type == EventEntry::Type::SENSOR) {
1439 it = mInboundQueue.erase(it);
1440 releaseInboundEventLocked(entry);
1441 }
1442 }
1443 }
1444 return true;
1445}
1446
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001447bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001448 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001449 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001450 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001451 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001452 entry->dispatchInProgress = true;
1453
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001454 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001455 }
1456
1457 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001458 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001459 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001460 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1461 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001462 return true;
1463 }
1464
1465 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1466
1467 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001468 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001469
1470 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001471 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001472 if (isPointerEvent) {
1473 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001474 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001475 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001476 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 } else {
1478 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001479 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001480 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001481 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001482 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001483 return false;
1484 }
1485
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001486 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001487 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001488 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1489 return true;
1490 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001491 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001492 CancelationOptions::Mode mode(isPointerEvent
1493 ? CancelationOptions::CANCEL_POINTER_EVENTS
1494 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1495 CancelationOptions options(mode, "input event injection failed");
1496 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001497 return true;
1498 }
1499
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001500 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001501 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001502
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001503 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001504 std::unordered_map<int32_t, TouchState>::iterator it =
1505 mTouchStatesByDisplay.find(entry->displayId);
1506 if (it != mTouchStatesByDisplay.end()) {
1507 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001508 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001509 // The event has gone through these portal windows, so we add monitoring targets of
1510 // the corresponding displays as well.
1511 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001512 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001513 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001514 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001515 }
1516 }
1517 }
1518 }
1519
Michael Wrightd02c5b62014-02-10 15:10:22 -08001520 // Dispatch the motion.
1521 if (conflictingPointerActions) {
1522 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001523 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001524 synthesizeCancelationEventsForAllConnectionsLocked(options);
1525 }
1526 dispatchEventLocked(currentTime, entry, inputTargets);
1527 return true;
1528}
1529
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001530void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001531#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001532 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001533 ", policyFlags=0x%x, "
1534 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1535 "metaState=0x%x, buttonState=0x%x,"
1536 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001537 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1538 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1539 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001540
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001541 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001542 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001543 "x=%f, y=%f, pressure=%f, size=%f, "
1544 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1545 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001546 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1547 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1548 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1549 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1550 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1551 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1552 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1553 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1554 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1555 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001556 }
1557#endif
1558}
1559
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001560void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1561 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001562 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001563 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564#if DEBUG_DISPATCH_CYCLE
1565 ALOGD("dispatchEventToCurrentInputTargets");
1566#endif
1567
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001568 updateInteractionTokensLocked(*eventEntry, inputTargets);
1569
Michael Wrightd02c5b62014-02-10 15:10:22 -08001570 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1571
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001572 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001573
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001574 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001575 sp<Connection> connection =
1576 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001577 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001578 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001579 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001580 if (DEBUG_FOCUS) {
1581 ALOGD("Dropping event delivery to target with channel '%s' because it "
1582 "is no longer registered with the input dispatcher.",
1583 inputTarget.inputChannel->getName().c_str());
1584 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001585 }
1586 }
1587}
1588
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001589void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1590 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1591 // If the policy decides to close the app, we will get a channel removal event via
1592 // unregisterInputChannel, and will clean up the connection that way. We are already not
1593 // sending new pointers to the connection when it blocked, but focused events will continue to
1594 // pile up.
1595 ALOGW("Canceling events for %s because it is unresponsive",
1596 connection->inputChannel->getName().c_str());
1597 if (connection->status == Connection::STATUS_NORMAL) {
1598 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1599 "application not responding");
1600 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601 }
1602}
1603
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001604void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001605 if (DEBUG_FOCUS) {
1606 ALOGD("Resetting ANR timeouts.");
1607 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001608
1609 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001610 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001611 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001612}
1613
Tiger Huang721e26f2018-07-24 22:26:19 +08001614/**
1615 * Get the display id that the given event should go to. If this event specifies a valid display id,
1616 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1617 * Focused display is the display that the user most recently interacted with.
1618 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001619int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001620 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001621 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001622 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001623 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1624 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001625 break;
1626 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001627 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001628 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1629 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001630 break;
1631 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001632 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001633 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001634 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001635 case EventEntry::Type::DEVICE_RESET:
1636 case EventEntry::Type::SENSOR: {
1637 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001638 return ADISPLAY_ID_NONE;
1639 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001640 }
1641 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1642}
1643
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001644bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1645 const char* focusedWindowName) {
1646 if (mAnrTracker.empty()) {
1647 // already processed all events that we waited for
1648 mKeyIsWaitingForEventsTimeout = std::nullopt;
1649 return false;
1650 }
1651
1652 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1653 // Start the timer
1654 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1655 "focus to change",
1656 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001657 mKeyIsWaitingForEventsTimeout = currentTime +
1658 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1659 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001660 return true;
1661 }
1662
1663 // We still have pending events, and already started the timer
1664 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1665 return true; // Still waiting
1666 }
1667
1668 // Waited too long, and some connection still hasn't processed all motions
1669 // Just send the key to the focused window
1670 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1671 focusedWindowName);
1672 mKeyIsWaitingForEventsTimeout = std::nullopt;
1673 return false;
1674}
1675
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001676InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1677 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1678 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001679 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001680
Tiger Huang721e26f2018-07-24 22:26:19 +08001681 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001682 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001683 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001684 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1685
Michael Wrightd02c5b62014-02-10 15:10:22 -08001686 // If there is no currently focused window and no focused application
1687 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001688 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1689 ALOGI("Dropping %s event because there is no focused window or focused application in "
1690 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001691 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001692 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001693 }
1694
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001695 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1696 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1697 // start interacting with another application via touch (app switch). This code can be removed
1698 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1699 // an app is expected to have a focused window.
1700 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1701 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1702 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001703 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1704 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1705 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001706 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001707 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001708 ALOGW("Waiting because no window has focus but %s may eventually add a "
1709 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001710 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001711 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001712 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001713 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1714 // Already raised ANR. Drop the event
1715 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001716 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001717 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001718 } else {
1719 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001720 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001721 }
1722 }
1723
1724 // we have a valid, non-null focused window
1725 resetNoFocusedWindowTimeoutLocked();
1726
Michael Wrightd02c5b62014-02-10 15:10:22 -08001727 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001728 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001729 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001730 }
1731
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001732 if (focusedWindowHandle->getInfo()->paused) {
1733 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001734 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001735 }
1736
1737 // If the event is a key event, then we must wait for all previous events to
1738 // complete before delivering it because previous events may have the
1739 // side-effect of transferring focus to a different window and we want to
1740 // ensure that the following keys are sent to the new window.
1741 //
1742 // Suppose the user touches a button in a window then immediately presses "A".
1743 // If the button causes a pop-up window to appear then we want to ensure that
1744 // the "A" key is delivered to the new pop-up window. This is because users
1745 // often anticipate pending UI changes when typing on a keyboard.
1746 // To obtain this behavior, we must serialize key events with respect to all
1747 // prior input events.
1748 if (entry.type == EventEntry::Type::KEY) {
1749 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1750 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001751 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001752 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001753 }
1754
1755 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001756 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001757 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1758 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001759
1760 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001761 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001762}
1763
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001764/**
1765 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1766 * that are currently unresponsive.
1767 */
1768std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1769 const std::vector<TouchedMonitor>& monitors) const {
1770 std::vector<TouchedMonitor> responsiveMonitors;
1771 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1772 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1773 sp<Connection> connection = getConnectionLocked(
1774 monitor.monitor.inputChannel->getConnectionToken());
1775 if (connection == nullptr) {
1776 ALOGE("Could not find connection for monitor %s",
1777 monitor.monitor.inputChannel->getName().c_str());
1778 return false;
1779 }
1780 if (!connection->responsive) {
1781 ALOGW("Unresponsive monitor %s will not get the new gesture",
1782 connection->inputChannel->getName().c_str());
1783 return false;
1784 }
1785 return true;
1786 });
1787 return responsiveMonitors;
1788}
1789
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001790InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1791 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1792 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001793 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001794 enum InjectionPermission {
1795 INJECTION_PERMISSION_UNKNOWN,
1796 INJECTION_PERMISSION_GRANTED,
1797 INJECTION_PERMISSION_DENIED
1798 };
1799
Michael Wrightd02c5b62014-02-10 15:10:22 -08001800 // For security reasons, we defer updating the touch state until we are sure that
1801 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001802 int32_t displayId = entry.displayId;
1803 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001804 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1805
1806 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001807 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001808 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001809 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1810 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001811
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001812 // Copy current touch state into tempTouchState.
1813 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1814 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001815 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001816 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001817 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1818 mTouchStatesByDisplay.find(displayId);
1819 if (oldStateIt != mTouchStatesByDisplay.end()) {
1820 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001821 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001822 }
1823
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001824 bool isSplit = tempTouchState.split;
1825 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1826 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1827 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001828 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1829 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1830 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1831 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1832 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001833 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001834 bool wrongDevice = false;
1835 if (newGesture) {
1836 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001837 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001838 ALOGI("Dropping event because a pointer for a different device is already down "
1839 "in display %" PRId32,
1840 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001841 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001842 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001843 switchedDevice = false;
1844 wrongDevice = true;
1845 goto Failed;
1846 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001847 tempTouchState.reset();
1848 tempTouchState.down = down;
1849 tempTouchState.deviceId = entry.deviceId;
1850 tempTouchState.source = entry.source;
1851 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001852 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001853 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001854 ALOGI("Dropping move event because a pointer for a different device is already active "
1855 "in display %" PRId32,
1856 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001857 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001858 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001859 switchedDevice = false;
1860 wrongDevice = true;
1861 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001862 }
1863
1864 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1865 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1866
Garfield Tan00f511d2019-06-12 16:55:40 -07001867 int32_t x;
1868 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001869 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001870 // Always dispatch mouse events to cursor position.
1871 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001872 x = int32_t(entry.xCursorPosition);
1873 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001874 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001875 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1876 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001877 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001878 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001879 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001880 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1881 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001882
1883 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001884 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001885 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001886
Michael Wrightd02c5b62014-02-10 15:10:22 -08001887 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001888 if (newTouchedWindowHandle != nullptr &&
1889 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001890 // New window supports splitting, but we should never split mouse events.
1891 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001892 } else if (isSplit) {
1893 // New window does not support splitting but we have already split events.
1894 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001895 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001896 }
1897
1898 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001899 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001900 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001901 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001902 }
1903
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001904 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1905 ALOGI("Not sending touch event to %s because it is paused",
1906 newTouchedWindowHandle->getName().c_str());
1907 newTouchedWindowHandle = nullptr;
1908 }
1909
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001910 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001911 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001912 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1913 if (!isResponsive) {
1914 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001915 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1916 newTouchedWindowHandle = nullptr;
1917 }
1918 }
1919
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001920 // Drop events that can't be trusted due to occlusion
1921 if (newTouchedWindowHandle != nullptr &&
1922 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1923 TouchOcclusionInfo occlusionInfo =
1924 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001925 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001926 if (DEBUG_TOUCH_OCCLUSION) {
1927 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1928 for (const auto& log : occlusionInfo.debugInfo) {
1929 ALOGD("%s", log.c_str());
1930 }
1931 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001932 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1933 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1934 ALOGW("Dropping untrusted touch event due to %s/%d",
1935 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1936 newTouchedWindowHandle = nullptr;
1937 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001938 }
1939 }
1940
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001941 // Also don't send the new touch event to unresponsive gesture monitors
1942 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1943
Michael Wright3dd60e22019-03-27 22:06:44 +00001944 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1945 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001946 "(%d, %d) in display %" PRId32 ".",
1947 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001948 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001949 goto Failed;
1950 }
1951
1952 if (newTouchedWindowHandle != nullptr) {
1953 // Set target flags.
1954 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1955 if (isSplit) {
1956 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001957 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001958 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1959 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1960 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1961 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1962 }
1963
1964 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001965 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1966 newHoverWindowHandle = nullptr;
1967 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001968 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001969 }
1970
1971 // Update the temporary touch state.
1972 BitSet32 pointerIds;
1973 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001974 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001975 pointerIds.markBit(pointerId);
1976 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001977 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001978 }
1979
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001980 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001981 } else {
1982 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1983
1984 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001985 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001986 if (DEBUG_FOCUS) {
1987 ALOGD("Dropping event because the pointer is not down or we previously "
1988 "dropped the pointer down event in display %" PRId32,
1989 displayId);
1990 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001991 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001992 goto Failed;
1993 }
1994
1995 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001996 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001997 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001998 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
1999 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002000
2001 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002002 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002003 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002004 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2005 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002006 if (DEBUG_FOCUS) {
2007 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2008 oldTouchedWindowHandle->getName().c_str(),
2009 newTouchedWindowHandle->getName().c_str(), displayId);
2010 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002011 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002012 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2013 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2014 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002015
2016 // Make a slippery entrance into the new window.
2017 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2018 isSplit = true;
2019 }
2020
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002021 int32_t targetFlags =
2022 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002023 if (isSplit) {
2024 targetFlags |= InputTarget::FLAG_SPLIT;
2025 }
2026 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2027 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002028 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2029 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002030 }
2031
2032 BitSet32 pointerIds;
2033 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002034 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002035 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002036 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002037 }
2038 }
2039 }
2040
2041 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002042 // Let the previous window know that the hover sequence is over, unless we already did it
2043 // when dispatching it as is to newTouchedWindowHandle.
2044 if (mLastHoverWindowHandle != nullptr &&
2045 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2046 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002047#if DEBUG_HOVER
2048 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002049 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002050#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002051 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2052 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002053 }
2054
Garfield Tandf26e862020-07-01 20:18:19 -07002055 // Let the new window know that the hover sequence is starting, unless we already did it
2056 // when dispatching it as is to newTouchedWindowHandle.
2057 if (newHoverWindowHandle != nullptr &&
2058 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2059 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002060#if DEBUG_HOVER
2061 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002062 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002063#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002064 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2065 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2066 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002067 }
2068 }
2069
2070 // Check permission to inject into all touched foreground windows and ensure there
2071 // is at least one touched foreground window.
2072 {
2073 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002074 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2076 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002077 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002078 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002079 injectionPermission = INJECTION_PERMISSION_DENIED;
2080 goto Failed;
2081 }
2082 }
2083 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002084 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002085 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002086 ALOGI("Dropping event because there is no touched foreground window in display "
2087 "%" PRId32 " or gesture monitor to receive it.",
2088 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002089 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002090 goto Failed;
2091 }
2092
2093 // Permission granted to injection into all touched foreground windows.
2094 injectionPermission = INJECTION_PERMISSION_GRANTED;
2095 }
2096
2097 // Check whether windows listening for outside touches are owned by the same UID. If it is
2098 // set the policy flag that we will not reveal coordinate information to this window.
2099 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2100 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002101 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002102 if (foregroundWindowHandle) {
2103 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002104 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002105 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2106 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2107 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002108 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2109 InputTarget::FLAG_ZERO_COORDS,
2110 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002111 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002112 }
2113 }
2114 }
2115 }
2116
Michael Wrightd02c5b62014-02-10 15:10:22 -08002117 // If this is the first pointer going down and the touched window has a wallpaper
2118 // then also add the touched wallpaper windows so they are locked in for the duration
2119 // of the touch gesture.
2120 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2121 // engine only supports touch events. We would need to add a mechanism similar
2122 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2123 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2124 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002125 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002126 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002127 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002128 getWindowHandlesLocked(displayId);
2129 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002130 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002131 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002132 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002133 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002134 .addOrUpdateWindow(windowHandle,
2135 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2136 InputTarget::
2137 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2138 InputTarget::FLAG_DISPATCH_AS_IS,
2139 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002140 }
2141 }
2142 }
2143 }
2144
2145 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002146 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002147
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002148 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002149 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002150 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002151 }
2152
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002153 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002154 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002155 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002156 }
2157
Michael Wrightd02c5b62014-02-10 15:10:22 -08002158 // Drop the outside or hover touch windows since we will not care about them
2159 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002160 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002161
2162Failed:
2163 // Check injection permission once and for all.
2164 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002165 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002166 injectionPermission = INJECTION_PERMISSION_GRANTED;
2167 } else {
2168 injectionPermission = INJECTION_PERMISSION_DENIED;
2169 }
2170 }
2171
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002172 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2173 return injectionResult;
2174 }
2175
Michael Wrightd02c5b62014-02-10 15:10:22 -08002176 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002177 if (!wrongDevice) {
2178 if (switchedDevice) {
2179 if (DEBUG_FOCUS) {
2180 ALOGD("Conflicting pointer actions: Switched to a different device.");
2181 }
2182 *outConflictingPointerActions = true;
2183 }
2184
2185 if (isHoverAction) {
2186 // Started hovering, therefore no longer down.
2187 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002188 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002189 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2190 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002191 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002192 *outConflictingPointerActions = true;
2193 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002194 tempTouchState.reset();
2195 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2196 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2197 tempTouchState.deviceId = entry.deviceId;
2198 tempTouchState.source = entry.source;
2199 tempTouchState.displayId = displayId;
2200 }
2201 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2202 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2203 // All pointers up or canceled.
2204 tempTouchState.reset();
2205 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2206 // First pointer went down.
2207 if (oldState && oldState->down) {
2208 if (DEBUG_FOCUS) {
2209 ALOGD("Conflicting pointer actions: Down received while already down.");
2210 }
2211 *outConflictingPointerActions = true;
2212 }
2213 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2214 // One pointer went up.
2215 if (isSplit) {
2216 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2217 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002218
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002219 for (size_t i = 0; i < tempTouchState.windows.size();) {
2220 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2221 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2222 touchedWindow.pointerIds.clearBit(pointerId);
2223 if (touchedWindow.pointerIds.isEmpty()) {
2224 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2225 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002226 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002227 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002228 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002229 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002230 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002231 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002232
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002233 // Save changes unless the action was scroll in which case the temporary touch
2234 // state was only valid for this one action.
2235 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2236 if (tempTouchState.displayId >= 0) {
2237 mTouchStatesByDisplay[displayId] = tempTouchState;
2238 } else {
2239 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002241 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002242
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002243 // Update hover state.
2244 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002245 }
2246
Michael Wrightd02c5b62014-02-10 15:10:22 -08002247 return injectionResult;
2248}
2249
2250void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002251 int32_t targetFlags, BitSet32 pointerIds,
2252 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002253 std::vector<InputTarget>::iterator it =
2254 std::find_if(inputTargets.begin(), inputTargets.end(),
2255 [&windowHandle](const InputTarget& inputTarget) {
2256 return inputTarget.inputChannel->getConnectionToken() ==
2257 windowHandle->getToken();
2258 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002259
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002260 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002261
2262 if (it == inputTargets.end()) {
2263 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002264 std::shared_ptr<InputChannel> inputChannel =
2265 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002266 if (inputChannel == nullptr) {
2267 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2268 return;
2269 }
2270 inputTarget.inputChannel = inputChannel;
2271 inputTarget.flags = targetFlags;
2272 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2273 inputTargets.push_back(inputTarget);
2274 it = inputTargets.end() - 1;
2275 }
2276
2277 ALOG_ASSERT(it->flags == targetFlags);
2278 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2279
chaviw1ff3d1e2020-07-01 15:53:47 -07002280 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002281}
2282
Michael Wright3dd60e22019-03-27 22:06:44 +00002283void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002284 int32_t displayId, float xOffset,
2285 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002286 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2287 mGlobalMonitorsByDisplay.find(displayId);
2288
2289 if (it != mGlobalMonitorsByDisplay.end()) {
2290 const std::vector<Monitor>& monitors = it->second;
2291 for (const Monitor& monitor : monitors) {
2292 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002293 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002294 }
2295}
2296
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002297void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2298 float yOffset,
2299 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002300 InputTarget target;
2301 target.inputChannel = monitor.inputChannel;
2302 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002303 ui::Transform t;
2304 t.set(xOffset, yOffset);
2305 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002306 inputTargets.push_back(target);
2307}
2308
Michael Wrightd02c5b62014-02-10 15:10:22 -08002309bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002310 const InjectionState* injectionState) {
2311 if (injectionState &&
2312 (windowHandle == nullptr ||
2313 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2314 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002315 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002316 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002317 "owned by uid %d",
2318 injectionState->injectorPid, injectionState->injectorUid,
2319 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002320 } else {
2321 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002322 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002323 }
2324 return false;
2325 }
2326 return true;
2327}
2328
Robert Carrc9bf1d32020-04-13 17:21:08 -07002329/**
2330 * Indicate whether one window handle should be considered as obscuring
2331 * another window handle. We only check a few preconditions. Actually
2332 * checking the bounds is left to the caller.
2333 */
2334static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2335 const sp<InputWindowHandle>& otherHandle) {
2336 // Compare by token so cloned layers aren't counted
2337 if (haveSameToken(windowHandle, otherHandle)) {
2338 return false;
2339 }
2340 auto info = windowHandle->getInfo();
2341 auto otherInfo = otherHandle->getInfo();
2342 if (!otherInfo->visible) {
2343 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002344 } else if (otherInfo->alpha == 0 &&
2345 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2346 // Those act as if they were invisible, so we don't need to flag them.
2347 // We do want to potentially flag touchable windows even if they have 0
2348 // opacity, since they can consume touches and alter the effects of the
2349 // user interaction (eg. apps that rely on
2350 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2351 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2352 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002353 } else if (info->ownerUid == otherInfo->ownerUid) {
2354 // If ownerUid is the same we don't generate occlusion events as there
2355 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002356 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002357 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002358 return false;
2359 } else if (otherInfo->displayId != info->displayId) {
2360 return false;
2361 }
2362 return true;
2363}
2364
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002365/**
2366 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2367 * untrusted, one should check:
2368 *
2369 * 1. If result.hasBlockingOcclusion is true.
2370 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2371 * BLOCK_UNTRUSTED.
2372 *
2373 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2374 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2375 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2376 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2377 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2378 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2379 *
2380 * If neither of those is true, then it means the touch can be allowed.
2381 */
2382InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2383 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002384 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2385 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002386 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2387 TouchOcclusionInfo info;
2388 info.hasBlockingOcclusion = false;
2389 info.obscuringOpacity = 0;
2390 info.obscuringUid = -1;
2391 std::map<int32_t, float> opacityByUid;
2392 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2393 if (windowHandle == otherHandle) {
2394 break; // All future windows are below us. Exit early.
2395 }
2396 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2397 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002398 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2399 if (DEBUG_TOUCH_OCCLUSION) {
2400 info.debugInfo.push_back(
2401 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2402 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002403 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2404 // we perform the checks below to see if the touch can be propagated or not based on the
2405 // window's touch occlusion mode
2406 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2407 info.hasBlockingOcclusion = true;
2408 info.obscuringUid = otherInfo->ownerUid;
2409 info.obscuringPackage = otherInfo->packageName;
2410 break;
2411 }
2412 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2413 uint32_t uid = otherInfo->ownerUid;
2414 float opacity =
2415 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2416 // Given windows A and B:
2417 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2418 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2419 opacityByUid[uid] = opacity;
2420 if (opacity > info.obscuringOpacity) {
2421 info.obscuringOpacity = opacity;
2422 info.obscuringUid = uid;
2423 info.obscuringPackage = otherInfo->packageName;
2424 }
2425 }
2426 }
2427 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002428 if (DEBUG_TOUCH_OCCLUSION) {
2429 info.debugInfo.push_back(
2430 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2431 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002432 return info;
2433}
2434
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002435std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2436 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002437 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2438 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002439 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2440 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2441 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002442 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002443 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002444 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002445 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2446 info->frameTop, info->frameRight, info->frameBottom,
2447 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002448 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2449 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002450}
2451
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002452bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2453 if (occlusionInfo.hasBlockingOcclusion) {
2454 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2455 occlusionInfo.obscuringUid);
2456 return false;
2457 }
2458 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2459 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2460 "%.2f, maximum allowed = %.2f)",
2461 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2462 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2463 return false;
2464 }
2465 return true;
2466}
2467
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002468bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2469 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002470 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002471 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002472 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002473 if (windowHandle == otherHandle) {
2474 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002475 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002476 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002477 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002478 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002479 return true;
2480 }
2481 }
2482 return false;
2483}
2484
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002485bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2486 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002487 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002488 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002489 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002490 if (windowHandle == otherHandle) {
2491 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002492 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002493 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002494 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002495 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002496 return true;
2497 }
2498 }
2499 return false;
2500}
2501
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002502std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002503 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002504 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002505 if (applicationHandle != nullptr) {
2506 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002507 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002508 } else {
2509 return applicationHandle->getName();
2510 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002511 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002512 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002513 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002514 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002515 }
2516}
2517
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002518void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002519 if (eventEntry.type == EventEntry::Type::FOCUS ||
2520 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2521 // Focus or pointer capture changed events are passed to apps, but do not represent user
2522 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002523 return;
2524 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002525 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002526 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002527 if (focusedWindowHandle != nullptr) {
2528 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002529 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002531 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002532#endif
2533 return;
2534 }
2535 }
2536
2537 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002538 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002539 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002540 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2541 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002542 return;
2543 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002544
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002545 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002546 eventType = USER_ACTIVITY_EVENT_TOUCH;
2547 }
2548 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002549 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002550 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002551 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2552 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002553 return;
2554 }
2555 eventType = USER_ACTIVITY_EVENT_BUTTON;
2556 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002557 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002558 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002559 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002560 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002561 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -08002562 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002563 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002564 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002565 break;
2566 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002567 }
2568
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002569 std::unique_ptr<CommandEntry> commandEntry =
2570 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002571 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002572 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002573 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002574}
2575
2576void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002577 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002578 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002579 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002580 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002581 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002582 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002583 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002584 ATRACE_NAME(message.c_str());
2585 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002586#if DEBUG_DISPATCH_CYCLE
2587 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002588 "globalScaleFactor=%f, pointerIds=0x%x %s",
2589 connection->getInputChannelName().c_str(), inputTarget.flags,
2590 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2591 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002592#endif
2593
2594 // Skip this event if the connection status is not normal.
2595 // We don't want to enqueue additional outbound events if the connection is broken.
2596 if (connection->status != Connection::STATUS_NORMAL) {
2597#if DEBUG_DISPATCH_CYCLE
2598 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002599 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002600#endif
2601 return;
2602 }
2603
2604 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002605 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2606 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2607 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002608 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002609
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002610 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002611 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002612 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002613 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614 if (!splitMotionEntry) {
2615 return; // split event was dropped
2616 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002617 if (DEBUG_FOCUS) {
2618 ALOGD("channel '%s' ~ Split motion event.",
2619 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002620 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002621 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002622 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2623 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002624 return;
2625 }
2626 }
2627
2628 // Not splitting. Enqueue dispatch entries for the event as is.
2629 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2630}
2631
2632void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002633 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002634 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002635 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002636 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002637 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002638 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002639 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002640 ATRACE_NAME(message.c_str());
2641 }
2642
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002643 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002644
2645 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002646 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002647 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002648 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002649 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002650 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002651 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002652 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002653 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002654 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002655 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002656 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002657 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002658
2659 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002660 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002661 startDispatchCycleLocked(currentTime, connection);
2662 }
2663}
2664
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002665void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002666 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002667 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002668 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002669 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002670 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2671 connection->getInputChannelName().c_str(),
2672 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002673 ATRACE_NAME(message.c_str());
2674 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002675 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002676 if (!(inputTargetFlags & dispatchMode)) {
2677 return;
2678 }
2679 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2680
2681 // This is a new event.
2682 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002683 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002684 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002685
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002686 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2687 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002688 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002689 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002690 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002691 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002692 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002693 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002694 dispatchEntry->resolvedAction = keyEntry.action;
2695 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002696
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002697 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2698 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002699#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002700 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2701 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002702#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002703 return; // skip the inconsistent event
2704 }
2705 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002708 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002709 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002710 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2711 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2712 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2713 static_cast<int32_t>(IdGenerator::Source::OTHER);
2714 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002715 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2716 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2717 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2718 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2719 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2720 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2721 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2722 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2723 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2724 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2725 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002726 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002727 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002728 }
2729 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002730 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2731 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002732#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002733 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2734 "event",
2735 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002736#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002737 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2738 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002739
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002740 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002741 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2742 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2743 }
2744 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2745 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2746 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002747
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002748 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2749 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002750#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002751 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2752 "event",
2753 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002755 return; // skip the inconsistent event
2756 }
2757
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002758 dispatchEntry->resolvedEventId =
2759 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2760 ? mIdGenerator.nextId()
2761 : motionEntry.id;
2762 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2763 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2764 ") to MotionEvent(id=0x%" PRIx32 ").",
2765 motionEntry.id, dispatchEntry->resolvedEventId);
2766 ATRACE_NAME(message.c_str());
2767 }
2768
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002769 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002770 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002771
2772 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002773 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002774 case EventEntry::Type::FOCUS:
2775 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002776 break;
2777 }
Chris Yef59a2f42020-10-16 12:55:26 -07002778 case EventEntry::Type::SENSOR: {
2779 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2780 break;
2781 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002782 case EventEntry::Type::CONFIGURATION_CHANGED:
2783 case EventEntry::Type::DEVICE_RESET: {
2784 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002785 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002786 break;
2787 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002788 }
2789
2790 // Remember that we are waiting for this dispatch to complete.
2791 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002792 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002793 }
2794
2795 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002796 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002797 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002798}
2799
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002800/**
2801 * This function is purely for debugging. It helps us understand where the user interaction
2802 * was taking place. For example, if user is touching launcher, we will see a log that user
2803 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2804 * We will see both launcher and wallpaper in that list.
2805 * Once the interaction with a particular set of connections starts, no new logs will be printed
2806 * until the set of interacted connections changes.
2807 *
2808 * The following items are skipped, to reduce the logspam:
2809 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2810 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2811 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2812 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2813 * Both of those ACTION_UP events would not be logged
2814 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2815 * will not be logged. This is omitted to reduce the amount of data printed.
2816 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2817 * gesture monitor is the only connection receiving the remainder of the gesture.
2818 */
2819void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2820 const std::vector<InputTarget>& targets) {
2821 // Skip ACTION_UP events, and all events other than keys and motions
2822 if (entry.type == EventEntry::Type::KEY) {
2823 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2824 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2825 return;
2826 }
2827 } else if (entry.type == EventEntry::Type::MOTION) {
2828 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2829 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2830 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2831 return;
2832 }
2833 } else {
2834 return; // Not a key or a motion
2835 }
2836
2837 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2838 std::vector<sp<Connection>> newConnections;
2839 for (const InputTarget& target : targets) {
2840 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2841 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2842 continue; // Skip windows that receive ACTION_OUTSIDE
2843 }
2844
2845 sp<IBinder> token = target.inputChannel->getConnectionToken();
2846 sp<Connection> connection = getConnectionLocked(token);
2847 if (connection == nullptr || connection->monitor) {
2848 continue; // We only need to keep track of the non-monitor connections.
2849 }
2850 newConnectionTokens.insert(std::move(token));
2851 newConnections.emplace_back(connection);
2852 }
2853 if (newConnectionTokens == mInteractionConnectionTokens) {
2854 return; // no change
2855 }
2856 mInteractionConnectionTokens = newConnectionTokens;
2857
2858 std::string windowList;
2859 for (const sp<Connection>& connection : newConnections) {
2860 windowList += connection->getWindowName() + ", ";
2861 }
2862 std::string message = "Interaction with windows: " + windowList;
2863 if (windowList.empty()) {
2864 message += "<none>";
2865 }
2866 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2867}
2868
chaviwfd6d3512019-03-25 13:23:49 -07002869void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002870 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002871 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002872 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2873 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002874 return;
2875 }
2876
Vishnu Nairad321cd2020-08-20 16:40:21 -07002877 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2878 if (focusedToken == token) {
2879 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002880 return;
2881 }
2882
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002883 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2884 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002885 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002886 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002887}
2888
2889void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002890 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002891 if (ATRACE_ENABLED()) {
2892 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002893 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002894 ATRACE_NAME(message.c_str());
2895 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002896#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002897 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002898#endif
2899
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002900 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2901 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002902 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002903 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002904 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002905 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002906
2907 // Publish the event.
2908 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002909 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2910 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002911 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002912 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2913 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002914
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002916 status = connection->inputPublisher
2917 .publishKeyEvent(dispatchEntry->seq,
2918 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2919 keyEntry.source, keyEntry.displayId,
2920 std::move(hmac), dispatchEntry->resolvedAction,
2921 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2922 keyEntry.scanCode, keyEntry.metaState,
2923 keyEntry.repeatCount, keyEntry.downTime,
2924 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002925 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002926 }
2927
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002928 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002929 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002930
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002931 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002932 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002933
chaviw82357092020-01-28 13:13:06 -08002934 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002935 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002936 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2937 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002938 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002939 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2940 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002941 // Don't apply window scale here since we don't want scale to affect raw
2942 // coordinates. The scale will be sent back to the client and applied
2943 // later when requesting relative coordinates.
2944 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2945 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002946 }
2947 usingCoords = scaledCoords;
2948 }
2949 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002950 // We don't want the dispatch target to know.
2951 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002952 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002953 scaledCoords[i].clear();
2954 }
2955 usingCoords = scaledCoords;
2956 }
2957 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002958
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002959 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002960
2961 // Publish the motion event.
2962 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002963 .publishMotionEvent(dispatchEntry->seq,
2964 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002965 motionEntry.deviceId, motionEntry.source,
2966 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002967 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002968 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002969 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002970 motionEntry.edgeFlags, motionEntry.metaState,
2971 motionEntry.buttonState,
2972 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002973 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002974 motionEntry.xPrecision, motionEntry.yPrecision,
2975 motionEntry.xCursorPosition,
2976 motionEntry.yCursorPosition,
2977 motionEntry.downTime, motionEntry.eventTime,
2978 motionEntry.pointerCount,
2979 motionEntry.pointerProperties, usingCoords);
2980 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002981 break;
2982 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002983
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002984 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002985 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002986 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002987 focusEntry.id,
2988 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002989 mInTouchMode);
2990 break;
2991 }
2992
Prabir Pradhan99987712020-11-10 18:43:05 -08002993 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
2994 const auto& captureEntry =
2995 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
2996 status = connection->inputPublisher
2997 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
2998 captureEntry.pointerCaptureEnabled);
2999 break;
3000 }
3001
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003002 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003003 case EventEntry::Type::DEVICE_RESET:
3004 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003005 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003006 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003007 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003008 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003009 }
3010
3011 // Check the result.
3012 if (status) {
3013 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003014 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003015 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003016 "This is unexpected because the wait queue is empty, so the pipe "
3017 "should be empty and we shouldn't have any problems writing an "
3018 "event to it, status=%d",
3019 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003020 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3021 } else {
3022 // Pipe is full and we are waiting for the app to finish process some events
3023 // before sending more events to it.
3024#if DEBUG_DISPATCH_CYCLE
3025 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003026 "waiting for the application to catch up",
3027 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003028#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003029 }
3030 } else {
3031 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003032 "status=%d",
3033 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003034 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3035 }
3036 return;
3037 }
3038
3039 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003040 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3041 connection->outboundQueue.end(),
3042 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003043 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003044 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003045 if (connection->responsive) {
3046 mAnrTracker.insert(dispatchEntry->timeoutTime,
3047 connection->inputChannel->getConnectionToken());
3048 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003049 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050 }
3051}
3052
chaviw09c8d2d2020-08-24 15:48:26 -07003053std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3054 size_t size;
3055 switch (event.type) {
3056 case VerifiedInputEvent::Type::KEY: {
3057 size = sizeof(VerifiedKeyEvent);
3058 break;
3059 }
3060 case VerifiedInputEvent::Type::MOTION: {
3061 size = sizeof(VerifiedMotionEvent);
3062 break;
3063 }
3064 }
3065 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3066 return mHmacKeyManager.sign(start, size);
3067}
3068
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003069const std::array<uint8_t, 32> InputDispatcher::getSignature(
3070 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3071 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3072 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3073 // Only sign events up and down events as the purely move events
3074 // are tied to their up/down counterparts so signing would be redundant.
3075 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3076 verifiedEvent.actionMasked = actionMasked;
3077 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003078 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003079 }
3080 return INVALID_HMAC;
3081}
3082
3083const std::array<uint8_t, 32> InputDispatcher::getSignature(
3084 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3085 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3086 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3087 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003088 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003089}
3090
Michael Wrightd02c5b62014-02-10 15:10:22 -08003091void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003092 const sp<Connection>& connection, uint32_t seq,
3093 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003094#if DEBUG_DISPATCH_CYCLE
3095 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003096 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003097#endif
3098
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003099 if (connection->status == Connection::STATUS_BROKEN ||
3100 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003101 return;
3102 }
3103
3104 // Notify other system components and prepare to start the next dispatch cycle.
3105 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
3106}
3107
3108void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003109 const sp<Connection>& connection,
3110 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003111#if DEBUG_DISPATCH_CYCLE
3112 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003113 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003114#endif
3115
3116 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003117 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003118 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003119 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003120 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003121
3122 // The connection appears to be unrecoverably broken.
3123 // Ignore already broken or zombie connections.
3124 if (connection->status == Connection::STATUS_NORMAL) {
3125 connection->status = Connection::STATUS_BROKEN;
3126
3127 if (notify) {
3128 // Notify other system components.
3129 onDispatchCycleBrokenLocked(currentTime, connection);
3130 }
3131 }
3132}
3133
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003134void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3135 while (!queue.empty()) {
3136 DispatchEntry* dispatchEntry = queue.front();
3137 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003138 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003139 }
3140}
3141
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003142void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003144 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003145 }
3146 delete dispatchEntry;
3147}
3148
3149int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3150 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3151
3152 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003153 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003154
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003155 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003156 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003157 "fd=%d, events=0x%x",
3158 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003159 return 0; // remove the callback
3160 }
3161
3162 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003163 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003164 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3165 if (!(events & ALOOPER_EVENT_INPUT)) {
3166 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003167 "events=0x%x",
3168 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003169 return 1;
3170 }
3171
3172 nsecs_t currentTime = now();
3173 bool gotOne = false;
3174 status_t status;
3175 for (;;) {
3176 uint32_t seq;
3177 bool handled;
3178 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3179 if (status) {
3180 break;
3181 }
3182 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3183 gotOne = true;
3184 }
3185 if (gotOne) {
3186 d->runCommandsLockedInterruptible();
3187 if (status == WOULD_BLOCK) {
3188 return 1;
3189 }
3190 }
3191
3192 notify = status != DEAD_OBJECT || !connection->monitor;
3193 if (notify) {
3194 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003195 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003196 }
3197 } else {
3198 // Monitor channels are never explicitly unregistered.
3199 // We do it automatically when the remote endpoint is closed so don't warn
3200 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003201 const bool stillHaveWindowHandle =
3202 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3203 nullptr;
3204 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003205 if (notify) {
3206 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003207 "events=0x%x",
3208 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003209 }
3210 }
3211
Garfield Tan15601662020-09-22 15:32:38 -07003212 // Remove the channel.
3213 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003214 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003215 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003216}
3217
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003218void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003219 const CancelationOptions& options) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003220 for (const auto& pair : mConnectionsByFd) {
3221 synthesizeCancelationEventsForConnectionLocked(pair.second, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003222 }
3223}
3224
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003225void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003226 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003227 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3228 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3229}
3230
3231void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3232 const CancelationOptions& options,
3233 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3234 for (const auto& it : monitorsByDisplay) {
3235 const std::vector<Monitor>& monitors = it.second;
3236 for (const Monitor& monitor : monitors) {
3237 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003238 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003239 }
3240}
3241
Michael Wrightd02c5b62014-02-10 15:10:22 -08003242void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003243 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003244 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003245 if (connection == nullptr) {
3246 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003247 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003248
3249 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003250}
3251
3252void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3253 const sp<Connection>& connection, const CancelationOptions& options) {
3254 if (connection->status == Connection::STATUS_BROKEN) {
3255 return;
3256 }
3257
3258 nsecs_t currentTime = now();
3259
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003260 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003261 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003262
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003263 if (cancelationEvents.empty()) {
3264 return;
3265 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003266#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003267 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3268 "with reality: %s, mode=%d.",
3269 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3270 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003271#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003272
3273 InputTarget target;
3274 sp<InputWindowHandle> windowHandle =
3275 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3276 if (windowHandle != nullptr) {
3277 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003278 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003279 target.globalScaleFactor = windowInfo->globalScaleFactor;
3280 }
3281 target.inputChannel = connection->inputChannel;
3282 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3283
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003284 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003285 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003286 switch (cancelationEventEntry->type) {
3287 case EventEntry::Type::KEY: {
3288 logOutboundKeyDetails("cancel - ",
3289 static_cast<const KeyEntry&>(*cancelationEventEntry));
3290 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003291 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003292 case EventEntry::Type::MOTION: {
3293 logOutboundMotionDetails("cancel - ",
3294 static_cast<const MotionEntry&>(*cancelationEventEntry));
3295 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003296 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003297 case EventEntry::Type::FOCUS:
3298 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3299 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003300 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003301 break;
3302 }
3303 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003304 case EventEntry::Type::DEVICE_RESET:
3305 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003306 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003307 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003308 break;
3309 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003310 }
3311
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003312 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3313 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003314 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003315
3316 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003317}
3318
Svet Ganov5d3bc372020-01-26 23:11:07 -08003319void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3320 const sp<Connection>& connection) {
3321 if (connection->status == Connection::STATUS_BROKEN) {
3322 return;
3323 }
3324
3325 nsecs_t currentTime = now();
3326
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003327 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003328 connection->inputState.synthesizePointerDownEvents(currentTime);
3329
3330 if (downEvents.empty()) {
3331 return;
3332 }
3333
3334#if DEBUG_OUTBOUND_EVENT_DETAILS
3335 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3336 connection->getInputChannelName().c_str(), downEvents.size());
3337#endif
3338
3339 InputTarget target;
3340 sp<InputWindowHandle> windowHandle =
3341 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3342 if (windowHandle != nullptr) {
3343 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003344 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003345 target.globalScaleFactor = windowInfo->globalScaleFactor;
3346 }
3347 target.inputChannel = connection->inputChannel;
3348 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3349
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003350 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003351 switch (downEventEntry->type) {
3352 case EventEntry::Type::MOTION: {
3353 logOutboundMotionDetails("down - ",
3354 static_cast<const MotionEntry&>(*downEventEntry));
3355 break;
3356 }
3357
3358 case EventEntry::Type::KEY:
3359 case EventEntry::Type::FOCUS:
3360 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003361 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003362 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3363 case EventEntry::Type::SENSOR: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003364 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003365 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003366 break;
3367 }
3368 }
3369
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003370 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3371 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003372 }
3373
3374 startDispatchCycleLocked(currentTime, connection);
3375}
3376
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003377std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3378 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003379 ALOG_ASSERT(pointerIds.value != 0);
3380
3381 uint32_t splitPointerIndexMap[MAX_POINTERS];
3382 PointerProperties splitPointerProperties[MAX_POINTERS];
3383 PointerCoords splitPointerCoords[MAX_POINTERS];
3384
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003385 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003386 uint32_t splitPointerCount = 0;
3387
3388 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003389 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003390 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003391 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003392 uint32_t pointerId = uint32_t(pointerProperties.id);
3393 if (pointerIds.hasBit(pointerId)) {
3394 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3395 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3396 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003397 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003398 splitPointerCount += 1;
3399 }
3400 }
3401
3402 if (splitPointerCount != pointerIds.count()) {
3403 // This is bad. We are missing some of the pointers that we expected to deliver.
3404 // Most likely this indicates that we received an ACTION_MOVE events that has
3405 // different pointer ids than we expected based on the previous ACTION_DOWN
3406 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3407 // in this way.
3408 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003409 "we expected there to be %d pointers. This probably means we received "
3410 "a broken sequence of pointer ids from the input device.",
3411 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003412 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003413 }
3414
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003415 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003416 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003417 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3418 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003419 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3420 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003421 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003422 uint32_t pointerId = uint32_t(pointerProperties.id);
3423 if (pointerIds.hasBit(pointerId)) {
3424 if (pointerIds.count() == 1) {
3425 // The first/last pointer went down/up.
3426 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003427 ? AMOTION_EVENT_ACTION_DOWN
3428 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003429 } else {
3430 // A secondary pointer went down/up.
3431 uint32_t splitPointerIndex = 0;
3432 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3433 splitPointerIndex += 1;
3434 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003435 action = maskedAction |
3436 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003437 }
3438 } else {
3439 // An unrelated pointer changed.
3440 action = AMOTION_EVENT_ACTION_MOVE;
3441 }
3442 }
3443
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003444 int32_t newId = mIdGenerator.nextId();
3445 if (ATRACE_ENABLED()) {
3446 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3447 ") to MotionEvent(id=0x%" PRIx32 ").",
3448 originalMotionEntry.id, newId);
3449 ATRACE_NAME(message.c_str());
3450 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003451 std::unique_ptr<MotionEntry> splitMotionEntry =
3452 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3453 originalMotionEntry.deviceId, originalMotionEntry.source,
3454 originalMotionEntry.displayId,
3455 originalMotionEntry.policyFlags, action,
3456 originalMotionEntry.actionButton,
3457 originalMotionEntry.flags, originalMotionEntry.metaState,
3458 originalMotionEntry.buttonState,
3459 originalMotionEntry.classification,
3460 originalMotionEntry.edgeFlags,
3461 originalMotionEntry.xPrecision,
3462 originalMotionEntry.yPrecision,
3463 originalMotionEntry.xCursorPosition,
3464 originalMotionEntry.yCursorPosition,
3465 originalMotionEntry.downTime, splitPointerCount,
3466 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003467
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003468 if (originalMotionEntry.injectionState) {
3469 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003470 splitMotionEntry->injectionState->refCount += 1;
3471 }
3472
3473 return splitMotionEntry;
3474}
3475
3476void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3477#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003478 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003479#endif
3480
3481 bool needWake;
3482 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003483 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003484
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003485 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3486 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3487 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003488 } // release lock
3489
3490 if (needWake) {
3491 mLooper->wake();
3492 }
3493}
3494
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003495/**
3496 * If one of the meta shortcuts is detected, process them here:
3497 * Meta + Backspace -> generate BACK
3498 * Meta + Enter -> generate HOME
3499 * This will potentially overwrite keyCode and metaState.
3500 */
3501void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003502 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003503 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3504 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3505 if (keyCode == AKEYCODE_DEL) {
3506 newKeyCode = AKEYCODE_BACK;
3507 } else if (keyCode == AKEYCODE_ENTER) {
3508 newKeyCode = AKEYCODE_HOME;
3509 }
3510 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003511 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003512 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003513 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003514 keyCode = newKeyCode;
3515 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3516 }
3517 } else if (action == AKEY_EVENT_ACTION_UP) {
3518 // In order to maintain a consistent stream of up and down events, check to see if the key
3519 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3520 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003521 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003522 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003523 auto replacementIt = mReplacedKeys.find(replacement);
3524 if (replacementIt != mReplacedKeys.end()) {
3525 keyCode = replacementIt->second;
3526 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003527 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3528 }
3529 }
3530}
3531
Michael Wrightd02c5b62014-02-10 15:10:22 -08003532void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3533#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003534 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3535 "policyFlags=0x%x, action=0x%x, "
3536 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3537 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3538 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3539 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003540#endif
3541 if (!validateKeyEvent(args->action)) {
3542 return;
3543 }
3544
3545 uint32_t policyFlags = args->policyFlags;
3546 int32_t flags = args->flags;
3547 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003548 // InputDispatcher tracks and generates key repeats on behalf of
3549 // whatever notifies it, so repeatCount should always be set to 0
3550 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003551 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3552 policyFlags |= POLICY_FLAG_VIRTUAL;
3553 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3554 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003555 if (policyFlags & POLICY_FLAG_FUNCTION) {
3556 metaState |= AMETA_FUNCTION_ON;
3557 }
3558
3559 policyFlags |= POLICY_FLAG_TRUSTED;
3560
Michael Wright78f24442014-08-06 15:55:28 -07003561 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003562 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003563
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003565 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003566 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3567 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003568
Michael Wright2b3c3302018-03-02 17:19:13 +00003569 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003570 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003571 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3572 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003573 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003574 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575
Michael Wrightd02c5b62014-02-10 15:10:22 -08003576 bool needWake;
3577 { // acquire lock
3578 mLock.lock();
3579
3580 if (shouldSendKeyToInputFilterLocked(args)) {
3581 mLock.unlock();
3582
3583 policyFlags |= POLICY_FLAG_FILTERED;
3584 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3585 return; // event was consumed by the filter
3586 }
3587
3588 mLock.lock();
3589 }
3590
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003591 std::unique_ptr<KeyEntry> newEntry =
3592 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3593 args->displayId, policyFlags, args->action, flags,
3594 keyCode, args->scanCode, metaState, repeatCount,
3595 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003596
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003597 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003598 mLock.unlock();
3599 } // release lock
3600
3601 if (needWake) {
3602 mLooper->wake();
3603 }
3604}
3605
3606bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3607 return mInputFilterEnabled;
3608}
3609
3610void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3611#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003612 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3613 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003614 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3615 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003616 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003617 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3618 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3619 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3620 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003621 for (uint32_t i = 0; i < args->pointerCount; i++) {
3622 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003623 "x=%f, y=%f, pressure=%f, size=%f, "
3624 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3625 "orientation=%f",
3626 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3627 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3628 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3629 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3630 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3631 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3632 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3633 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3634 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3635 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003636 }
3637#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003638 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3639 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003640 return;
3641 }
3642
3643 uint32_t policyFlags = args->policyFlags;
3644 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003645
3646 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003647 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003648 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3649 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003650 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003651 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003652
3653 bool needWake;
3654 { // acquire lock
3655 mLock.lock();
3656
3657 if (shouldSendMotionToInputFilterLocked(args)) {
3658 mLock.unlock();
3659
3660 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003661 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003662 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3663 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003664 args->metaState, args->buttonState, args->classification, transform,
3665 args->xPrecision, args->yPrecision, args->xCursorPosition,
3666 args->yCursorPosition, args->downTime, args->eventTime,
3667 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003668
3669 policyFlags |= POLICY_FLAG_FILTERED;
3670 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3671 return; // event was consumed by the filter
3672 }
3673
3674 mLock.lock();
3675 }
3676
3677 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003678 std::unique_ptr<MotionEntry> newEntry =
3679 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3680 args->source, args->displayId, policyFlags,
3681 args->action, args->actionButton, args->flags,
3682 args->metaState, args->buttonState,
3683 args->classification, args->edgeFlags,
3684 args->xPrecision, args->yPrecision,
3685 args->xCursorPosition, args->yCursorPosition,
3686 args->downTime, args->pointerCount,
3687 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003688
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003689 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003690 mLock.unlock();
3691 } // release lock
3692
3693 if (needWake) {
3694 mLooper->wake();
3695 }
3696}
3697
Chris Yef59a2f42020-10-16 12:55:26 -07003698void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3699#if DEBUG_INBOUND_EVENT_DETAILS
3700 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3701 " sensorType=%s",
3702 args->id, args->eventTime, args->deviceId, args->source,
3703 NamedEnum::string(args->sensorType).c_str());
3704#endif
3705
3706 bool needWake;
3707 { // acquire lock
3708 mLock.lock();
3709
3710 // Just enqueue a new sensor event.
3711 std::unique_ptr<SensorEntry> newEntry =
3712 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3713 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3714 args->sensorType, args->accuracy,
3715 args->accuracyChanged, args->values);
3716
3717 needWake = enqueueInboundEventLocked(std::move(newEntry));
3718 mLock.unlock();
3719 } // release lock
3720
3721 if (needWake) {
3722 mLooper->wake();
3723 }
3724}
3725
Michael Wrightd02c5b62014-02-10 15:10:22 -08003726bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003727 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003728}
3729
3730void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3731#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003732 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003733 "switchMask=0x%08x",
3734 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003735#endif
3736
3737 uint32_t policyFlags = args->policyFlags;
3738 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003739 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003740}
3741
3742void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3743#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003744 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3745 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003746#endif
3747
3748 bool needWake;
3749 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003750 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003751
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003752 std::unique_ptr<DeviceResetEntry> newEntry =
3753 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3754 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003755 } // release lock
3756
3757 if (needWake) {
3758 mLooper->wake();
3759 }
3760}
3761
Prabir Pradhan7e186182020-11-10 13:56:45 -08003762void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3763#if DEBUG_INBOUND_EVENT_DETAILS
3764 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3765 args->enabled ? "true" : "false");
3766#endif
3767
Prabir Pradhan99987712020-11-10 18:43:05 -08003768 bool needWake;
3769 { // acquire lock
3770 std::scoped_lock _l(mLock);
3771 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3772 args->enabled);
3773 needWake = enqueueInboundEventLocked(std::move(entry));
3774 } // release lock
3775
3776 if (needWake) {
3777 mLooper->wake();
3778 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003779}
3780
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003781InputEventInjectionResult InputDispatcher::injectInputEvent(
3782 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3783 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003784#if DEBUG_INBOUND_EVENT_DETAILS
3785 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003786 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3787 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003788#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003789 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003790
3791 policyFlags |= POLICY_FLAG_INJECTED;
3792 if (hasInjectionPermission(injectorPid, injectorUid)) {
3793 policyFlags |= POLICY_FLAG_TRUSTED;
3794 }
3795
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003796 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003797 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003798 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003799 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3800 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003801 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003802 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003803 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003804
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003805 int32_t flags = incomingKey.getFlags();
3806 int32_t keyCode = incomingKey.getKeyCode();
3807 int32_t metaState = incomingKey.getMetaState();
3808 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003809 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003810 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003811 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003812 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3813 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3814 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003815
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003816 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3817 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003818 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003819
3820 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3821 android::base::Timer t;
3822 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3823 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3824 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3825 std::to_string(t.duration().count()).c_str());
3826 }
3827 }
3828
3829 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003830 std::unique_ptr<KeyEntry> injectedEntry =
3831 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3832 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3833 incomingKey.getDisplayId(), policyFlags, action,
3834 flags, keyCode, incomingKey.getScanCode(), metaState,
3835 incomingKey.getRepeatCount(),
3836 incomingKey.getDownTime());
3837 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003838 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839 }
3840
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003841 case AINPUT_EVENT_TYPE_MOTION: {
3842 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3843 int32_t action = motionEvent->getAction();
3844 size_t pointerCount = motionEvent->getPointerCount();
3845 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3846 int32_t actionButton = motionEvent->getActionButton();
3847 int32_t displayId = motionEvent->getDisplayId();
3848 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003849 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003850 }
3851
3852 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3853 nsecs_t eventTime = motionEvent->getEventTime();
3854 android::base::Timer t;
3855 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3856 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3857 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3858 std::to_string(t.duration().count()).c_str());
3859 }
3860 }
3861
3862 mLock.lock();
3863 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3864 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003865 std::unique_ptr<MotionEntry> injectedEntry =
3866 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3867 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3868 motionEvent->getDisplayId(), policyFlags, action,
3869 actionButton, motionEvent->getFlags(),
3870 motionEvent->getMetaState(),
3871 motionEvent->getButtonState(),
3872 motionEvent->getClassification(),
3873 motionEvent->getEdgeFlags(),
3874 motionEvent->getXPrecision(),
3875 motionEvent->getYPrecision(),
3876 motionEvent->getRawXCursorPosition(),
3877 motionEvent->getRawYCursorPosition(),
3878 motionEvent->getDownTime(),
3879 uint32_t(pointerCount), pointerProperties,
3880 samplePointerCoords, motionEvent->getXOffset(),
3881 motionEvent->getYOffset());
3882 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003883 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3884 sampleEventTimes += 1;
3885 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003886 std::unique_ptr<MotionEntry> nextInjectedEntry =
3887 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3888 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3889 motionEvent->getDisplayId(), policyFlags,
3890 action, actionButton, motionEvent->getFlags(),
3891 motionEvent->getMetaState(),
3892 motionEvent->getButtonState(),
3893 motionEvent->getClassification(),
3894 motionEvent->getEdgeFlags(),
3895 motionEvent->getXPrecision(),
3896 motionEvent->getYPrecision(),
3897 motionEvent->getRawXCursorPosition(),
3898 motionEvent->getRawYCursorPosition(),
3899 motionEvent->getDownTime(),
3900 uint32_t(pointerCount), pointerProperties,
3901 samplePointerCoords,
3902 motionEvent->getXOffset(),
3903 motionEvent->getYOffset());
3904 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003905 }
3906 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003907 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003908
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003909 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003910 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003911 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003912 }
3913
3914 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003915 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003916 injectionState->injectionIsAsync = true;
3917 }
3918
3919 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003920 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003921
3922 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003923 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003924 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003925 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003926 }
3927
3928 mLock.unlock();
3929
3930 if (needWake) {
3931 mLooper->wake();
3932 }
3933
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003934 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003935 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003936 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003937
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003938 if (syncMode == InputEventInjectionSync::NONE) {
3939 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940 } else {
3941 for (;;) {
3942 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003943 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003944 break;
3945 }
3946
3947 nsecs_t remainingTimeout = endTime - now();
3948 if (remainingTimeout <= 0) {
3949#if DEBUG_INJECTION
3950 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003951 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003952#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003953 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003954 break;
3955 }
3956
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003957 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003958 }
3959
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003960 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3961 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003962 while (injectionState->pendingForegroundDispatches != 0) {
3963#if DEBUG_INJECTION
3964 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003965 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003966#endif
3967 nsecs_t remainingTimeout = endTime - now();
3968 if (remainingTimeout <= 0) {
3969#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003970 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3971 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003972#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003973 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003974 break;
3975 }
3976
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003977 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003978 }
3979 }
3980 }
3981
3982 injectionState->release();
3983 } // release lock
3984
3985#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003986 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003987 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003988#endif
3989
3990 return injectionResult;
3991}
3992
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08003993std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05003994 std::array<uint8_t, 32> calculatedHmac;
3995 std::unique_ptr<VerifiedInputEvent> result;
3996 switch (event.getType()) {
3997 case AINPUT_EVENT_TYPE_KEY: {
3998 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
3999 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4000 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004001 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004002 break;
4003 }
4004 case AINPUT_EVENT_TYPE_MOTION: {
4005 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4006 VerifiedMotionEvent verifiedMotionEvent =
4007 verifiedMotionEventFromMotionEvent(motionEvent);
4008 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004009 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004010 break;
4011 }
4012 default: {
4013 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4014 return nullptr;
4015 }
4016 }
4017 if (calculatedHmac == INVALID_HMAC) {
4018 return nullptr;
4019 }
4020 if (calculatedHmac != event.getHmac()) {
4021 return nullptr;
4022 }
4023 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004024}
4025
Michael Wrightd02c5b62014-02-10 15:10:22 -08004026bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004027 return injectorUid == 0 ||
4028 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004029}
4030
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004031void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004032 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004033 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004034 if (injectionState) {
4035#if DEBUG_INJECTION
4036 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004037 "injectorPid=%d, injectorUid=%d",
4038 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004039#endif
4040
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004041 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004042 // Log the outcome since the injector did not wait for the injection result.
4043 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004044 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004045 ALOGV("Asynchronous input event injection succeeded.");
4046 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004047 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004048 ALOGW("Asynchronous input event injection failed.");
4049 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004050 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004051 ALOGW("Asynchronous input event injection permission denied.");
4052 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004053 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004054 ALOGW("Asynchronous input event injection timed out.");
4055 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004056 case InputEventInjectionResult::PENDING:
4057 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4058 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004059 }
4060 }
4061
4062 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004063 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004064 }
4065}
4066
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004067void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4068 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004069 if (injectionState) {
4070 injectionState->pendingForegroundDispatches += 1;
4071 }
4072}
4073
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004074void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4075 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004076 if (injectionState) {
4077 injectionState->pendingForegroundDispatches -= 1;
4078
4079 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004080 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004081 }
4082 }
4083}
4084
Vishnu Nairad321cd2020-08-20 16:40:21 -07004085const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004086 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004087 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4088 auto it = mWindowHandlesByDisplay.find(displayId);
4089 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004090}
4091
Michael Wrightd02c5b62014-02-10 15:10:22 -08004092sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004093 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004094 if (windowHandleToken == nullptr) {
4095 return nullptr;
4096 }
4097
Arthur Hungb92218b2018-08-14 12:00:21 +08004098 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004099 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004100 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004101 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004102 return windowHandle;
4103 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004104 }
4105 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004106 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004107}
4108
Vishnu Nairad321cd2020-08-20 16:40:21 -07004109sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4110 int displayId) const {
4111 if (windowHandleToken == nullptr) {
4112 return nullptr;
4113 }
4114
4115 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4116 if (windowHandle->getToken() == windowHandleToken) {
4117 return windowHandle;
4118 }
4119 }
4120 return nullptr;
4121}
4122
4123sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4124 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4125 return getWindowHandleLocked(focusedToken, displayId);
4126}
4127
Mady Mellor017bcd12020-06-23 19:12:00 +00004128bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4129 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004130 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004131 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004132 if (handle->getId() == windowHandle->getId() &&
4133 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004134 if (windowHandle->getInfo()->displayId != it.first) {
4135 ALOGE("Found window %s in display %" PRId32
4136 ", but it should belong to display %" PRId32,
4137 windowHandle->getName().c_str(), it.first,
4138 windowHandle->getInfo()->displayId);
4139 }
4140 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004141 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004142 }
4143 }
4144 return false;
4145}
4146
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004147bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4148 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4149 const bool noInputChannel =
4150 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4151 if (connection != nullptr && noInputChannel) {
4152 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4153 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4154 return false;
4155 }
4156
4157 if (connection == nullptr) {
4158 if (!noInputChannel) {
4159 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4160 }
4161 return false;
4162 }
4163 if (!connection->responsive) {
4164 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4165 return false;
4166 }
4167 return true;
4168}
4169
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004170std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4171 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004172 size_t count = mInputChannelsByToken.count(token);
4173 if (count == 0) {
4174 return nullptr;
4175 }
4176 return mInputChannelsByToken.at(token);
4177}
4178
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004179void InputDispatcher::updateWindowHandlesForDisplayLocked(
4180 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4181 if (inputWindowHandles.empty()) {
4182 // Remove all handles on a display if there are no windows left.
4183 mWindowHandlesByDisplay.erase(displayId);
4184 return;
4185 }
4186
4187 // Since we compare the pointer of input window handles across window updates, we need
4188 // to make sure the handle object for the same window stays unchanged across updates.
4189 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004190 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004191 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004192 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004193 }
4194
4195 std::vector<sp<InputWindowHandle>> newHandles;
4196 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4197 if (!handle->updateInfo()) {
4198 // handle no longer valid
4199 continue;
4200 }
4201
4202 const InputWindowInfo* info = handle->getInfo();
4203 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4204 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4205 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004206 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4207 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4208 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004209 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004210 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004211 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004212 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004213 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004214 }
4215
4216 if (info->displayId != displayId) {
4217 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4218 handle->getName().c_str(), displayId, info->displayId);
4219 continue;
4220 }
4221
Robert Carredd13602020-04-13 17:24:34 -07004222 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4223 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004224 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004225 oldHandle->updateFrom(handle);
4226 newHandles.push_back(oldHandle);
4227 } else {
4228 newHandles.push_back(handle);
4229 }
4230 }
4231
4232 // Insert or replace
4233 mWindowHandlesByDisplay[displayId] = newHandles;
4234}
4235
Arthur Hung72d8dc32020-03-28 00:48:39 +00004236void InputDispatcher::setInputWindows(
4237 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4238 { // acquire lock
4239 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004240 for (const auto& [displayId, handles] : handlesPerDisplay) {
4241 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004242 }
4243 }
4244 // Wake up poll loop since it may need to make new input dispatching choices.
4245 mLooper->wake();
4246}
4247
Arthur Hungb92218b2018-08-14 12:00:21 +08004248/**
4249 * Called from InputManagerService, update window handle list by displayId that can receive input.
4250 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4251 * If set an empty list, remove all handles from the specific display.
4252 * For focused handle, check if need to change and send a cancel event to previous one.
4253 * For removed handle, check if need to send a cancel event if already in touch.
4254 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004255void InputDispatcher::setInputWindowsLocked(
4256 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004257 if (DEBUG_FOCUS) {
4258 std::string windowList;
4259 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4260 windowList += iwh->getName() + " ";
4261 }
4262 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4263 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004264
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004265 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4266 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4267 const bool noInputWindow =
4268 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4269 if (noInputWindow && window->getToken() != nullptr) {
4270 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4271 window->getName().c_str());
4272 window->releaseChannel();
4273 }
4274 }
4275
Arthur Hung72d8dc32020-03-28 00:48:39 +00004276 // Copy old handles for release if they are no longer present.
4277 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004278
Arthur Hung72d8dc32020-03-28 00:48:39 +00004279 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004280
Vishnu Nair958da932020-08-21 17:12:37 -07004281 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4282 if (mLastHoverWindowHandle &&
4283 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4284 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004285 mLastHoverWindowHandle = nullptr;
4286 }
4287
Vishnu Nair958da932020-08-21 17:12:37 -07004288 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4289 if (focusedToken) {
4290 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4291 if (result != FocusResult::OK) {
4292 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4293 }
4294 }
4295
4296 std::optional<FocusRequest> focusRequest =
4297 getOptionalValueByKey(mPendingFocusRequests, displayId);
4298 if (focusRequest) {
4299 // If the window from the pending request is now visible, provide it focus.
4300 FocusResult result = handleFocusRequestLocked(*focusRequest);
4301 if (result != FocusResult::NOT_VISIBLE) {
4302 // Drop the request if we were able to change the focus or we cannot change
4303 // it for another reason.
4304 mPendingFocusRequests.erase(displayId);
4305 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004306 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004307
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004308 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4309 mTouchStatesByDisplay.find(displayId);
4310 if (stateIt != mTouchStatesByDisplay.end()) {
4311 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004312 for (size_t i = 0; i < state.windows.size();) {
4313 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004314 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004315 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004316 ALOGD("Touched window was removed: %s in display %" PRId32,
4317 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004318 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004319 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004320 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4321 if (touchedInputChannel != nullptr) {
4322 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4323 "touched window was removed");
4324 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004325 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004326 state.windows.erase(state.windows.begin() + i);
4327 } else {
4328 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004329 }
4330 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004331 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004332
Arthur Hung72d8dc32020-03-28 00:48:39 +00004333 // Release information for windows that are no longer present.
4334 // This ensures that unused input channels are released promptly.
4335 // Otherwise, they might stick around until the window handle is destroyed
4336 // which might not happen until the next GC.
4337 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004338 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004339 if (DEBUG_FOCUS) {
4340 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004341 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004342 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004343 // To avoid making too many calls into the compat framework, only
4344 // check for window flags when windows are going away.
4345 // TODO(b/157929241) : delete this. This is only needed temporarily
4346 // in order to gather some data about the flag usage
4347 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4348 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4349 oldWindowHandle->getName().c_str());
4350 if (mCompatService != nullptr) {
4351 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4352 oldWindowHandle->getInfo()->ownerUid);
4353 }
4354 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004355 }
chaviw291d88a2019-02-14 10:33:58 -08004356 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004357}
4358
4359void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004360 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004361 if (DEBUG_FOCUS) {
4362 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4363 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4364 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004365 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004366 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004367
Chris Yea209fde2020-07-22 13:54:51 -07004368 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004369 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004370
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004371 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4372 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004373 }
4374
Chris Yea209fde2020-07-22 13:54:51 -07004375 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004376 if (inputApplicationHandle != nullptr) {
4377 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4378 } else {
4379 mFocusedApplicationHandlesByDisplay.erase(displayId);
4380 }
4381
4382 // No matter what the old focused application was, stop waiting on it because it is
4383 // no longer focused.
4384 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004385 } // release lock
4386
4387 // Wake up poll loop since it may need to make new input dispatching choices.
4388 mLooper->wake();
4389}
4390
Tiger Huang721e26f2018-07-24 22:26:19 +08004391/**
4392 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4393 * the display not specified.
4394 *
4395 * We track any unreleased events for each window. If a window loses the ability to receive the
4396 * released event, we will send a cancel event to it. So when the focused display is changed, we
4397 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4398 * display. The display-specified events won't be affected.
4399 */
4400void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004401 if (DEBUG_FOCUS) {
4402 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4403 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004404 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004405 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004406
4407 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004408 sp<IBinder> oldFocusedWindowToken =
4409 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4410 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004411 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004412 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004413 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004414 CancelationOptions
4415 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4416 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004417 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004418 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4419 }
4420 }
4421 mFocusedDisplayId = displayId;
4422
Chris Ye3c2d6f52020-08-09 10:39:48 -07004423 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004424 sp<IBinder> newFocusedWindowToken =
4425 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4426 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004427
Vishnu Nairad321cd2020-08-20 16:40:21 -07004428 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004429 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004430 if (!mFocusedWindowTokenByDisplay.empty()) {
4431 ALOGE("But another display has a focused window\n%s",
4432 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004433 }
4434 }
4435 }
4436
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004437 if (DEBUG_FOCUS) {
4438 logDispatchStateLocked();
4439 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004440 } // release lock
4441
4442 // Wake up poll loop since it may need to make new input dispatching choices.
4443 mLooper->wake();
4444}
4445
Michael Wrightd02c5b62014-02-10 15:10:22 -08004446void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004447 if (DEBUG_FOCUS) {
4448 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4449 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004450
4451 bool changed;
4452 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004453 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004454
4455 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4456 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004457 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004458 }
4459
4460 if (mDispatchEnabled && !enabled) {
4461 resetAndDropEverythingLocked("dispatcher is being disabled");
4462 }
4463
4464 mDispatchEnabled = enabled;
4465 mDispatchFrozen = frozen;
4466 changed = true;
4467 } else {
4468 changed = false;
4469 }
4470
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004471 if (DEBUG_FOCUS) {
4472 logDispatchStateLocked();
4473 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004474 } // release lock
4475
4476 if (changed) {
4477 // Wake up poll loop since it may need to make new input dispatching choices.
4478 mLooper->wake();
4479 }
4480}
4481
4482void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004483 if (DEBUG_FOCUS) {
4484 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4485 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004486
4487 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004488 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004489
4490 if (mInputFilterEnabled == enabled) {
4491 return;
4492 }
4493
4494 mInputFilterEnabled = enabled;
4495 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4496 } // release lock
4497
4498 // Wake up poll loop since there might be work to do to drop everything.
4499 mLooper->wake();
4500}
4501
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004502void InputDispatcher::setInTouchMode(bool inTouchMode) {
4503 std::scoped_lock lock(mLock);
4504 mInTouchMode = inTouchMode;
4505}
4506
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004507void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4508 if (opacity < 0 || opacity > 1) {
4509 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4510 return;
4511 }
4512
4513 std::scoped_lock lock(mLock);
4514 mMaximumObscuringOpacityForTouch = opacity;
4515}
4516
4517void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4518 std::scoped_lock lock(mLock);
4519 mBlockUntrustedTouchesMode = mode;
4520}
4521
chaviwfbe5d9c2018-12-26 12:23:37 -08004522bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4523 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004524 if (DEBUG_FOCUS) {
4525 ALOGD("Trivial transfer to same window.");
4526 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004527 return true;
4528 }
4529
Michael Wrightd02c5b62014-02-10 15:10:22 -08004530 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004531 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004532
chaviwfbe5d9c2018-12-26 12:23:37 -08004533 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4534 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004535 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004536 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004537 return false;
4538 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004539 if (DEBUG_FOCUS) {
4540 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4541 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4542 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004543 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004544 if (DEBUG_FOCUS) {
4545 ALOGD("Cannot transfer focus because windows are on different displays.");
4546 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004547 return false;
4548 }
4549
4550 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004551 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4552 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004553 for (size_t i = 0; i < state.windows.size(); i++) {
4554 const TouchedWindow& touchedWindow = state.windows[i];
4555 if (touchedWindow.windowHandle == fromWindowHandle) {
4556 int32_t oldTargetFlags = touchedWindow.targetFlags;
4557 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004558
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004559 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004560
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004561 int32_t newTargetFlags = oldTargetFlags &
4562 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4563 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004564 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004565
Jeff Brownf086ddb2014-02-11 14:28:48 -08004566 found = true;
4567 goto Found;
4568 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004569 }
4570 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004571 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004572
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004573 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004574 if (DEBUG_FOCUS) {
4575 ALOGD("Focus transfer failed because from window did not have focus.");
4576 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004577 return false;
4578 }
4579
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004580 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4581 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004582 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004583 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004584 CancelationOptions
4585 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4586 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004587 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004588 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589 }
4590
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004591 if (DEBUG_FOCUS) {
4592 logDispatchStateLocked();
4593 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004594 } // release lock
4595
4596 // Wake up poll loop since it may need to make new input dispatching choices.
4597 mLooper->wake();
4598 return true;
4599}
4600
4601void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004602 if (DEBUG_FOCUS) {
4603 ALOGD("Resetting and dropping all events (%s).", reason);
4604 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004605
4606 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4607 synthesizeCancelationEventsForAllConnectionsLocked(options);
4608
4609 resetKeyRepeatLocked();
4610 releasePendingEventLocked();
4611 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004612 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004613
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004614 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004615 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004616 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004617 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004618}
4619
4620void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004621 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004622 dumpDispatchStateLocked(dump);
4623
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004624 std::istringstream stream(dump);
4625 std::string line;
4626
4627 while (std::getline(stream, line, '\n')) {
4628 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004629 }
4630}
4631
Vishnu Nairad321cd2020-08-20 16:40:21 -07004632std::string InputDispatcher::dumpFocusedWindowsLocked() {
4633 if (mFocusedWindowTokenByDisplay.empty()) {
4634 return INDENT "FocusedWindows: <none>\n";
4635 }
4636
4637 std::string dump;
4638 dump += INDENT "FocusedWindows:\n";
4639 for (auto& it : mFocusedWindowTokenByDisplay) {
4640 const int32_t displayId = it.first;
4641 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4642 if (windowHandle) {
4643 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4644 windowHandle->getName().c_str());
4645 } else {
4646 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4647 " has focused token without a window'\n",
4648 displayId);
4649 }
4650 }
4651 return dump;
4652}
4653
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004654std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4655 if (mPendingFocusRequests.empty()) {
4656 return INDENT "mPendingFocusRequests: <none>\n";
4657 }
4658
4659 std::string dump;
4660 dump += INDENT "mPendingFocusRequests:\n";
4661 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4662 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4663 // try to resolve them to actual windows.
4664 std::string windowName = getConnectionNameLocked(focusRequest.token);
4665 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4666 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4667 displayId, windowName.c_str(), focusedWindowName.c_str());
4668 }
4669 return dump;
4670}
4671
Prabir Pradhan99987712020-11-10 18:43:05 -08004672std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4673 std::string dump;
4674
4675 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4676 toString(mFocusedWindowRequestedPointerCapture));
4677
4678 std::string windowName = "None";
4679 if (mWindowTokenWithPointerCapture) {
4680 const sp<InputWindowHandle> captureWindowHandle =
4681 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4682 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4683 : "token has capture without window";
4684 }
4685 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4686
4687 return dump;
4688}
4689
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004690void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004691 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4692 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4693 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004694 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004695
Tiger Huang721e26f2018-07-24 22:26:19 +08004696 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4697 dump += StringPrintf(INDENT "FocusedApplications:\n");
4698 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4699 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004700 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004701 const std::chrono::duration timeout =
4702 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004703 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004704 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004705 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004707 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004708 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004709 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004710
Vishnu Nairad321cd2020-08-20 16:40:21 -07004711 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004712 dump += dumpPendingFocusRequestsLocked();
Prabir Pradhan99987712020-11-10 18:43:05 -08004713 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004714
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004715 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004716 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004717 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4718 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004719 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004720 state.displayId, toString(state.down), toString(state.split),
4721 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004722 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004723 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004724 for (size_t i = 0; i < state.windows.size(); i++) {
4725 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004726 dump += StringPrintf(INDENT4
4727 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4728 i, touchedWindow.windowHandle->getName().c_str(),
4729 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004730 }
4731 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004732 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004733 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004734 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004735 dump += INDENT3 "Portal windows:\n";
4736 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004737 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004738 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4739 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004740 }
4741 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004742 }
4743 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004744 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004745 }
4746
Arthur Hungb92218b2018-08-14 12:00:21 +08004747 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004748 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004749 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004750 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004751 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004752 dump += INDENT2 "Windows:\n";
4753 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004754 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004755 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004756
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004757 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004758 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004759 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004760 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004761 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004762 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004763 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004764 i, windowInfo->name.c_str(), windowInfo->id,
4765 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004766 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004767 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004768 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004769 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004770 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004771 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004772 windowInfo->frameLeft, windowInfo->frameTop,
4773 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004774 windowInfo->globalScaleFactor,
4775 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004776 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004777 dump += StringPrintf(", inputFeatures=%s",
4778 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004779 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004780 "ms, trustedOverlay=%s, hasToken=%s, "
4781 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004782 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004783 millis(windowInfo->dispatchingTimeout),
4784 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004785 toString(windowInfo->token != nullptr),
4786 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004787 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004788 }
4789 } else {
4790 dump += INDENT2 "Windows: <none>\n";
4791 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004792 }
4793 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004794 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004795 }
4796
Michael Wright3dd60e22019-03-27 22:06:44 +00004797 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004798 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004799 const std::vector<Monitor>& monitors = it.second;
4800 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4801 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004802 }
4803 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004804 const std::vector<Monitor>& monitors = it.second;
4805 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4806 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004807 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004808 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004809 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004810 }
4811
4812 nsecs_t currentTime = now();
4813
4814 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004815 if (!mRecentQueue.empty()) {
4816 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004817 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004818 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004819 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004820 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004821 }
4822 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004823 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004824 }
4825
4826 // Dump event currently being dispatched.
4827 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004828 dump += INDENT "PendingEvent:\n";
4829 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004830 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004831 dump += StringPrintf(", age=%" PRId64 "ms\n",
4832 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004833 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004834 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004835 }
4836
4837 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004838 if (!mInboundQueue.empty()) {
4839 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004840 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004841 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004842 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004843 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004844 }
4845 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004846 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004847 }
4848
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004849 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004850 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004851 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4852 const KeyReplacement& replacement = pair.first;
4853 int32_t newKeyCode = pair.second;
4854 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004855 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004856 }
4857 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004858 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004859 }
4860
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004861 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004862 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004863 for (const auto& pair : mConnectionsByFd) {
4864 const sp<Connection>& connection = pair.second;
4865 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004866 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004867 pair.first, connection->getInputChannelName().c_str(),
4868 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004869 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004870
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004871 if (!connection->outboundQueue.empty()) {
4872 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4873 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004874 dump += dumpQueue(connection->outboundQueue, currentTime);
4875
Michael Wrightd02c5b62014-02-10 15:10:22 -08004876 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004877 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004878 }
4879
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004880 if (!connection->waitQueue.empty()) {
4881 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4882 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004883 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004884 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004885 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004886 }
4887 }
4888 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004889 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004890 }
4891
4892 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004893 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4894 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004895 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004896 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004897 }
4898
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004899 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004900 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4901 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4902 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004903}
4904
Michael Wright3dd60e22019-03-27 22:06:44 +00004905void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4906 const size_t numMonitors = monitors.size();
4907 for (size_t i = 0; i < numMonitors; i++) {
4908 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004909 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004910 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4911 dump += "\n";
4912 }
4913}
4914
Garfield Tan15601662020-09-22 15:32:38 -07004915base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4916 const std::string& name) {
4917#if DEBUG_CHANNEL_CREATION
4918 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004919#endif
4920
Garfield Tan15601662020-09-22 15:32:38 -07004921 std::shared_ptr<InputChannel> serverChannel;
4922 std::unique_ptr<InputChannel> clientChannel;
4923 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4924
4925 if (result) {
4926 return base::Error(result) << "Failed to open input channel pair with name " << name;
4927 }
4928
Michael Wrightd02c5b62014-02-10 15:10:22 -08004929 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004930 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004931 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004932
Garfield Tan15601662020-09-22 15:32:38 -07004933 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004934 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004935 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004936
Michael Wrightd02c5b62014-02-10 15:10:22 -08004937 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4938 } // release lock
4939
4940 // Wake the looper because some connections have changed.
4941 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004942 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004943}
4944
Garfield Tan15601662020-09-22 15:32:38 -07004945base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004946 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004947 std::shared_ptr<InputChannel> serverChannel;
4948 std::unique_ptr<InputChannel> clientChannel;
4949 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4950 if (result) {
4951 return base::Error(result) << "Failed to open input channel pair with name " << name;
4952 }
4953
Michael Wright3dd60e22019-03-27 22:06:44 +00004954 { // acquire lock
4955 std::scoped_lock _l(mLock);
4956
4957 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004958 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4959 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004960 }
4961
Garfield Tan15601662020-09-22 15:32:38 -07004962 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004963
Garfield Tan15601662020-09-22 15:32:38 -07004964 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004965 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004966 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004967
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004968 auto& monitorsByDisplay =
4969 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004970 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00004971
4972 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004973 }
Garfield Tan15601662020-09-22 15:32:38 -07004974
Michael Wright3dd60e22019-03-27 22:06:44 +00004975 // Wake the looper because some connections have changed.
4976 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004977 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004978}
4979
Garfield Tan15601662020-09-22 15:32:38 -07004980status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004981 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004982 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004983
Garfield Tan15601662020-09-22 15:32:38 -07004984 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004985 if (status) {
4986 return status;
4987 }
4988 } // release lock
4989
4990 // Wake the poll loop because removing the connection may have changed the current
4991 // synchronization state.
4992 mLooper->wake();
4993 return OK;
4994}
4995
Garfield Tan15601662020-09-22 15:32:38 -07004996status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
4997 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05004998 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004999 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005000 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005001 return BAD_VALUE;
5002 }
5003
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005004 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005005 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07005006
Michael Wrightd02c5b62014-02-10 15:10:22 -08005007 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005008 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005009 }
5010
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005011 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005012
5013 nsecs_t currentTime = now();
5014 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5015
5016 connection->status = Connection::STATUS_ZOMBIE;
5017 return OK;
5018}
5019
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005020void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5021 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5022 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005023}
5024
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005025void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005026 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005027 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005028 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005029 std::vector<Monitor>& monitors = it->second;
5030 const size_t numMonitors = monitors.size();
5031 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005032 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005033 monitors.erase(monitors.begin() + i);
5034 break;
5035 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005036 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005037 if (monitors.empty()) {
5038 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005039 } else {
5040 ++it;
5041 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005042 }
5043}
5044
Michael Wright3dd60e22019-03-27 22:06:44 +00005045status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5046 { // acquire lock
5047 std::scoped_lock _l(mLock);
5048 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5049
5050 if (!foundDisplayId) {
5051 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5052 return BAD_VALUE;
5053 }
5054 int32_t displayId = foundDisplayId.value();
5055
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005056 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5057 mTouchStatesByDisplay.find(displayId);
5058 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005059 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5060 return BAD_VALUE;
5061 }
5062
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005063 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00005064 std::optional<int32_t> foundDeviceId;
5065 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005066 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005067 foundDeviceId = state.deviceId;
5068 }
5069 }
5070 if (!foundDeviceId || !state.down) {
5071 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005072 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005073 return BAD_VALUE;
5074 }
5075 int32_t deviceId = foundDeviceId.value();
5076
5077 // Send cancel events to all the input channels we're stealing from.
5078 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005079 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005080 options.deviceId = deviceId;
5081 options.displayId = displayId;
5082 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005083 std::shared_ptr<InputChannel> channel =
5084 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005085 if (channel != nullptr) {
5086 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5087 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005088 }
5089 // Then clear the current touch state so we stop dispatching to them as well.
5090 state.filterNonMonitors();
5091 }
5092 return OK;
5093}
5094
Prabir Pradhan99987712020-11-10 18:43:05 -08005095void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5096 { // acquire lock
5097 std::scoped_lock _l(mLock);
5098 if (DEBUG_FOCUS) {
5099 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5100 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5101 windowHandle != nullptr ? windowHandle->getName().c_str()
5102 : "token without window");
5103 }
5104
5105 const sp<IBinder> focusedToken =
5106 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
5107 if (focusedToken != windowToken) {
5108 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5109 enabled ? "enable" : "disable");
5110 return;
5111 }
5112
5113 if (enabled == mFocusedWindowRequestedPointerCapture) {
5114 ALOGW("Ignoring request to %s Pointer Capture: "
5115 "window has %s requested pointer capture.",
5116 enabled ? "enable" : "disable", enabled ? "already" : "not");
5117 return;
5118 }
5119
5120 mFocusedWindowRequestedPointerCapture = enabled;
5121 setPointerCaptureLocked(enabled);
5122 } // release lock
5123
5124 // Wake the thread to process command entries.
5125 mLooper->wake();
5126}
5127
Michael Wright3dd60e22019-03-27 22:06:44 +00005128std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5129 const sp<IBinder>& token) {
5130 for (const auto& it : mGestureMonitorsByDisplay) {
5131 const std::vector<Monitor>& monitors = it.second;
5132 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005133 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005134 return it.first;
5135 }
5136 }
5137 }
5138 return std::nullopt;
5139}
5140
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005141sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005142 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005143 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005144 }
5145
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005146 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005147 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005148 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005149 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005150 }
5151 }
Robert Carr4e670e52018-08-15 13:26:12 -07005152
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005153 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005154}
5155
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005156std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5157 sp<Connection> connection = getConnectionLocked(connectionToken);
5158 if (connection == nullptr) {
5159 return "<nullptr>";
5160 }
5161 return connection->getInputChannelName();
5162}
5163
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005164void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005165 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005166 removeByValue(mConnectionsByFd, connection);
5167}
5168
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005169void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5170 const sp<Connection>& connection, uint32_t seq,
5171 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005172 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5173 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005174 commandEntry->connection = connection;
5175 commandEntry->eventTime = currentTime;
5176 commandEntry->seq = seq;
5177 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005178 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005179}
5180
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005181void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5182 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005183 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005184 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005185
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005186 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5187 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005188 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005189 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005190}
5191
Vishnu Nairad321cd2020-08-20 16:40:21 -07005192void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5193 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005194 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5195 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005196 commandEntry->oldToken = oldToken;
5197 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005198 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005199}
5200
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005201void InputDispatcher::onAnrLocked(const Connection& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005202 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5203 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005204 if (connection.waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005205 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005206 connection.inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005207 return;
5208 }
5209 /**
5210 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5211 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5212 * has changed. This could cause newer entries to time out before the already dispatched
5213 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5214 * processes the events linearly. So providing information about the oldest entry seems to be
5215 * most useful.
5216 */
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005217 DispatchEntry* oldestEntry = *connection.waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005218 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5219 std::string reason =
5220 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakoua72accd2020-09-22 21:43:09 -05005221 connection.inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005222 ns2ms(currentWait),
5223 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005224 sp<IBinder> connectionToken = connection.inputChannel->getConnectionToken();
5225 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005226
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005227 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5228 &InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible);
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005229 commandEntry->connectionToken = connectionToken;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005230 commandEntry->reason = std::move(reason);
5231 postCommandLocked(std::move(commandEntry));
5232}
5233
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005234void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5235 std::string reason =
5236 StringPrintf("%s does not have a focused window", application->getName().c_str());
5237 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005238
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005239 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5240 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5241 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005242 postCommandLocked(std::move(commandEntry));
5243}
5244
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005245void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5246 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5247 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5248 commandEntry->obscuringPackage = obscuringPackage;
5249 postCommandLocked(std::move(commandEntry));
5250}
5251
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005252void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5253 const std::string& reason) {
5254 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5255 updateLastAnrStateLocked(windowLabel, reason);
5256}
5257
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005258void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5259 const std::string& reason) {
5260 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005261 updateLastAnrStateLocked(windowLabel, reason);
5262}
5263
5264void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5265 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005266 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005267 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005268 struct tm tm;
5269 localtime_r(&t, &tm);
5270 char timestr[64];
5271 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005272 mLastAnrState.clear();
5273 mLastAnrState += INDENT "ANR:\n";
5274 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005275 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5276 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005277 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005278}
5279
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005280void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005281 mLock.unlock();
5282
5283 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5284
5285 mLock.lock();
5286}
5287
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005288void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005289 sp<Connection> connection = commandEntry->connection;
5290
5291 if (connection->status != Connection::STATUS_ZOMBIE) {
5292 mLock.unlock();
5293
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005294 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005295
5296 mLock.lock();
5297 }
5298}
5299
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005300void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005301 sp<IBinder> oldToken = commandEntry->oldToken;
5302 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005303 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005304 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005305 mLock.lock();
5306}
5307
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005308void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005309 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005310
5311 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5312
5313 mLock.lock();
5314}
5315
5316void InputDispatcher::doNotifyConnectionUnresponsiveLockedInterruptible(
5317 CommandEntry* commandEntry) {
5318 mLock.unlock();
5319
5320 mPolicy->notifyConnectionUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005321
5322 mLock.lock();
5323
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005324 // stop waking up for events in this connection, it is already not responding
5325 sp<Connection> connection = getConnectionLocked(commandEntry->connectionToken);
5326 if (connection == nullptr) {
5327 return;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005328 }
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005329 cancelEventsForAnrLocked(connection);
5330}
5331
5332void InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5333 mLock.unlock();
5334
5335 mPolicy->notifyConnectionResponsive(commandEntry->connectionToken);
5336
5337 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005338}
5339
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005340void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5341 mLock.unlock();
5342
5343 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5344
5345 mLock.lock();
5346}
5347
Michael Wrightd02c5b62014-02-10 15:10:22 -08005348void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5349 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005350 KeyEntry& entry = *(commandEntry->keyEntry);
5351 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005352
5353 mLock.unlock();
5354
Michael Wright2b3c3302018-03-02 17:19:13 +00005355 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005356 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005357 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005358 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5359 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005360 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005361 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005362
5363 mLock.lock();
5364
5365 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005366 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005367 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005368 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005369 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005370 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5371 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005372 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005373}
5374
chaviwfd6d3512019-03-25 13:23:49 -07005375void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5376 mLock.unlock();
5377 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5378 mLock.lock();
5379}
5380
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005381/**
5382 * Connection is responsive if it has no events in the waitQueue that are older than the
5383 * current time.
5384 */
5385static bool isConnectionResponsive(const Connection& connection) {
5386 const nsecs_t currentTime = now();
5387 for (const DispatchEntry* entry : connection.waitQueue) {
5388 if (entry->timeoutTime < currentTime) {
5389 return false;
5390 }
5391 }
5392 return true;
5393}
5394
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005395void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005396 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005397 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005398 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005399 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005400
5401 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005402 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005403 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005404 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005405 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005406 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005407 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005408 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005409 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5410 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005411 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005412 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005413
5414 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005415 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005416 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005417 restartEvent =
5418 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005419 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005420 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005421 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5422 handled);
5423 } else {
5424 restartEvent = false;
5425 }
5426
5427 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005428 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005429 // contents of the wait queue to have been drained, so we need to double-check
5430 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005431 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5432 if (dispatchEntryIt != connection->waitQueue.end()) {
5433 dispatchEntry = *dispatchEntryIt;
5434 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005435 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5436 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005437 if (!connection->responsive) {
5438 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005439 if (connection->responsive) {
5440 // The connection was unresponsive, and now it's responsive. Tell the policy
5441 // about it so that it can stop ANR.
5442 std::unique_ptr<CommandEntry> connectionResponsiveCommand =
5443 std::make_unique<CommandEntry>(
5444 &InputDispatcher::doNotifyConnectionResponsiveLockedInterruptible);
5445 connectionResponsiveCommand->connectionToken = connectionToken;
5446 postCommandLocked(std::move(connectionResponsiveCommand));
5447 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005448 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005449 traceWaitQueueLength(connection);
5450 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005451 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005452 traceOutboundQueueLength(connection);
5453 } else {
5454 releaseDispatchEntry(dispatchEntry);
5455 }
5456 }
5457
5458 // Start the next dispatch cycle for this connection.
5459 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005460}
5461
5462bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005463 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005464 KeyEntry& keyEntry, bool handled) {
5465 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005466 if (!handled) {
5467 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005468 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005469 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005470 return false;
5471 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005472
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005473 // Get the fallback key state.
5474 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005475 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005476 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005477 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005478 connection->inputState.removeFallbackKey(originalKeyCode);
5479 }
5480
5481 if (handled || !dispatchEntry->hasForegroundTarget()) {
5482 // If the application handles the original key for which we previously
5483 // generated a fallback or if the window is not a foreground window,
5484 // then cancel the associated fallback key, if any.
5485 if (fallbackKeyCode != -1) {
5486 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005487#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005488 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005489 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005490 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005491#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005492 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005493 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005494
5495 mLock.unlock();
5496
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005497 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005498 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005499
5500 mLock.lock();
5501
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005502 // Cancel the fallback key.
5503 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005504 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005505 "application handled the original non-fallback key "
5506 "or is no longer a foreground target, "
5507 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005508 options.keyCode = fallbackKeyCode;
5509 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005510 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005511 connection->inputState.removeFallbackKey(originalKeyCode);
5512 }
5513 } else {
5514 // If the application did not handle a non-fallback key, first check
5515 // that we are in a good state to perform unhandled key event processing
5516 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005517 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005518 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005519#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005520 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005521 "since this is not an initial down. "
5522 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005523 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005524#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005525 return false;
5526 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005527
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005528 // Dispatch the unhandled key to the policy.
5529#if DEBUG_OUTBOUND_EVENT_DETAILS
5530 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005531 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005532 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005533#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005534 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005535
5536 mLock.unlock();
5537
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005538 bool fallback =
5539 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005540 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005541
5542 mLock.lock();
5543
5544 if (connection->status != Connection::STATUS_NORMAL) {
5545 connection->inputState.removeFallbackKey(originalKeyCode);
5546 return false;
5547 }
5548
5549 // Latch the fallback keycode for this key on an initial down.
5550 // The fallback keycode cannot change at any other point in the lifecycle.
5551 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005552 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005553 fallbackKeyCode = event.getKeyCode();
5554 } else {
5555 fallbackKeyCode = AKEYCODE_UNKNOWN;
5556 }
5557 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5558 }
5559
5560 ALOG_ASSERT(fallbackKeyCode != -1);
5561
5562 // Cancel the fallback key if the policy decides not to send it anymore.
5563 // We will continue to dispatch the key to the policy but we will no
5564 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005565 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5566 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005567#if DEBUG_OUTBOUND_EVENT_DETAILS
5568 if (fallback) {
5569 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005570 "as a fallback for %d, but on the DOWN it had requested "
5571 "to send %d instead. Fallback canceled.",
5572 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005573 } else {
5574 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005575 "but on the DOWN it had requested to send %d. "
5576 "Fallback canceled.",
5577 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005578 }
5579#endif
5580
5581 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5582 "canceling fallback, policy no longer desires it");
5583 options.keyCode = fallbackKeyCode;
5584 synthesizeCancelationEventsForConnectionLocked(connection, options);
5585
5586 fallback = false;
5587 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005588 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005589 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005590 }
5591 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005592
5593#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005594 {
5595 std::string msg;
5596 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5597 connection->inputState.getFallbackKeys();
5598 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005599 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005600 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005601 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005602 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005603 }
5604#endif
5605
5606 if (fallback) {
5607 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005608 keyEntry.eventTime = event.getEventTime();
5609 keyEntry.deviceId = event.getDeviceId();
5610 keyEntry.source = event.getSource();
5611 keyEntry.displayId = event.getDisplayId();
5612 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5613 keyEntry.keyCode = fallbackKeyCode;
5614 keyEntry.scanCode = event.getScanCode();
5615 keyEntry.metaState = event.getMetaState();
5616 keyEntry.repeatCount = event.getRepeatCount();
5617 keyEntry.downTime = event.getDownTime();
5618 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005619
5620#if DEBUG_OUTBOUND_EVENT_DETAILS
5621 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005622 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005623 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005624#endif
5625 return true; // restart the event
5626 } else {
5627#if DEBUG_OUTBOUND_EVENT_DETAILS
5628 ALOGD("Unhandled key event: No fallback key.");
5629#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005630
5631 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005632 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005633 }
5634 }
5635 return false;
5636}
5637
5638bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005639 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005640 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005641 return false;
5642}
5643
5644void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5645 mLock.unlock();
5646
5647 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5648
5649 mLock.lock();
5650}
5651
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005652KeyEvent InputDispatcher::createKeyEvent(const KeyEntry& entry) {
5653 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08005654 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08005655 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
5656 entry.repeatCount, entry.downTime, entry.eventTime);
Siarhei Vishniakou9757f782019-10-29 12:53:08 -07005657 return event;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005658}
5659
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005660void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5661 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005662 // TODO Write some statistics about how long we spend waiting.
5663}
5664
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005665/**
5666 * Report the touch event latency to the statsd server.
5667 * Input events are reported for statistics if:
5668 * - This is a touchscreen event
5669 * - InputFilter is not enabled
5670 * - Event is not injected or synthesized
5671 *
5672 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5673 * from getting aggregated with the "old" data.
5674 */
5675void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5676 REQUIRES(mLock) {
5677 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5678 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5679 if (!reportForStatistics) {
5680 return;
5681 }
5682
5683 if (mTouchStatistics.shouldReport()) {
5684 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5685 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5686 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5687 mTouchStatistics.reset();
5688 }
5689 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5690 mTouchStatistics.addValue(latencyMicros);
5691}
5692
Michael Wrightd02c5b62014-02-10 15:10:22 -08005693void InputDispatcher::traceInboundQueueLengthLocked() {
5694 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005695 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005696 }
5697}
5698
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005699void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005700 if (ATRACE_ENABLED()) {
5701 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005702 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005703 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005704 }
5705}
5706
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005707void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005708 if (ATRACE_ENABLED()) {
5709 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005710 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005711 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005712 }
5713}
5714
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005715void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005716 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005717
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005718 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005719 dumpDispatchStateLocked(dump);
5720
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005721 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005722 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005723 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005724 }
5725}
5726
5727void InputDispatcher::monitor() {
5728 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005729 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005730 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005731 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005732}
5733
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005734/**
5735 * Wake up the dispatcher and wait until it processes all events and commands.
5736 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5737 * this method can be safely called from any thread, as long as you've ensured that
5738 * the work you are interested in completing has already been queued.
5739 */
5740bool InputDispatcher::waitForIdle() {
5741 /**
5742 * Timeout should represent the longest possible time that a device might spend processing
5743 * events and commands.
5744 */
5745 constexpr std::chrono::duration TIMEOUT = 100ms;
5746 std::unique_lock lock(mLock);
5747 mLooper->wake();
5748 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5749 return result == std::cv_status::no_timeout;
5750}
5751
Vishnu Naire798b472020-07-23 13:52:21 -07005752/**
5753 * Sets focus to the window identified by the token. This must be called
5754 * after updating any input window handles.
5755 *
5756 * Params:
5757 * request.token - input channel token used to identify the window that should gain focus.
5758 * request.focusedToken - the token that the caller expects currently to be focused. If the
5759 * specified token does not match the currently focused window, this request will be dropped.
5760 * If the specified focused token matches the currently focused window, the call will succeed.
5761 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5762 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5763 * when requesting the focus change. This determines which request gets
5764 * precedence if there is a focus change request from another source such as pointer down.
5765 */
Vishnu Nair958da932020-08-21 17:12:37 -07005766void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5767 { // acquire lock
5768 std::scoped_lock _l(mLock);
5769
5770 const int32_t displayId = request.displayId;
5771 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5772 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5773 ALOGD_IF(DEBUG_FOCUS,
5774 "setFocusedWindow on display %" PRId32
5775 " ignored, reason: focusedToken is not focused",
5776 displayId);
5777 return;
5778 }
5779
5780 mPendingFocusRequests.erase(displayId);
5781 FocusResult result = handleFocusRequestLocked(request);
5782 if (result == FocusResult::NOT_VISIBLE) {
5783 // The requested window is not currently visible. Wait for the window to become visible
5784 // and then provide it focus. This is to handle situations where a user action triggers
5785 // a new window to appear. We want to be able to queue any key events after the user
5786 // action and deliver it to the newly focused window. In order for this to happen, we
5787 // take focus from the currently focused window so key events can be queued.
5788 ALOGD_IF(DEBUG_FOCUS,
5789 "setFocusedWindow on display %" PRId32
5790 " pending, reason: window is not visible",
5791 displayId);
5792 mPendingFocusRequests[displayId] = request;
5793 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5794 "setFocusedWindow_AwaitingWindowVisibility");
5795 } else if (result != FocusResult::OK) {
5796 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5797 typeToString(result));
5798 }
5799 } // release lock
5800 // Wake up poll loop since it may need to make new input dispatching choices.
5801 mLooper->wake();
5802}
5803
5804InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5805 const FocusRequest& request) {
5806 const int32_t displayId = request.displayId;
5807 const sp<IBinder> newFocusedToken = request.token;
5808 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5809
5810 if (oldFocusedToken == request.token) {
5811 ALOGD_IF(DEBUG_FOCUS,
5812 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5813 displayId);
5814 return FocusResult::OK;
5815 }
5816
5817 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5818 if (result != FocusResult::OK) {
5819 return result;
5820 }
5821
5822 std::string_view reason =
5823 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5824 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5825 return FocusResult::OK;
5826}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005827
Vishnu Nairad321cd2020-08-20 16:40:21 -07005828void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5829 const sp<IBinder>& newFocusedToken, int32_t displayId,
5830 std::string_view reason) {
5831 if (oldFocusedToken) {
5832 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005833 if (focusedInputChannel) {
5834 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5835 "focus left window");
5836 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005837 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005838 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005839 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005840 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005841 if (newFocusedToken) {
5842 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5843 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005844 }
5845
Prabir Pradhan99987712020-11-10 18:43:05 -08005846 // If a window has pointer capture, then it must have focus. We need to ensure that this
5847 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5848 // If the window loses focus before it loses pointer capture, then the window can be in a state
5849 // where it has pointer capture but not focus, violating the contract. Therefore we must
5850 // dispatch the pointer capture event before the focus event. Since focus events are added to
5851 // the front of the queue (above), we add the pointer capture event to the front of the queue
5852 // after the focus events are added. This ensures the pointer capture event ends up at the
5853 // front.
5854 disablePointerCaptureForcedLocked();
5855
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005856 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005857 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005858 }
5859}
Vishnu Nair958da932020-08-21 17:12:37 -07005860
Prabir Pradhan99987712020-11-10 18:43:05 -08005861void InputDispatcher::disablePointerCaptureForcedLocked() {
5862 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5863 return;
5864 }
5865
5866 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5867
5868 if (mFocusedWindowRequestedPointerCapture) {
5869 mFocusedWindowRequestedPointerCapture = false;
5870 setPointerCaptureLocked(false);
5871 }
5872
5873 if (!mWindowTokenWithPointerCapture) {
5874 // No need to send capture changes because no window has capture.
5875 return;
5876 }
5877
5878 if (mPendingEvent != nullptr) {
5879 // Move the pending event to the front of the queue. This will give the chance
5880 // for the pending event to be dropped if it is a captured event.
5881 mInboundQueue.push_front(mPendingEvent);
5882 mPendingEvent = nullptr;
5883 }
5884
5885 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5886 false /* hasCapture */);
5887 mInboundQueue.push_front(std::move(entry));
5888}
5889
Vishnu Nair958da932020-08-21 17:12:37 -07005890/**
5891 * Checks if the window token can be focused on a display. The token can be focused if there is
5892 * at least one window handle that is visible with the same token and all window handles with the
5893 * same token are focusable.
5894 *
5895 * In the case of mirroring, two windows may share the same window token and their visibility
5896 * might be different. Example, the mirrored window can cover the window its mirroring. However,
5897 * we expect the focusability of the windows to match since its hard to reason why one window can
5898 * receive focus events and the other cannot when both are backed by the same input channel.
5899 */
5900InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
5901 int32_t displayId) const {
5902 bool allWindowsAreFocusable = true;
5903 bool visibleWindowFound = false;
5904 bool windowFound = false;
5905 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
5906 if (window->getToken() != token) {
5907 continue;
5908 }
5909 windowFound = true;
5910 if (window->getInfo()->visible) {
5911 // Check if at least a single window is visible.
5912 visibleWindowFound = true;
5913 }
5914 if (!window->getInfo()->focusable) {
5915 // Check if all windows with the window token are focusable.
5916 allWindowsAreFocusable = false;
5917 break;
5918 }
5919 }
5920
5921 if (!windowFound) {
5922 return FocusResult::NO_WINDOW;
5923 }
5924 if (!allWindowsAreFocusable) {
5925 return FocusResult::NOT_FOCUSABLE;
5926 }
5927 if (!visibleWindowFound) {
5928 return FocusResult::NOT_VISIBLE;
5929 }
5930
5931 return FocusResult::OK;
5932}
Prabir Pradhan99987712020-11-10 18:43:05 -08005933
5934void InputDispatcher::setPointerCaptureLocked(bool enabled) {
5935 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5936 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
5937 commandEntry->enabled = enabled;
5938 postCommandLocked(std::move(commandEntry));
5939}
5940
5941void InputDispatcher::doSetPointerCaptureLockedInterruptible(
5942 android::inputdispatcher::CommandEntry* commandEntry) {
5943 mLock.unlock();
5944
5945 mPolicy->setPointerCapture(commandEntry->enabled);
5946
5947 mLock.lock();
5948}
5949
Garfield Tane84e6f92019-08-29 17:28:41 -07005950} // namespace android::inputdispatcher