blob: cf901e70cceb84e3c86ea4ec99f1882daee76aa7 [file] [log] [blame]
Michael Wrightd02c5b62014-02-10 15:10:22 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputDispatcher"
18#define ATRACE_TAG ATRACE_TAG_INPUT
19
John Recke0710582019-09-26 13:46:12 -070020#define LOG_NDEBUG 1
Michael Wrightd02c5b62014-02-10 15:10:22 -080021
22// Log detailed debug messages about each inbound event notification to the dispatcher.
23#define DEBUG_INBOUND_EVENT_DETAILS 0
24
25// Log detailed debug messages about each outbound event processed by the dispatcher.
26#define DEBUG_OUTBOUND_EVENT_DETAILS 0
27
28// Log debug messages about the dispatch cycle.
29#define DEBUG_DISPATCH_CYCLE 0
30
Garfield Tan15601662020-09-22 15:32:38 -070031// Log debug messages about channel creation
32#define DEBUG_CHANNEL_CREATION 0
Michael Wrightd02c5b62014-02-10 15:10:22 -080033
34// Log debug messages about input event injection.
35#define DEBUG_INJECTION 0
36
37// Log debug messages about input focus tracking.
Siarhei Vishniakou86587282019-09-09 18:20:15 +010038static constexpr bool DEBUG_FOCUS = false;
Michael Wrightd02c5b62014-02-10 15:10:22 -080039
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +000040// Log debug messages about touch occlusion
41// STOPSHIP(b/169067926): Set to false
42static constexpr bool DEBUG_TOUCH_OCCLUSION = true;
43
Michael Wrightd02c5b62014-02-10 15:10:22 -080044// Log debug messages about the app switch latency optimization.
45#define DEBUG_APP_SWITCH 0
46
47// Log debug messages about hover events.
48#define DEBUG_HOVER 0
49
Michael Wright2b3c3302018-03-02 17:19:13 +000050#include <android-base/chrono_utils.h>
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080051#include <android-base/stringprintf.h>
Siarhei Vishniakou70622952020-07-30 11:17:23 -050052#include <android/os/IInputConstants.h>
Robert Carr4e670e52018-08-15 13:26:12 -070053#include <binder/Binder.h>
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100054#include <binder/IServiceManager.h>
55#include <com/android/internal/compat/IPlatformCompatNative.h>
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -080056#include <input/InputDevice.h>
Michael Wright44753b12020-07-08 13:48:11 +010057#include <input/InputWindow.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070058#include <log/log.h>
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +000059#include <log/log_event_list.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070060#include <powermanager/PowerManager.h>
Michael Wright44753b12020-07-08 13:48:11 +010061#include <statslog.h>
62#include <unistd.h>
Garfield Tan0fc2fa72019-08-29 17:22:15 -070063#include <utils/Trace.h>
Michael Wrightd02c5b62014-02-10 15:10:22 -080064
Michael Wright44753b12020-07-08 13:48:11 +010065#include <cerrno>
66#include <cinttypes>
67#include <climits>
68#include <cstddef>
69#include <ctime>
70#include <queue>
71#include <sstream>
72
73#include "Connection.h"
Chris Yef59a2f42020-10-16 12:55:26 -070074#include "InputDispatcher.h"
Michael Wright44753b12020-07-08 13:48:11 +010075
Michael Wrightd02c5b62014-02-10 15:10:22 -080076#define INDENT " "
77#define INDENT2 " "
78#define INDENT3 " "
79#define INDENT4 " "
80
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080081using android::base::StringPrintf;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080082using android::os::BlockUntrustedTouchesMode;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100083using android::os::IInputConstants;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -080084using android::os::InputEventInjectionResult;
85using android::os::InputEventInjectionSync;
Siarhei Vishniakou2508b872020-12-03 16:33:53 -100086using com::android::internal::compat::IPlatformCompatNative;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -080087
Garfield Tane84e6f92019-08-29 17:28:41 -070088namespace android::inputdispatcher {
Michael Wrightd02c5b62014-02-10 15:10:22 -080089
90// Default input dispatching timeout if there is no focused application or paused window
91// from which to determine an appropriate dispatching timeout.
Siarhei Vishniakou70622952020-07-30 11:17:23 -050092constexpr std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT =
93 std::chrono::milliseconds(android::os::IInputConstants::DEFAULT_DISPATCHING_TIMEOUT_MILLIS);
Michael Wrightd02c5b62014-02-10 15:10:22 -080094
95// Amount of time to allow for all pending events to be processed when an app switch
96// key is on the way. This is used to preempt input dispatch and drop input events
97// when an application takes too long to respond and the user has pressed an app switch key.
Michael Wright2b3c3302018-03-02 17:19:13 +000098constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
Michael Wrightd02c5b62014-02-10 15:10:22 -080099
100// Amount of time to allow for an event to be dispatched (measured since its eventTime)
101// before considering it stale and dropping it.
Michael Wright2b3c3302018-03-02 17:19:13 +0000102constexpr nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
Michael Wrightd02c5b62014-02-10 15:10:22 -0800103
Michael Wrightd02c5b62014-02-10 15:10:22 -0800104// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
Michael Wright2b3c3302018-03-02 17:19:13 +0000105constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
106
107// Log a warning when an interception call takes longer than this to process.
108constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800109
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700110// Additional key latency in case a connection is still processing some motion events.
111// This will help with the case when a user touched a button that opens a new window,
112// and gives us the chance to dispatch the key to this new window.
113constexpr std::chrono::nanoseconds KEY_WAITING_FOR_EVENTS_TIMEOUT = 500ms;
114
Michael Wrightd02c5b62014-02-10 15:10:22 -0800115// Number of recent events to keep for debugging purposes.
Michael Wright2b3c3302018-03-02 17:19:13 +0000116constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
117
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +0000118// Event log tags. See EventLogTags.logtags for reference
119constexpr int LOGTAG_INPUT_INTERACTION = 62000;
120constexpr int LOGTAG_INPUT_FOCUS = 62001;
121
Michael Wrightd02c5b62014-02-10 15:10:22 -0800122static inline nsecs_t now() {
123 return systemTime(SYSTEM_TIME_MONOTONIC);
124}
125
126static inline const char* toString(bool value) {
127 return value ? "true" : "false";
128}
129
130static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700131 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
132 AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800133}
134
135static bool isValidKeyAction(int32_t action) {
136 switch (action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700137 case AKEY_EVENT_ACTION_DOWN:
138 case AKEY_EVENT_ACTION_UP:
139 return true;
140 default:
141 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800142 }
143}
144
145static bool validateKeyEvent(int32_t action) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700146 if (!isValidKeyAction(action)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800147 ALOGE("Key event has invalid action code 0x%x", action);
148 return false;
149 }
150 return true;
151}
152
Michael Wright7b159c92015-05-14 14:48:03 +0100153static bool isValidMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800154 switch (action & AMOTION_EVENT_ACTION_MASK) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700155 case AMOTION_EVENT_ACTION_DOWN:
156 case AMOTION_EVENT_ACTION_UP:
157 case AMOTION_EVENT_ACTION_CANCEL:
158 case AMOTION_EVENT_ACTION_MOVE:
159 case AMOTION_EVENT_ACTION_OUTSIDE:
160 case AMOTION_EVENT_ACTION_HOVER_ENTER:
161 case AMOTION_EVENT_ACTION_HOVER_MOVE:
162 case AMOTION_EVENT_ACTION_HOVER_EXIT:
163 case AMOTION_EVENT_ACTION_SCROLL:
164 return true;
165 case AMOTION_EVENT_ACTION_POINTER_DOWN:
166 case AMOTION_EVENT_ACTION_POINTER_UP: {
167 int32_t index = getMotionEventActionPointerIndex(action);
168 return index >= 0 && index < pointerCount;
169 }
170 case AMOTION_EVENT_ACTION_BUTTON_PRESS:
171 case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
172 return actionButton != 0;
173 default:
174 return false;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800175 }
176}
177
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500178static int64_t millis(std::chrono::nanoseconds t) {
179 return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
180}
181
Michael Wright7b159c92015-05-14 14:48:03 +0100182static bool validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700183 const PointerProperties* pointerProperties) {
184 if (!isValidMotionAction(action, actionButton, pointerCount)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800185 ALOGE("Motion event has invalid action code 0x%x", action);
186 return false;
187 }
188 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
Narayan Kamath37764c72014-03-27 14:21:09 +0000189 ALOGE("Motion event has invalid pointer count %zu; value must be between 1 and %d.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700190 pointerCount, MAX_POINTERS);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800191 return false;
192 }
193 BitSet32 pointerIdBits;
194 for (size_t i = 0; i < pointerCount; i++) {
195 int32_t id = pointerProperties[i].id;
196 if (id < 0 || id > MAX_POINTER_ID) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700197 ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", id,
198 MAX_POINTER_ID);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800199 return false;
200 }
201 if (pointerIdBits.hasBit(id)) {
202 ALOGE("Motion event has duplicate pointer id %d", id);
203 return false;
204 }
205 pointerIdBits.markBit(id);
206 }
207 return true;
208}
209
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000210static std::string dumpRegion(const Region& region) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800211 if (region.isEmpty()) {
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000212 return "<empty>";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800213 }
214
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000215 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800216 bool first = true;
217 Region::const_iterator cur = region.begin();
218 Region::const_iterator const tail = region.end();
219 while (cur != tail) {
220 if (first) {
221 first = false;
222 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800223 dump += "|";
Michael Wrightd02c5b62014-02-10 15:10:22 -0800224 }
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800225 dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800226 cur++;
227 }
Bernardo Rufino53fc31e2020-11-03 11:01:07 +0000228 return dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800229}
230
Siarhei Vishniakou14411c92020-09-18 21:15:05 -0500231static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
232 constexpr size_t maxEntries = 50; // max events to print
233 constexpr size_t skipBegin = maxEntries / 2;
234 const size_t skipEnd = queue.size() - maxEntries / 2;
235 // skip from maxEntries / 2 ... size() - maxEntries/2
236 // only print from 0 .. skipBegin and then from skipEnd .. size()
237
238 std::string dump;
239 for (size_t i = 0; i < queue.size(); i++) {
240 const DispatchEntry& entry = *queue[i];
241 if (i >= skipBegin && i < skipEnd) {
242 dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
243 i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
244 continue;
245 }
246 dump.append(INDENT4);
247 dump += entry.eventEntry->getDescription();
248 dump += StringPrintf(", seq=%" PRIu32
249 ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
250 entry.seq, entry.targetFlags, entry.resolvedAction,
251 ns2ms(currentTime - entry.eventEntry->eventTime));
252 if (entry.deliveryTime != 0) {
253 // This entry was delivered, so add information on how long we've been waiting
254 dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
255 }
256 dump.append("\n");
257 }
258 return dump;
259}
260
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700261/**
262 * Find the entry in std::unordered_map by key, and return it.
263 * If the entry is not found, return a default constructed entry.
264 *
265 * Useful when the entries are vectors, since an empty vector will be returned
266 * if the entry is not found.
267 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
268 */
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700269template <typename K, typename V>
270static V getValueByKey(const std::unordered_map<K, V>& map, K key) {
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -0700271 auto it = map.find(key);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700272 return it != map.end() ? it->second : V{};
Tiger Huang721e26f2018-07-24 22:26:19 +0800273}
274
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700275/**
276 * Find the entry in std::unordered_map by value, and remove it.
277 * If more than one entry has the same value, then all matching
278 * key-value pairs will be removed.
279 *
280 * Return true if at least one value has been removed.
281 */
282template <typename K, typename V>
283static bool removeByValue(std::unordered_map<K, V>& map, const V& value) {
284 bool removed = false;
285 for (auto it = map.begin(); it != map.end();) {
286 if (it->second == value) {
287 it = map.erase(it);
288 removed = true;
289 } else {
290 it++;
291 }
292 }
293 return removed;
294}
Michael Wrightd02c5b62014-02-10 15:10:22 -0800295
Vishnu Nair958da932020-08-21 17:12:37 -0700296/**
297 * Find the entry in std::unordered_map by key and return the value as an optional.
298 */
299template <typename K, typename V>
300static std::optional<V> getOptionalValueByKey(const std::unordered_map<K, V>& map, K key) {
301 auto it = map.find(key);
302 return it != map.end() ? std::optional<V>{it->second} : std::nullopt;
303}
304
chaviwaf87b3e2019-10-01 16:59:28 -0700305static bool haveSameToken(const sp<InputWindowHandle>& first, const sp<InputWindowHandle>& second) {
306 if (first == second) {
307 return true;
308 }
309
310 if (first == nullptr || second == nullptr) {
311 return false;
312 }
313
314 return first->getToken() == second->getToken();
315}
316
Siarhei Vishniakouadfd4fa2019-12-20 11:02:58 -0800317static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
318 return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
319}
320
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000321static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700322 std::shared_ptr<EventEntry> eventEntry,
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000323 int32_t inputTargetFlags) {
yunho.shinf4a80b82020-11-16 21:13:57 +0900324 if (eventEntry->type == EventEntry::Type::MOTION) {
325 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
326 if (motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) {
327 const ui::Transform identityTransform;
328 // Use identity transform for joystick events events because they don't depend on
329 // the window info
330 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
331 1.0f /*globalScaleFactor*/);
332 }
333 }
334
chaviw1ff3d1e2020-07-01 15:53:47 -0700335 if (inputTarget.useDefaultPointerTransform()) {
336 const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700337 return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
chaviw1ff3d1e2020-07-01 15:53:47 -0700338 inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000339 }
340
341 ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
342 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
343
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700344 std::vector<PointerCoords> pointerCoords;
345 pointerCoords.resize(motionEntry.pointerCount);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000346
347 // Use the first pointer information to normalize all other pointers. This could be any pointer
348 // as long as all other pointers are normalized to the same value and the final DispatchEntry
chaviw1ff3d1e2020-07-01 15:53:47 -0700349 // uses the transform for the normalized pointer.
350 const ui::Transform& firstPointerTransform =
351 inputTarget.pointerTransforms[inputTarget.pointerIds.firstMarkedBit()];
352 ui::Transform inverseFirstTransform = firstPointerTransform.inverse();
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000353
354 // Iterate through all pointers in the event to normalize against the first.
355 for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
356 const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
357 uint32_t pointerId = uint32_t(pointerProperties.id);
chaviw1ff3d1e2020-07-01 15:53:47 -0700358 const ui::Transform& currTransform = inputTarget.pointerTransforms[pointerId];
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000359
360 pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
chaviw1ff3d1e2020-07-01 15:53:47 -0700361 // First, apply the current pointer's transform to update the coordinates into
362 // window space.
363 pointerCoords[pointerIndex].transform(currTransform);
364 // Next, apply the inverse transform of the normalized coordinates so the
365 // current coordinates are transformed into the normalized coordinate space.
366 pointerCoords[pointerIndex].transform(inverseFirstTransform);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000367 }
368
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700369 std::unique_ptr<MotionEntry> combinedMotionEntry =
370 std::make_unique<MotionEntry>(motionEntry.id, motionEntry.eventTime,
371 motionEntry.deviceId, motionEntry.source,
372 motionEntry.displayId, motionEntry.policyFlags,
373 motionEntry.action, motionEntry.actionButton,
374 motionEntry.flags, motionEntry.metaState,
375 motionEntry.buttonState, motionEntry.classification,
376 motionEntry.edgeFlags, motionEntry.xPrecision,
377 motionEntry.yPrecision, motionEntry.xCursorPosition,
378 motionEntry.yCursorPosition, motionEntry.downTime,
379 motionEntry.pointerCount, motionEntry.pointerProperties,
380 pointerCoords.data(), 0 /* xOffset */, 0 /* yOffset */);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000381
382 if (motionEntry.injectionState) {
383 combinedMotionEntry->injectionState = motionEntry.injectionState;
384 combinedMotionEntry->injectionState->refCount += 1;
385 }
386
387 std::unique_ptr<DispatchEntry> dispatchEntry =
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700388 std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
389 firstPointerTransform, inputTarget.globalScaleFactor);
Chavi Weingarten65f98b82020-01-16 18:56:50 +0000390 return dispatchEntry;
391}
392
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700393static void addGestureMonitors(const std::vector<Monitor>& monitors,
394 std::vector<TouchedMonitor>& outTouchedMonitors, float xOffset = 0,
395 float yOffset = 0) {
396 if (monitors.empty()) {
397 return;
398 }
399 outTouchedMonitors.reserve(monitors.size() + outTouchedMonitors.size());
400 for (const Monitor& monitor : monitors) {
401 outTouchedMonitors.emplace_back(monitor, xOffset, yOffset);
402 }
403}
404
Garfield Tan15601662020-09-22 15:32:38 -0700405static status_t openInputChannelPair(const std::string& name,
406 std::shared_ptr<InputChannel>& serverChannel,
407 std::unique_ptr<InputChannel>& clientChannel) {
408 std::unique_ptr<InputChannel> uniqueServerChannel;
409 status_t result = InputChannel::openInputChannelPair(name, uniqueServerChannel, clientChannel);
410
411 serverChannel = std::move(uniqueServerChannel);
412 return result;
413}
414
Vishnu Nair958da932020-08-21 17:12:37 -0700415const char* InputDispatcher::typeToString(InputDispatcher::FocusResult result) {
416 switch (result) {
417 case InputDispatcher::FocusResult::OK:
418 return "Ok";
419 case InputDispatcher::FocusResult::NO_WINDOW:
420 return "Window not found";
421 case InputDispatcher::FocusResult::NOT_FOCUSABLE:
422 return "Window not focusable";
423 case InputDispatcher::FocusResult::NOT_VISIBLE:
424 return "Window not visible";
425 }
426}
427
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -0500428template <typename T>
429static bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
430 if (lhs == nullptr && rhs == nullptr) {
431 return true;
432 }
433 if (lhs == nullptr || rhs == nullptr) {
434 return false;
435 }
436 return *lhs == *rhs;
437}
438
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000439static sp<IPlatformCompatNative> getCompatService() {
440 sp<IBinder> service(defaultServiceManager()->getService(String16("platform_compat_native")));
441 if (service == nullptr) {
442 ALOGE("Failed to link to compat service");
443 return nullptr;
444 }
445 return interface_cast<IPlatformCompatNative>(service);
446}
447
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +0000448static KeyEvent createKeyEvent(const KeyEntry& entry) {
449 KeyEvent event;
450 event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
451 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
452 entry.repeatCount, entry.downTime, entry.eventTime);
453 return event;
454}
455
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000456static std::optional<int32_t> findMonitorPidByToken(
457 const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
458 const sp<IBinder>& token) {
459 for (const auto& it : monitorsByDisplay) {
460 const std::vector<Monitor>& monitors = it.second;
461 for (const Monitor& monitor : monitors) {
462 if (monitor.inputChannel->getConnectionToken() == token) {
463 return monitor.pid;
464 }
465 }
466 }
467 return std::nullopt;
468}
469
Michael Wrightd02c5b62014-02-10 15:10:22 -0800470// --- InputDispatcher ---
471
Garfield Tan00f511d2019-06-12 16:55:40 -0700472InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
473 : mPolicy(policy),
474 mPendingEvent(nullptr),
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700475 mLastDropReason(DropReason::NOT_DROPPED),
Garfield Tanff1f1bb2020-01-28 13:24:04 -0800476 mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
Garfield Tan00f511d2019-06-12 16:55:40 -0700477 mAppSwitchSawKeyDown(false),
478 mAppSwitchDueTime(LONG_LONG_MAX),
479 mNextUnblockedEvent(nullptr),
480 mDispatchEnabled(false),
481 mDispatchFrozen(false),
482 mInputFilterEnabled(false),
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -0800483 // mInTouchMode will be initialized by the WindowManager to the default device config.
484 // To avoid leaking stack in case that call never comes, and for tests,
485 // initialize it here anyways.
486 mInTouchMode(true),
Bernardo Rufinoea97d182020-08-19 14:43:14 +0100487 mMaximumObscuringOpacityForTouch(1.0f),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000488 mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
Prabir Pradhan99987712020-11-10 18:43:05 -0800489 mFocusedWindowRequestedPointerCapture(false),
490 mWindowTokenWithPointerCapture(nullptr),
Siarhei Vishniakou2508b872020-12-03 16:33:53 -1000491 mCompatService(getCompatService()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800492 mLooper = new Looper(false);
Prabir Pradhanf93562f2018-11-29 12:13:37 -0800493 mReporter = createInputReporter();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800494
Yi Kong9b14ac62018-07-17 13:48:38 -0700495 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800496
497 policy->getDispatcherConfiguration(&mConfig);
498}
499
500InputDispatcher::~InputDispatcher() {
501 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800502 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800503
504 resetKeyRepeatLocked();
505 releasePendingEventLocked();
506 drainInboundQueueLocked();
507 }
508
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -0700509 while (!mConnectionsByFd.empty()) {
510 sp<Connection> connection = mConnectionsByFd.begin()->second;
Garfield Tan15601662020-09-22 15:32:38 -0700511 removeInputChannel(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800512 }
513}
514
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700515status_t InputDispatcher::start() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700516 if (mThread) {
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700517 return ALREADY_EXISTS;
518 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700519 mThread = std::make_unique<InputThread>(
520 "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
521 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700522}
523
524status_t InputDispatcher::stop() {
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700525 if (mThread && mThread->isCallingThread()) {
526 ALOGE("InputDispatcher cannot be stopped from its own thread!");
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700527 return INVALID_OPERATION;
528 }
Prabir Pradhan5a57cff2019-10-31 18:40:33 -0700529 mThread.reset();
530 return OK;
Prabir Pradhan3608aad2019-10-02 17:08:26 -0700531}
532
Michael Wrightd02c5b62014-02-10 15:10:22 -0800533void InputDispatcher::dispatchOnce() {
534 nsecs_t nextWakeupTime = LONG_LONG_MAX;
535 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -0800536 std::scoped_lock _l(mLock);
537 mDispatcherIsAlive.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800538
539 // Run a dispatch loop if there are no pending commands.
540 // The dispatch loop might enqueue commands to run afterwards.
541 if (!haveCommandsLocked()) {
542 dispatchOnceInnerLocked(&nextWakeupTime);
543 }
544
545 // Run all pending commands if there are any.
546 // If any commands were run then force the next poll to wake up immediately.
547 if (runCommandsLockedInterruptible()) {
548 nextWakeupTime = LONG_LONG_MIN;
549 }
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800550
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700551 // If we are still waiting for ack on some events,
552 // we might have to wake up earlier to check if an app is anr'ing.
553 const nsecs_t nextAnrCheck = processAnrsLocked();
554 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
555
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -0800556 // We are about to enter an infinitely long sleep, because we have no commands or
557 // pending or queued events
558 if (nextWakeupTime == LONG_LONG_MAX) {
559 mDispatcherEnteredIdle.notify_all();
560 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800561 } // release lock
562
563 // Wait for callback or timeout or wake. (make sure we round up, not down)
564 nsecs_t currentTime = now();
565 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
566 mLooper->pollOnce(timeoutMillis);
567}
568
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700569/**
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500570 * Raise ANR if there is no focused window.
571 * Before the ANR is raised, do a final state check:
572 * 1. The currently focused application must be the same one we are waiting for.
573 * 2. Ensure we still don't have a focused window.
574 */
575void InputDispatcher::processNoFocusedWindowAnrLocked() {
576 // Check if the application that we are waiting for is still focused.
577 std::shared_ptr<InputApplicationHandle> focusedApplication =
578 getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
579 if (focusedApplication == nullptr ||
580 focusedApplication->getApplicationToken() !=
581 mAwaitedFocusedApplication->getApplicationToken()) {
582 // Unexpected because we should have reset the ANR timer when focused application changed
583 ALOGE("Waited for a focused window, but focused application has already changed to %s",
584 focusedApplication->getName().c_str());
585 return; // The focused application has changed.
586 }
587
588 const sp<InputWindowHandle>& focusedWindowHandle =
589 getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
590 if (focusedWindowHandle != nullptr) {
591 return; // We now have a focused window. No need for ANR.
592 }
593 onAnrLocked(mAwaitedFocusedApplication);
594}
595
596/**
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700597 * Check if any of the connections' wait queues have events that are too old.
598 * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
599 * Return the time at which we should wake up next.
600 */
601nsecs_t InputDispatcher::processAnrsLocked() {
602 const nsecs_t currentTime = now();
603 nsecs_t nextAnrCheck = LONG_LONG_MAX;
604 // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
605 if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
606 if (currentTime >= *mNoFocusedWindowTimeoutTime) {
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500607 processNoFocusedWindowAnrLocked();
Chris Yea209fde2020-07-22 13:54:51 -0700608 mAwaitedFocusedApplication.reset();
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -0500609 mNoFocusedWindowTimeoutTime = std::nullopt;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700610 return LONG_LONG_MIN;
611 } else {
Siarhei Vishniakou38a6d272020-10-20 20:29:33 -0500612 // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700613 nextAnrCheck = *mNoFocusedWindowTimeoutTime;
614 }
615 }
616
617 // Check if any connection ANRs are due
618 nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
619 if (currentTime < nextAnrCheck) { // most likely scenario
620 return nextAnrCheck; // everything is normal. Let's check again at nextAnrCheck
621 }
622
623 // If we reached here, we have an unresponsive connection.
624 sp<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
625 if (connection == nullptr) {
626 ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
627 return nextAnrCheck;
628 }
629 connection->responsive = false;
630 // Stop waking up for this unresponsive connection
631 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +0000632 onAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700633 return LONG_LONG_MIN;
634}
635
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500636std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(const sp<IBinder>& token) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700637 sp<InputWindowHandle> window = getWindowHandleLocked(token);
638 if (window != nullptr) {
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500639 return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700640 }
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500641 return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700642}
643
Michael Wrightd02c5b62014-02-10 15:10:22 -0800644void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
645 nsecs_t currentTime = now();
646
Jeff Browndc5992e2014-04-11 01:27:26 -0700647 // Reset the key repeat timer whenever normal dispatch is suspended while the
648 // device is in a non-interactive state. This is to ensure that we abort a key
649 // repeat if the device is just coming out of sleep.
650 if (!mDispatchEnabled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800651 resetKeyRepeatLocked();
652 }
653
654 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
655 if (mDispatchFrozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +0100656 if (DEBUG_FOCUS) {
657 ALOGD("Dispatch frozen. Waiting some more.");
658 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800659 return;
660 }
661
662 // Optimize latency of app switches.
663 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
664 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
665 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
666 if (mAppSwitchDueTime < *nextWakeupTime) {
667 *nextWakeupTime = mAppSwitchDueTime;
668 }
669
670 // Ready to start a new event.
671 // If we don't already have a pending event, go grab one.
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700672 if (!mPendingEvent) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700673 if (mInboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800674 if (isAppSwitchDue) {
675 // The inbound queue is empty so the app switch key we were waiting
676 // for will never arrive. Stop waiting for it.
677 resetPendingAppSwitchLocked(false);
678 isAppSwitchDue = false;
679 }
680
681 // Synthesize a key repeat if appropriate.
682 if (mKeyRepeatState.lastKeyEntry) {
683 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
684 mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
685 } else {
686 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
687 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
688 }
689 }
690 }
691
692 // Nothing to do if there is no pending event.
693 if (!mPendingEvent) {
694 return;
695 }
696 } else {
697 // Inbound queue has at least one entry.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700698 mPendingEvent = mInboundQueue.front();
699 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800700 traceInboundQueueLengthLocked();
701 }
702
703 // Poke user activity for this event.
704 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700705 pokeUserActivityLocked(*mPendingEvent);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800706 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800707 }
708
709 // Now we have an event to dispatch.
710 // All events are eventually dequeued and processed this way, even if we intend to drop them.
Yi Kong9b14ac62018-07-17 13:48:38 -0700711 ALOG_ASSERT(mPendingEvent != nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800712 bool done = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700713 DropReason dropReason = DropReason::NOT_DROPPED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800714 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700715 dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800716 } else if (!mDispatchEnabled) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700717 dropReason = DropReason::DISABLED;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800718 }
719
720 if (mNextUnblockedEvent == mPendingEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -0700721 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800722 }
723
724 switch (mPendingEvent->type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700725 case EventEntry::Type::CONFIGURATION_CHANGED: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700726 const ConfigurationChangedEntry& typedEntry =
727 static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700728 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700729 dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700730 break;
731 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800732
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700733 case EventEntry::Type::DEVICE_RESET: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700734 const DeviceResetEntry& typedEntry =
735 static_cast<const DeviceResetEntry&>(*mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700736 done = dispatchDeviceResetLocked(currentTime, typedEntry);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700737 dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700738 break;
739 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800740
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100741 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700742 std::shared_ptr<FocusEntry> typedEntry =
743 std::static_pointer_cast<FocusEntry>(mPendingEvent);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100744 dispatchFocusLocked(currentTime, typedEntry);
745 done = true;
746 dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
747 break;
748 }
749
Prabir Pradhan99987712020-11-10 18:43:05 -0800750 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
751 const auto typedEntry =
752 std::static_pointer_cast<PointerCaptureChangedEntry>(mPendingEvent);
753 dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
754 done = true;
755 break;
756 }
757
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700758 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700759 std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700760 if (isAppSwitchDue) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700761 if (isAppSwitchKeyEvent(*keyEntry)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700762 resetPendingAppSwitchLocked(true);
763 isAppSwitchDue = false;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700764 } else if (dropReason == DropReason::NOT_DROPPED) {
765 dropReason = DropReason::APP_SWITCH;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700766 }
767 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700768 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700769 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700770 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700771 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
772 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700773 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700774 done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700775 break;
776 }
777
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700778 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700779 std::shared_ptr<MotionEntry> motionEntry =
780 std::static_pointer_cast<MotionEntry>(mPendingEvent);
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700781 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
782 dropReason = DropReason::APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800783 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700784 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700785 dropReason = DropReason::STALE;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700786 }
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700787 if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
788 dropReason = DropReason::BLOCKED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700789 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700790 done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700791 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800792 }
Chris Yef59a2f42020-10-16 12:55:26 -0700793
794 case EventEntry::Type::SENSOR: {
795 std::shared_ptr<SensorEntry> sensorEntry =
796 std::static_pointer_cast<SensorEntry>(mPendingEvent);
797 if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
798 dropReason = DropReason::APP_SWITCH;
799 }
800 // Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
801 // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
802 nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
803 if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
804 dropReason = DropReason::STALE;
805 }
806 dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
807 done = true;
808 break;
809 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800810 }
811
812 if (done) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -0700813 if (dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700814 dropInboundEventLocked(*mPendingEvent, dropReason);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800815 }
Michael Wright3a981722015-06-10 15:26:13 +0100816 mLastDropReason = dropReason;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800817
818 releasePendingEventLocked();
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700819 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Michael Wrightd02c5b62014-02-10 15:10:22 -0800820 }
821}
822
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700823/**
824 * Return true if the events preceding this incoming motion event should be dropped
825 * Return false otherwise (the default behaviour)
826 */
827bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700828 const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700829 (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700830
831 // Optimize case where the current application is unresponsive and the user
832 // decides to touch a window in a different application.
833 // If the application takes too long to catch up then we drop all events preceding
834 // the touch into the other window.
835 if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700836 int32_t displayId = motionEntry.displayId;
837 int32_t x = static_cast<int32_t>(
838 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
839 int32_t y = static_cast<int32_t>(
840 motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
841 sp<InputWindowHandle> touchedWindowHandle =
842 findTouchedWindowAtLocked(displayId, x, y, nullptr);
843 if (touchedWindowHandle != nullptr &&
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700844 touchedWindowHandle->getApplicationToken() !=
845 mAwaitedFocusedApplication->getApplicationToken()) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700846 // User touched a different application than the one we are waiting on.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700847 ALOGI("Pruning input queue because user touched a different application while waiting "
848 "for %s",
849 mAwaitedFocusedApplication->getName().c_str());
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700850 return true;
851 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700852
853 // Alternatively, maybe there's a gesture monitor that could handle this event
854 std::vector<TouchedMonitor> gestureMonitors =
855 findTouchedGestureMonitorsLocked(displayId, {});
856 for (TouchedMonitor& gestureMonitor : gestureMonitors) {
857 sp<Connection> connection =
858 getConnectionLocked(gestureMonitor.monitor.inputChannel->getConnectionToken());
Siarhei Vishniakou34ed4d42020-06-18 00:43:02 +0000859 if (connection != nullptr && connection->responsive) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -0700860 // This monitor could take more input. Drop all events preceding this
861 // event, so that gesture monitor could get a chance to receive the stream
862 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
863 "responsive gesture monitor that may handle the event",
864 mAwaitedFocusedApplication->getName().c_str());
865 return true;
866 }
867 }
868 }
869
870 // Prevent getting stuck: if we have a pending key event, and some motion events that have not
871 // yet been processed by some connections, the dispatcher will wait for these motion
872 // events to be processed before dispatching the key event. This is because these motion events
873 // may cause a new window to be launched, which the user might expect to receive focus.
874 // To prevent waiting forever for such events, just send the key to the currently focused window
875 if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
876 ALOGD("Received a new pointer down event, stop waiting for events to process and "
877 "just send the pending key event to the focused window.");
878 mKeyIsWaitingForEventsTimeout = now();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700879 }
880 return false;
881}
882
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700883bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700884 bool needWake = mInboundQueue.empty();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700885 mInboundQueue.push_back(std::move(newEntry));
886 EventEntry& entry = *(mInboundQueue.back());
Michael Wrightd02c5b62014-02-10 15:10:22 -0800887 traceInboundQueueLengthLocked();
888
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700889 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700890 case EventEntry::Type::KEY: {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700891 // Optimize app switch latency.
892 // If the application takes too long to catch up then we drop all events preceding
893 // the app switch key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700894 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700895 if (isAppSwitchKeyEvent(keyEntry)) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700896 if (keyEntry.action == AKEY_EVENT_ACTION_DOWN) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700897 mAppSwitchSawKeyDown = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700898 } else if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700899 if (mAppSwitchSawKeyDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800900#if DEBUG_APP_SWITCH
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700901 ALOGD("App switch is pending!");
Michael Wrightd02c5b62014-02-10 15:10:22 -0800902#endif
Siarhei Vishniakoud2770042019-10-29 11:08:14 -0700903 mAppSwitchDueTime = keyEntry.eventTime + APP_SWITCH_TIMEOUT;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700904 mAppSwitchSawKeyDown = false;
905 needWake = true;
906 }
907 }
908 }
909 break;
910 }
911
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700912 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700913 if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
914 mNextUnblockedEvent = mInboundQueue.back();
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700915 needWake = true;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800916 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700917 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800918 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100919 case EventEntry::Type::FOCUS: {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -0700920 LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
921 break;
922 }
923 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -0800924 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -0700925 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -0800926 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -0700927 // nothing to do
928 break;
929 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800930 }
931
932 return needWake;
933}
934
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -0700935void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
Chris Yef59a2f42020-10-16 12:55:26 -0700936 // Do not store sensor event in recent queue to avoid flooding the queue.
937 if (entry->type != EventEntry::Type::SENSOR) {
938 mRecentQueue.push_back(entry);
939 }
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700940 if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -0700941 mRecentQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -0800942 }
943}
944
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700945sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700946 int32_t y, TouchState* touchState,
947 bool addOutsideTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700948 bool addPortalWindows) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700949 if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
950 LOG_ALWAYS_FATAL(
951 "Must provide a valid touch state if adding portal windows or outside targets");
952 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800953 // Traverse windows from front to back to find touched window.
Vishnu Nairad321cd2020-08-20 16:40:21 -0700954 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +0800955 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -0800956 const InputWindowInfo* windowInfo = windowHandle->getInfo();
957 if (windowInfo->displayId == displayId) {
Michael Wright44753b12020-07-08 13:48:11 +0100958 auto flags = windowInfo->flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800959
960 if (windowInfo->visible) {
Michael Wright44753b12020-07-08 13:48:11 +0100961 if (!flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
962 bool isTouchModal = !flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE) &&
963 !flags.test(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
Michael Wrightd02c5b62014-02-10 15:10:22 -0800964 if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800965 int32_t portalToDisplayId = windowInfo->portalToDisplayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700966 if (portalToDisplayId != ADISPLAY_ID_NONE &&
967 portalToDisplayId != displayId) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800968 if (addPortalWindows) {
969 // For the monitoring channels of the display.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700970 touchState->addPortalWindow(windowHandle);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800971 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700972 return findTouchedWindowAtLocked(portalToDisplayId, x, y, touchState,
Garfield Tan0fc2fa72019-08-29 17:22:15 -0700973 addOutsideTargets, addPortalWindows);
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800974 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800975 // Found window.
976 return windowHandle;
977 }
978 }
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800979
Michael Wright44753b12020-07-08 13:48:11 +0100980 if (addOutsideTargets && flags.test(InputWindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -0700981 touchState->addOrUpdateWindow(windowHandle,
982 InputTarget::FLAG_DISPATCH_AS_OUTSIDE,
983 BitSet32(0));
Tiger Huang85b8c5e2019-01-17 18:34:54 +0800984 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800985 }
Michael Wrightd02c5b62014-02-10 15:10:22 -0800986 }
987 }
Yi Kong9b14ac62018-07-17 13:48:38 -0700988 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -0800989}
990
Garfield Tane84e6f92019-08-29 17:28:41 -0700991std::vector<TouchedMonitor> InputDispatcher::findTouchedGestureMonitorsLocked(
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -0700992 int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const {
Michael Wright3dd60e22019-03-27 22:06:44 +0000993 std::vector<TouchedMonitor> touchedMonitors;
994
995 std::vector<Monitor> monitors = getValueByKey(mGestureMonitorsByDisplay, displayId);
996 addGestureMonitors(monitors, touchedMonitors);
997 for (const sp<InputWindowHandle>& portalWindow : portalWindows) {
998 const InputWindowInfo* windowInfo = portalWindow->getInfo();
999 monitors = getValueByKey(mGestureMonitorsByDisplay, windowInfo->portalToDisplayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001000 addGestureMonitors(monitors, touchedMonitors, -windowInfo->frameLeft,
1001 -windowInfo->frameTop);
Michael Wright3dd60e22019-03-27 22:06:44 +00001002 }
1003 return touchedMonitors;
1004}
1005
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001006void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001007 const char* reason;
1008 switch (dropReason) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001009 case DropReason::POLICY:
Michael Wrightd02c5b62014-02-10 15:10:22 -08001010#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001011 ALOGD("Dropped event because policy consumed it.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001012#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001013 reason = "inbound event was dropped because the policy consumed it";
1014 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001015 case DropReason::DISABLED:
1016 if (mLastDropReason != DropReason::DISABLED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001017 ALOGI("Dropped event because input dispatch is disabled.");
1018 }
1019 reason = "inbound event was dropped because input dispatch is disabled";
1020 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001021 case DropReason::APP_SWITCH:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001022 ALOGI("Dropped event because of pending overdue app switch.");
1023 reason = "inbound event was dropped because of pending overdue app switch";
1024 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001025 case DropReason::BLOCKED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001026 ALOGI("Dropped event because the current application is not responding and the user "
1027 "has started interacting with a different application.");
1028 reason = "inbound event was dropped because the current application is not responding "
1029 "and the user has started interacting with a different application";
1030 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001031 case DropReason::STALE:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001032 ALOGI("Dropped event because it is stale.");
1033 reason = "inbound event was dropped because it is stale";
1034 break;
Prabir Pradhan99987712020-11-10 18:43:05 -08001035 case DropReason::NO_POINTER_CAPTURE:
1036 ALOGI("Dropped event because there is no window with Pointer Capture.");
1037 reason = "inbound event was dropped because there is no window with Pointer Capture";
1038 break;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001039 case DropReason::NOT_DROPPED: {
1040 LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001041 return;
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001042 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001043 }
1044
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001045 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001046 case EventEntry::Type::KEY: {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001047 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1048 synthesizeCancelationEventsForAllConnectionsLocked(options);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001049 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001050 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001051 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001052 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1053 if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001054 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
1055 synthesizeCancelationEventsForAllConnectionsLocked(options);
1056 } else {
1057 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
1058 synthesizeCancelationEventsForAllConnectionsLocked(options);
1059 }
1060 break;
1061 }
Chris Yef59a2f42020-10-16 12:55:26 -07001062 case EventEntry::Type::SENSOR: {
1063 break;
1064 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001065 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1066 break;
1067 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001068 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001069 case EventEntry::Type::CONFIGURATION_CHANGED:
1070 case EventEntry::Type::DEVICE_RESET: {
Chris Yef59a2f42020-10-16 12:55:26 -07001071 LOG_ALWAYS_FATAL("Should not drop %s events", NamedEnum::string(entry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001072 break;
1073 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001074 }
1075}
1076
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08001077static bool isAppSwitchKeyCode(int32_t keyCode) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001078 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL ||
1079 keyCode == AKEYCODE_APP_SWITCH;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001080}
1081
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001082bool InputDispatcher::isAppSwitchKeyEvent(const KeyEntry& keyEntry) {
1083 return !(keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) && isAppSwitchKeyCode(keyEntry.keyCode) &&
1084 (keyEntry.policyFlags & POLICY_FLAG_TRUSTED) &&
1085 (keyEntry.policyFlags & POLICY_FLAG_PASS_TO_USER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001086}
1087
1088bool InputDispatcher::isAppSwitchPendingLocked() {
1089 return mAppSwitchDueTime != LONG_LONG_MAX;
1090}
1091
1092void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
1093 mAppSwitchDueTime = LONG_LONG_MAX;
1094
1095#if DEBUG_APP_SWITCH
1096 if (handled) {
1097 ALOGD("App switch has arrived.");
1098 } else {
1099 ALOGD("App switch was abandoned.");
1100 }
1101#endif
1102}
1103
Michael Wrightd02c5b62014-02-10 15:10:22 -08001104bool InputDispatcher::haveCommandsLocked() const {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001105 return !mCommandQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001106}
1107
1108bool InputDispatcher::runCommandsLockedInterruptible() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001109 if (mCommandQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001110 return false;
1111 }
1112
1113 do {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001114 std::unique_ptr<CommandEntry> commandEntry = std::move(mCommandQueue.front());
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001115 mCommandQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001116 Command command = commandEntry->command;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001117 command(*this, commandEntry.get()); // commands are implicitly 'LockedInterruptible'
Michael Wrightd02c5b62014-02-10 15:10:22 -08001118
1119 commandEntry->connection.clear();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001120 } while (!mCommandQueue.empty());
Michael Wrightd02c5b62014-02-10 15:10:22 -08001121 return true;
1122}
1123
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001124void InputDispatcher::postCommandLocked(std::unique_ptr<CommandEntry> commandEntry) {
1125 mCommandQueue.push_back(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001126}
1127
1128void InputDispatcher::drainInboundQueueLocked() {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001129 while (!mInboundQueue.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001130 std::shared_ptr<EventEntry> entry = mInboundQueue.front();
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07001131 mInboundQueue.pop_front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001132 releaseInboundEventLocked(entry);
1133 }
1134 traceInboundQueueLengthLocked();
1135}
1136
1137void InputDispatcher::releasePendingEventLocked() {
1138 if (mPendingEvent) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001139 releaseInboundEventLocked(mPendingEvent);
Yi Kong9b14ac62018-07-17 13:48:38 -07001140 mPendingEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001141 }
1142}
1143
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001144void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<EventEntry> entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001145 InjectionState* injectionState = entry->injectionState;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001146 if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001147#if DEBUG_DISPATCH_CYCLE
1148 ALOGD("Injected inbound event was dropped.");
1149#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001150 setInjectionResult(*entry, InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001151 }
1152 if (entry == mNextUnblockedEvent) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001153 mNextUnblockedEvent = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001154 }
1155 addRecentEventLocked(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001156}
1157
1158void InputDispatcher::resetKeyRepeatLocked() {
1159 if (mKeyRepeatState.lastKeyEntry) {
Yi Kong9b14ac62018-07-17 13:48:38 -07001160 mKeyRepeatState.lastKeyEntry = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001161 }
1162}
1163
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001164std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1165 std::shared_ptr<KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001166
Michael Wright2e732952014-09-24 13:26:59 -07001167 uint32_t policyFlags = entry->policyFlags &
1168 (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001169
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001170 std::shared_ptr<KeyEntry> newEntry =
1171 std::make_unique<KeyEntry>(mIdGenerator.nextId(), currentTime, entry->deviceId,
1172 entry->source, entry->displayId, policyFlags, entry->action,
1173 entry->flags, entry->keyCode, entry->scanCode,
1174 entry->metaState, entry->repeatCount + 1, entry->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001175
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001176 newEntry->syntheticRepeat = true;
1177 mKeyRepeatState.lastKeyEntry = newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001178 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001179 return newEntry;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001180}
1181
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001182bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001183 const ConfigurationChangedEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001184#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001185 ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001186#endif
1187
1188 // Reset key repeating in case a keyboard device was added or removed or something.
1189 resetKeyRepeatLocked();
1190
1191 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001192 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
1193 &InputDispatcher::doNotifyConfigurationChangedLockedInterruptible);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001194 commandEntry->eventTime = entry.eventTime;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001195 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001196 return true;
1197}
1198
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001199bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1200 const DeviceResetEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001201#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001202 ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1203 entry.deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001204#endif
1205
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001206 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001207 options.deviceId = entry.deviceId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001208 synthesizeCancelationEventsForAllConnectionsLocked(options);
1209 return true;
1210}
1211
Vishnu Nairad321cd2020-08-20 16:40:21 -07001212void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001213 std::string_view reason) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001214 if (mPendingEvent != nullptr) {
1215 // Move the pending event to the front of the queue. This will give the chance
1216 // for the pending event to get dispatched to the newly focused window
1217 mInboundQueue.push_front(mPendingEvent);
1218 mPendingEvent = nullptr;
1219 }
1220
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001221 std::unique_ptr<FocusEntry> focusEntry =
1222 std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1223 reason);
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001224
1225 // This event should go to the front of the queue, but behind all other focus events
1226 // Find the last focus event, and insert right after it
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001227 std::deque<std::shared_ptr<EventEntry>>::reverse_iterator it =
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001228 std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001229 [](const std::shared_ptr<EventEntry>& event) {
1230 return event->type == EventEntry::Type::FOCUS;
1231 });
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07001232
1233 // Maintain the order of focus events. Insert the entry after all other focus events.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001234 mInboundQueue.insert(it.base(), std::move(focusEntry));
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001235}
1236
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001237void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, std::shared_ptr<FocusEntry> entry) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05001238 std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001239 if (channel == nullptr) {
1240 return; // Window has gone away
1241 }
1242 InputTarget target;
1243 target.inputChannel = channel;
1244 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1245 entry->dispatchInProgress = true;
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001246 std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1247 channel->getName();
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07001248 std::string reason = std::string("reason=").append(entry->reason);
1249 android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001250 dispatchEventLocked(currentTime, entry, {target});
1251}
1252
Prabir Pradhan99987712020-11-10 18:43:05 -08001253void InputDispatcher::dispatchPointerCaptureChangedLocked(
1254 nsecs_t currentTime, const std::shared_ptr<PointerCaptureChangedEntry>& entry,
1255 DropReason& dropReason) {
1256 const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1257 if (entry->pointerCaptureEnabled == haveWindowWithPointerCapture) {
1258 LOG_ALWAYS_FATAL_IF(mFocusedWindowRequestedPointerCapture,
1259 "The Pointer Capture state has already been dispatched to the window.");
1260 // Pointer capture was already forcefully disabled because of focus change.
1261 dropReason = DropReason::NOT_DROPPED;
1262 return;
1263 }
1264
1265 // Set drop reason for early returns
1266 dropReason = DropReason::NO_POINTER_CAPTURE;
1267
1268 sp<IBinder> token;
1269 if (entry->pointerCaptureEnabled) {
1270 // Enable Pointer Capture
1271 if (!mFocusedWindowRequestedPointerCapture) {
1272 // This can happen if a window requests capture and immediately releases capture.
1273 ALOGW("No window requested Pointer Capture.");
1274 return;
1275 }
1276 token = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
1277 LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1278 mWindowTokenWithPointerCapture = token;
1279 } else {
1280 // Disable Pointer Capture
1281 token = mWindowTokenWithPointerCapture;
1282 mWindowTokenWithPointerCapture = nullptr;
1283 mFocusedWindowRequestedPointerCapture = false;
1284 }
1285
1286 auto channel = getInputChannelLocked(token);
1287 if (channel == nullptr) {
1288 // Window has gone away, clean up Pointer Capture state.
1289 mWindowTokenWithPointerCapture = nullptr;
1290 mFocusedWindowRequestedPointerCapture = false;
1291 return;
1292 }
1293 InputTarget target;
1294 target.inputChannel = channel;
1295 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1296 entry->dispatchInProgress = true;
1297 dispatchEventLocked(currentTime, entry, {target});
1298
1299 dropReason = DropReason::NOT_DROPPED;
1300}
1301
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001302bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<KeyEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001303 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001304 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001305 if (!entry->dispatchInProgress) {
1306 if (entry->repeatCount == 0 && entry->action == AKEY_EVENT_ACTION_DOWN &&
1307 (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1308 (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1309 if (mKeyRepeatState.lastKeyEntry &&
Chris Ye2ad95392020-09-01 13:44:44 -07001310 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
Michael Wrightd02c5b62014-02-10 15:10:22 -08001311 // We have seen two identical key downs in a row which indicates that the device
1312 // driver is automatically generating key repeats itself. We take note of the
1313 // repeat here, but we disable our own next key repeat timer since it is clear that
1314 // we will not need to synthesize key repeats ourselves.
Chris Ye2ad95392020-09-01 13:44:44 -07001315 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1316 // Make sure we don't get key down from a different device. If a different
1317 // device Id has same key pressed down, the new device Id will replace the
1318 // current one to hold the key repeat with repeat count reset.
1319 // In the future when got a KEY_UP on the device id, drop it and do not
1320 // stop the key repeat on current device.
Michael Wrightd02c5b62014-02-10 15:10:22 -08001321 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1322 resetKeyRepeatLocked();
1323 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
1324 } else {
1325 // Not a repeat. Save key down state in case we do see a repeat later.
1326 resetKeyRepeatLocked();
1327 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1328 }
1329 mKeyRepeatState.lastKeyEntry = entry;
Chris Ye2ad95392020-09-01 13:44:44 -07001330 } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1331 mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001332 // The key on device 'deviceId' is still down, do not stop key repeat
Chris Ye2ad95392020-09-01 13:44:44 -07001333#if DEBUG_INBOUND_EVENT_DETAILS
1334 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1335#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001336 } else if (!entry->syntheticRepeat) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001337 resetKeyRepeatLocked();
1338 }
1339
1340 if (entry->repeatCount == 1) {
1341 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1342 } else {
1343 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1344 }
1345
1346 entry->dispatchInProgress = true;
1347
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001348 logOutboundKeyDetails("dispatchKey - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001349 }
1350
1351 // Handle case where the policy asked us to try again later last time.
1352 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
1353 if (currentTime < entry->interceptKeyWakeupTime) {
1354 if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
1355 *nextWakeupTime = entry->interceptKeyWakeupTime;
1356 }
1357 return false; // wait until next wakeup
1358 }
1359 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
1360 entry->interceptKeyWakeupTime = 0;
1361 }
1362
1363 // Give the policy a chance to intercept the key.
1364 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
1365 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001366 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
Siarhei Vishniakou49a350a2019-07-26 18:44:23 -07001367 &InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001368 sp<IBinder> focusedWindowToken =
1369 getValueByKey(mFocusedWindowTokenByDisplay, getTargetDisplayId(*entry));
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06001370 commandEntry->connectionToken = focusedWindowToken;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001371 commandEntry->keyEntry = entry;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07001372 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001373 return false; // wait for the command to run
1374 } else {
1375 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
1376 }
1377 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001378 if (*dropReason == DropReason::NOT_DROPPED) {
1379 *dropReason = DropReason::POLICY;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001380 }
1381 }
1382
1383 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001384 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001385 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001386 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1387 : InputEventInjectionResult::FAILED);
Garfield Tan6a5a14e2020-01-28 13:24:04 -08001388 mReporter->reportDroppedKey(entry->id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001389 return true;
1390 }
1391
1392 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001393 std::vector<InputTarget> inputTargets;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001394 InputEventInjectionResult injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001395 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001396 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001397 return false;
1398 }
1399
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001400 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001401 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001402 return true;
1403 }
1404
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001405 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001406 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001407
1408 // Dispatch the key.
1409 dispatchEventLocked(currentTime, entry, inputTargets);
1410 return true;
1411}
1412
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001413void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001414#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001415 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001416 "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1417 "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001418 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1419 entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
1420 entry.repeatCount, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001421#endif
1422}
1423
Chris Yef59a2f42020-10-16 12:55:26 -07001424void InputDispatcher::doNotifySensorLockedInterruptible(CommandEntry* commandEntry) {
1425 mLock.unlock();
1426
1427 const std::shared_ptr<SensorEntry>& entry = commandEntry->sensorEntry;
1428 if (entry->accuracyChanged) {
1429 mPolicy->notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
1430 }
1431 mPolicy->notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
1432 entry->hwTimestamp, entry->values);
1433 mLock.lock();
1434}
1435
1436void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
1437 DropReason* dropReason, nsecs_t* nextWakeupTime) {
1438#if DEBUG_OUTBOUND_EVENT_DETAILS
1439 ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
1440 "source=0x%x, sensorType=%s",
1441 entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
1442 NamedEnum::string(sensorType).c_str());
1443#endif
1444 std::unique_ptr<CommandEntry> commandEntry =
1445 std::make_unique<CommandEntry>(&InputDispatcher::doNotifySensorLockedInterruptible);
1446 commandEntry->sensorEntry = entry;
1447 postCommandLocked(std::move(commandEntry));
1448}
1449
1450bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
1451#if DEBUG_OUTBOUND_EVENT_DETAILS
1452 ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
1453 NamedEnum::string(sensorType).c_str());
1454#endif
1455 { // acquire lock
1456 std::scoped_lock _l(mLock);
1457
1458 for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
1459 std::shared_ptr<EventEntry> entry = *it;
1460 if (entry->type == EventEntry::Type::SENSOR) {
1461 it = mInboundQueue.erase(it);
1462 releaseInboundEventLocked(entry);
1463 }
1464 }
1465 }
1466 return true;
1467}
1468
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001469bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001470 DropReason* dropReason, nsecs_t* nextWakeupTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001471 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001472 // Preprocessing.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001473 if (!entry->dispatchInProgress) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001474 entry->dispatchInProgress = true;
1475
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001476 logOutboundMotionDetails("dispatchMotion - ", *entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001477 }
1478
1479 // Clean up if dropping the event.
Siarhei Vishniakou0fb1a0e2019-10-22 11:23:36 -07001480 if (*dropReason != DropReason::NOT_DROPPED) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001481 setInjectionResult(*entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001482 *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1483 : InputEventInjectionResult::FAILED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001484 return true;
1485 }
1486
1487 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
1488
1489 // Identify targets.
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001490 std::vector<InputTarget> inputTargets;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001491
1492 bool conflictingPointerActions = false;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001493 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001494 if (isPointerEvent) {
1495 // Pointer event. (eg. touchscreen)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001496 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001497 findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001498 &conflictingPointerActions);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001499 } else {
1500 // Non touch event. (eg. trackball)
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001501 injectionResult =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001502 findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001503 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001504 if (injectionResult == InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001505 return false;
1506 }
1507
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001508 setInjectionResult(*entry, injectionResult);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001509 if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001510 ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
1511 return true;
1512 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001513 if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07001514 CancelationOptions::Mode mode(isPointerEvent
1515 ? CancelationOptions::CANCEL_POINTER_EVENTS
1516 : CancelationOptions::CANCEL_NON_POINTER_EVENTS);
1517 CancelationOptions options(mode, "input event injection failed");
1518 synthesizeCancelationEventsForMonitorsLocked(options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001519 return true;
1520 }
1521
Arthur Hung2fbf37f2018-09-13 18:16:41 +08001522 // Add monitor channels from event's or focused display.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001523 addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001524
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001525 if (isPointerEvent) {
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001526 std::unordered_map<int32_t, TouchState>::iterator it =
1527 mTouchStatesByDisplay.find(entry->displayId);
1528 if (it != mTouchStatesByDisplay.end()) {
1529 const TouchState& state = it->second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001530 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001531 // The event has gone through these portal windows, so we add monitoring targets of
1532 // the corresponding displays as well.
1533 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001534 const InputWindowInfo* windowInfo = state.portalWindows[i]->getInfo();
Michael Wright3dd60e22019-03-27 22:06:44 +00001535 addGlobalMonitoringTargetsLocked(inputTargets, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001536 -windowInfo->frameLeft, -windowInfo->frameTop);
Tiger Huang85b8c5e2019-01-17 18:34:54 +08001537 }
1538 }
1539 }
1540 }
1541
Michael Wrightd02c5b62014-02-10 15:10:22 -08001542 // Dispatch the motion.
1543 if (conflictingPointerActions) {
1544 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001545 "conflicting pointer actions");
Michael Wrightd02c5b62014-02-10 15:10:22 -08001546 synthesizeCancelationEventsForAllConnectionsLocked(options);
1547 }
1548 dispatchEventLocked(currentTime, entry, inputTargets);
1549 return true;
1550}
1551
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001552void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001553#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001554 ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001555 ", policyFlags=0x%x, "
1556 "action=0x%x, actionButton=0x%x, flags=0x%x, "
1557 "metaState=0x%x, buttonState=0x%x,"
1558 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001559 prefix, entry.eventTime, entry.deviceId, entry.source, entry.displayId, entry.policyFlags,
1560 entry.action, entry.actionButton, entry.flags, entry.metaState, entry.buttonState,
1561 entry.edgeFlags, entry.xPrecision, entry.yPrecision, entry.downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001562
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001563 for (uint32_t i = 0; i < entry.pointerCount; i++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001564 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001565 "x=%f, y=%f, pressure=%f, size=%f, "
1566 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
1567 "orientation=%f",
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001568 i, entry.pointerProperties[i].id, entry.pointerProperties[i].toolType,
1569 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
1570 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
1571 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
1572 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
1573 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
1574 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
1575 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1576 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1577 entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08001578 }
1579#endif
1580}
1581
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07001582void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1583 std::shared_ptr<EventEntry> eventEntry,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001584 const std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001585 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001586#if DEBUG_DISPATCH_CYCLE
1587 ALOGD("dispatchEventToCurrentInputTargets");
1588#endif
1589
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00001590 updateInteractionTokensLocked(*eventEntry, inputTargets);
1591
Michael Wrightd02c5b62014-02-10 15:10:22 -08001592 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1593
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001594 pokeUserActivityLocked(*eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001595
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08001596 for (const InputTarget& inputTarget : inputTargets) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07001597 sp<Connection> connection =
1598 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07001599 if (connection != nullptr) {
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08001600 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001601 } else {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001602 if (DEBUG_FOCUS) {
1603 ALOGD("Dropping event delivery to target with channel '%s' because it "
1604 "is no longer registered with the input dispatcher.",
1605 inputTarget.inputChannel->getName().c_str());
1606 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001607 }
1608 }
1609}
1610
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001611void InputDispatcher::cancelEventsForAnrLocked(const sp<Connection>& connection) {
1612 // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
1613 // If the policy decides to close the app, we will get a channel removal event via
1614 // unregisterInputChannel, and will clean up the connection that way. We are already not
1615 // sending new pointers to the connection when it blocked, but focused events will continue to
1616 // pile up.
1617 ALOGW("Canceling events for %s because it is unresponsive",
1618 connection->inputChannel->getName().c_str());
1619 if (connection->status == Connection::STATUS_NORMAL) {
1620 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
1621 "application not responding");
1622 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001623 }
1624}
1625
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001626void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01001627 if (DEBUG_FOCUS) {
1628 ALOGD("Resetting ANR timeouts.");
1629 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001630
1631 // Reset input target wait timeout.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001632 mNoFocusedWindowTimeoutTime = std::nullopt;
Chris Yea209fde2020-07-22 13:54:51 -07001633 mAwaitedFocusedApplication.reset();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001634}
1635
Tiger Huang721e26f2018-07-24 22:26:19 +08001636/**
1637 * Get the display id that the given event should go to. If this event specifies a valid display id,
1638 * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
1639 * Focused display is the display that the user most recently interacted with.
1640 */
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001641int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
Tiger Huang721e26f2018-07-24 22:26:19 +08001642 int32_t displayId;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001643 switch (entry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001644 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001645 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1646 displayId = keyEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001647 break;
1648 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001649 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001650 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1651 displayId = motionEntry.displayId;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001652 break;
1653 }
Prabir Pradhan99987712020-11-10 18:43:05 -08001654 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01001655 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07001656 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07001657 case EventEntry::Type::DEVICE_RESET:
1658 case EventEntry::Type::SENSOR: {
1659 ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001660 return ADISPLAY_ID_NONE;
1661 }
Tiger Huang721e26f2018-07-24 22:26:19 +08001662 }
1663 return displayId == ADISPLAY_ID_NONE ? mFocusedDisplayId : displayId;
1664}
1665
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001666bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
1667 const char* focusedWindowName) {
1668 if (mAnrTracker.empty()) {
1669 // already processed all events that we waited for
1670 mKeyIsWaitingForEventsTimeout = std::nullopt;
1671 return false;
1672 }
1673
1674 if (!mKeyIsWaitingForEventsTimeout.has_value()) {
1675 // Start the timer
1676 ALOGD("Waiting to send key to %s because there are unprocessed events that may cause "
1677 "focus to change",
1678 focusedWindowName);
Siarhei Vishniakou70622952020-07-30 11:17:23 -05001679 mKeyIsWaitingForEventsTimeout = currentTime +
1680 std::chrono::duration_cast<std::chrono::nanoseconds>(KEY_WAITING_FOR_EVENTS_TIMEOUT)
1681 .count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001682 return true;
1683 }
1684
1685 // We still have pending events, and already started the timer
1686 if (currentTime < *mKeyIsWaitingForEventsTimeout) {
1687 return true; // Still waiting
1688 }
1689
1690 // Waited too long, and some connection still hasn't processed all motions
1691 // Just send the key to the focused window
1692 ALOGW("Dispatching key to %s even though there are other unprocessed events",
1693 focusedWindowName);
1694 mKeyIsWaitingForEventsTimeout = std::nullopt;
1695 return false;
1696}
1697
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001698InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
1699 nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
1700 nsecs_t* nextWakeupTime) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001701 std::string reason;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001702
Tiger Huang721e26f2018-07-24 22:26:19 +08001703 int32_t displayId = getTargetDisplayId(entry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07001704 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Chris Yea209fde2020-07-22 13:54:51 -07001705 std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08001706 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
1707
Michael Wrightd02c5b62014-02-10 15:10:22 -08001708 // If there is no currently focused window and no focused application
1709 // then drop the event.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001710 if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
1711 ALOGI("Dropping %s event because there is no focused window or focused application in "
1712 "display %" PRId32 ".",
Chris Yef59a2f42020-10-16 12:55:26 -07001713 NamedEnum::string(entry.type).c_str(), displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001714 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001715 }
1716
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001717 // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
1718 // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
1719 // start interacting with another application via touch (app switch). This code can be removed
1720 // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
1721 // an app is expected to have a focused window.
1722 if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
1723 if (!mNoFocusedWindowTimeoutTime.has_value()) {
1724 // We just discovered that there's no focused window. Start the ANR timer
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001725 std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
1726 DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1727 mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001728 mAwaitedFocusedApplication = focusedApplicationHandle;
Siarhei Vishniakouf56b2692020-09-08 19:43:33 -05001729 mAwaitedApplicationDisplayId = displayId;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001730 ALOGW("Waiting because no window has focus but %s may eventually add a "
1731 "window when it finishes starting up. Will wait for %" PRId64 "ms",
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -05001732 mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001733 *nextWakeupTime = *mNoFocusedWindowTimeoutTime;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001734 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001735 } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
1736 // Already raised ANR. Drop the event
1737 ALOGE("Dropping %s event because there is no focused window",
Chris Yef59a2f42020-10-16 12:55:26 -07001738 NamedEnum::string(entry.type).c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001739 return InputEventInjectionResult::FAILED;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001740 } else {
1741 // Still waiting for the focused window
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001742 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001743 }
1744 }
1745
1746 // we have a valid, non-null focused window
1747 resetNoFocusedWindowTimeoutLocked();
1748
Michael Wrightd02c5b62014-02-10 15:10:22 -08001749 // Check permissions.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001750 if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001751 return InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001752 }
1753
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001754 if (focusedWindowHandle->getInfo()->paused) {
1755 ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001756 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001757 }
1758
1759 // If the event is a key event, then we must wait for all previous events to
1760 // complete before delivering it because previous events may have the
1761 // side-effect of transferring focus to a different window and we want to
1762 // ensure that the following keys are sent to the new window.
1763 //
1764 // Suppose the user touches a button in a window then immediately presses "A".
1765 // If the button causes a pop-up window to appear then we want to ensure that
1766 // the "A" key is delivered to the new pop-up window. This is because users
1767 // often anticipate pending UI changes when typing on a keyboard.
1768 // To obtain this behavior, we must serialize key events with respect to all
1769 // prior input events.
1770 if (entry.type == EventEntry::Type::KEY) {
1771 if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
1772 *nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001773 return InputEventInjectionResult::PENDING;
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001774 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08001775 }
1776
1777 // Success! Output targets.
Tiger Huang721e26f2018-07-24 22:26:19 +08001778 addWindowTargetLocked(focusedWindowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001779 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS,
1780 BitSet32(0), inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08001781
1782 // Done.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001783 return InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001784}
1785
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001786/**
1787 * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
1788 * that are currently unresponsive.
1789 */
1790std::vector<TouchedMonitor> InputDispatcher::selectResponsiveMonitorsLocked(
1791 const std::vector<TouchedMonitor>& monitors) const {
1792 std::vector<TouchedMonitor> responsiveMonitors;
1793 std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
1794 [this](const TouchedMonitor& monitor) REQUIRES(mLock) {
1795 sp<Connection> connection = getConnectionLocked(
1796 monitor.monitor.inputChannel->getConnectionToken());
1797 if (connection == nullptr) {
1798 ALOGE("Could not find connection for monitor %s",
1799 monitor.monitor.inputChannel->getName().c_str());
1800 return false;
1801 }
1802 if (!connection->responsive) {
1803 ALOGW("Unresponsive monitor %s will not get the new gesture",
1804 connection->inputChannel->getName().c_str());
1805 return false;
1806 }
1807 return true;
1808 });
1809 return responsiveMonitors;
1810}
1811
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001812InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
1813 nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
1814 nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001815 ATRACE_CALL();
Michael Wrightd02c5b62014-02-10 15:10:22 -08001816 enum InjectionPermission {
1817 INJECTION_PERMISSION_UNKNOWN,
1818 INJECTION_PERMISSION_GRANTED,
1819 INJECTION_PERMISSION_DENIED
1820 };
1821
Michael Wrightd02c5b62014-02-10 15:10:22 -08001822 // For security reasons, we defer updating the touch state until we are sure that
1823 // event injection will be allowed.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001824 int32_t displayId = entry.displayId;
1825 int32_t action = entry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001826 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1827
1828 // Update the touch state as needed based on the properties of the touch event.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001829 InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001830 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001831 sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
1832 sp<InputWindowHandle> newTouchedWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001833
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001834 // Copy current touch state into tempTouchState.
1835 // This state will be used to update mTouchStatesByDisplay at the end of this function.
1836 // If no state for the specified display exists, then our initial state will be empty.
Yi Kong9b14ac62018-07-17 13:48:38 -07001837 const TouchState* oldState = nullptr;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001838 TouchState tempTouchState;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07001839 std::unordered_map<int32_t, TouchState>::iterator oldStateIt =
1840 mTouchStatesByDisplay.find(displayId);
1841 if (oldStateIt != mTouchStatesByDisplay.end()) {
1842 oldState = &(oldStateIt->second);
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001843 tempTouchState.copyFrom(*oldState);
Jeff Brownf086ddb2014-02-11 14:28:48 -08001844 }
1845
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001846 bool isSplit = tempTouchState.split;
1847 bool switchedDevice = tempTouchState.deviceId >= 0 && tempTouchState.displayId >= 0 &&
1848 (tempTouchState.deviceId != entry.deviceId || tempTouchState.source != entry.source ||
1849 tempTouchState.displayId != displayId);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001850 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
1851 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
1852 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1853 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
1854 maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001855 const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001856 bool wrongDevice = false;
1857 if (newGesture) {
1858 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001859 if (switchedDevice && tempTouchState.down && !down && !isHoverAction) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001860 ALOGI("Dropping event because a pointer for a different device is already down "
1861 "in display %" PRId32,
1862 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001863 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001864 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001865 switchedDevice = false;
1866 wrongDevice = true;
1867 goto Failed;
1868 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001869 tempTouchState.reset();
1870 tempTouchState.down = down;
1871 tempTouchState.deviceId = entry.deviceId;
1872 tempTouchState.source = entry.source;
1873 tempTouchState.displayId = displayId;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001874 isSplit = false;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001875 } else if (switchedDevice && maskedAction == AMOTION_EVENT_ACTION_MOVE) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07001876 ALOGI("Dropping move event because a pointer for a different device is already active "
1877 "in display %" PRId32,
1878 displayId);
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001879 // TODO: test multiple simultaneous input streams.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001880 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Kevin Schoedel1eb587b2017-05-03 13:58:56 -04001881 switchedDevice = false;
1882 wrongDevice = true;
1883 goto Failed;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001884 }
1885
1886 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1887 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1888
Garfield Tan00f511d2019-06-12 16:55:40 -07001889 int32_t x;
1890 int32_t y;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001891 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
Garfield Tan00f511d2019-06-12 16:55:40 -07001892 // Always dispatch mouse events to cursor position.
1893 if (isFromMouse) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001894 x = int32_t(entry.xCursorPosition);
1895 y = int32_t(entry.yCursorPosition);
Garfield Tan00f511d2019-06-12 16:55:40 -07001896 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001897 x = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X));
1898 y = int32_t(entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y));
Garfield Tan00f511d2019-06-12 16:55:40 -07001899 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001900 bool isDown = maskedAction == AMOTION_EVENT_ACTION_DOWN;
Garfield Tandf26e862020-07-01 20:18:19 -07001901 newTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001902 findTouchedWindowAtLocked(displayId, x, y, &tempTouchState,
1903 isDown /*addOutsideTargets*/, true /*addPortalWindows*/);
Michael Wright3dd60e22019-03-27 22:06:44 +00001904
1905 std::vector<TouchedMonitor> newGestureMonitors = isDown
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001906 ? findTouchedGestureMonitorsLocked(displayId, tempTouchState.portalWindows)
Michael Wright3dd60e22019-03-27 22:06:44 +00001907 : std::vector<TouchedMonitor>{};
Michael Wrightd02c5b62014-02-10 15:10:22 -08001908
Michael Wrightd02c5b62014-02-10 15:10:22 -08001909 // Figure out whether splitting will be allowed for this window.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001910 if (newTouchedWindowHandle != nullptr &&
1911 newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
Garfield Tanaddb02b2019-06-25 16:36:13 -07001912 // New window supports splitting, but we should never split mouse events.
1913 isSplit = !isFromMouse;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001914 } else if (isSplit) {
1915 // New window does not support splitting but we have already split events.
1916 // Ignore the new window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001917 newTouchedWindowHandle = nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001918 }
1919
1920 // Handle the case where we did not find a window.
Yi Kong9b14ac62018-07-17 13:48:38 -07001921 if (newTouchedWindowHandle == nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08001922 // Try to assign the pointer to the first foreground window we find, if there is one.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001923 newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00001924 }
1925
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001926 if (newTouchedWindowHandle != nullptr && newTouchedWindowHandle->getInfo()->paused) {
1927 ALOGI("Not sending touch event to %s because it is paused",
1928 newTouchedWindowHandle->getName().c_str());
1929 newTouchedWindowHandle = nullptr;
1930 }
1931
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001932 // Ensure the window has a connection and the connection is responsive
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001933 if (newTouchedWindowHandle != nullptr) {
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05001934 const bool isResponsive = hasResponsiveConnectionLocked(*newTouchedWindowHandle);
1935 if (!isResponsive) {
1936 ALOGW("%s will not receive the new gesture at %" PRIu64,
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001937 newTouchedWindowHandle->getName().c_str(), entry.eventTime);
1938 newTouchedWindowHandle = nullptr;
1939 }
1940 }
1941
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001942 // Drop events that can't be trusted due to occlusion
1943 if (newTouchedWindowHandle != nullptr &&
1944 mBlockUntrustedTouchesMode != BlockUntrustedTouchesMode::DISABLED) {
1945 TouchOcclusionInfo occlusionInfo =
1946 computeTouchOcclusionInfoLocked(newTouchedWindowHandle, x, y);
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001947 if (!isTouchTrustedLocked(occlusionInfo)) {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00001948 if (DEBUG_TOUCH_OCCLUSION) {
1949 ALOGD("Stack of obscuring windows during untrusted touch (%d, %d):", x, y);
1950 for (const auto& log : occlusionInfo.debugInfo) {
1951 ALOGD("%s", log.c_str());
1952 }
1953 }
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00001954 onUntrustedTouchLocked(occlusionInfo.obscuringPackage);
1955 if (mBlockUntrustedTouchesMode == BlockUntrustedTouchesMode::BLOCK) {
1956 ALOGW("Dropping untrusted touch event due to %s/%d",
1957 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid);
1958 newTouchedWindowHandle = nullptr;
1959 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01001960 }
1961 }
1962
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07001963 // Also don't send the new touch event to unresponsive gesture monitors
1964 newGestureMonitors = selectResponsiveMonitorsLocked(newGestureMonitors);
1965
Michael Wright3dd60e22019-03-27 22:06:44 +00001966 if (newTouchedWindowHandle == nullptr && newGestureMonitors.empty()) {
1967 ALOGI("Dropping event because there is no touchable window or gesture monitor at "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07001968 "(%d, %d) in display %" PRId32 ".",
1969 x, y, displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08001970 injectionResult = InputEventInjectionResult::FAILED;
Michael Wright3dd60e22019-03-27 22:06:44 +00001971 goto Failed;
1972 }
1973
1974 if (newTouchedWindowHandle != nullptr) {
1975 // Set target flags.
1976 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
1977 if (isSplit) {
1978 targetFlags |= InputTarget::FLAG_SPLIT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08001979 }
Michael Wright3dd60e22019-03-27 22:06:44 +00001980 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
1981 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1982 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
1983 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
1984 }
1985
1986 // Update hover state.
Garfield Tandf26e862020-07-01 20:18:19 -07001987 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
1988 newHoverWindowHandle = nullptr;
1989 } else if (isHoverAction) {
Michael Wright3dd60e22019-03-27 22:06:44 +00001990 newHoverWindowHandle = newTouchedWindowHandle;
Michael Wright3dd60e22019-03-27 22:06:44 +00001991 }
1992
1993 // Update the temporary touch state.
1994 BitSet32 pointerIds;
1995 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07001996 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wright3dd60e22019-03-27 22:06:44 +00001997 pointerIds.markBit(pointerId);
1998 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07001999 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002000 }
2001
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002002 tempTouchState.addGestureMonitors(newGestureMonitors);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002003 } else {
2004 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2005
2006 // If the pointer is not currently down, then ignore the event.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002007 if (!tempTouchState.down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002008 if (DEBUG_FOCUS) {
2009 ALOGD("Dropping event because the pointer is not down or we previously "
2010 "dropped the pointer down event in display %" PRId32,
2011 displayId);
2012 }
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002013 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002014 goto Failed;
2015 }
2016
2017 // Check whether touches should slip outside of the current foreground window.
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002018 if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002019 tempTouchState.isSlippery()) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002020 int32_t x = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
2021 int32_t y = int32_t(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002022
2023 sp<InputWindowHandle> oldTouchedWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002024 tempTouchState.getFirstForegroundWindowHandle();
Garfield Tandf26e862020-07-01 20:18:19 -07002025 newTouchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y, &tempTouchState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002026 if (oldTouchedWindowHandle != newTouchedWindowHandle &&
2027 oldTouchedWindowHandle != nullptr && newTouchedWindowHandle != nullptr) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002028 if (DEBUG_FOCUS) {
2029 ALOGD("Touch is slipping out of window %s into window %s in display %" PRId32,
2030 oldTouchedWindowHandle->getName().c_str(),
2031 newTouchedWindowHandle->getName().c_str(), displayId);
2032 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002033 // Make a slippery exit from the old window.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002034 tempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
2035 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT,
2036 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002037
2038 // Make a slippery entrance into the new window.
2039 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2040 isSplit = true;
2041 }
2042
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002043 int32_t targetFlags =
2044 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002045 if (isSplit) {
2046 targetFlags |= InputTarget::FLAG_SPLIT;
2047 }
2048 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2049 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
Siarhei Vishniakou870ecec2020-12-09 08:07:46 -10002050 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2051 targetFlags |= InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002052 }
2053
2054 BitSet32 pointerIds;
2055 if (isSplit) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002056 pointerIds.markBit(entry.pointerProperties[0].id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002057 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002058 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002059 }
2060 }
2061 }
2062
2063 if (newHoverWindowHandle != mLastHoverWindowHandle) {
Garfield Tandf26e862020-07-01 20:18:19 -07002064 // Let the previous window know that the hover sequence is over, unless we already did it
2065 // when dispatching it as is to newTouchedWindowHandle.
2066 if (mLastHoverWindowHandle != nullptr &&
2067 (maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT ||
2068 mLastHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002069#if DEBUG_HOVER
2070 ALOGD("Sending hover exit event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002071 mLastHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002072#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002073 tempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
2074 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002075 }
2076
Garfield Tandf26e862020-07-01 20:18:19 -07002077 // Let the new window know that the hover sequence is starting, unless we already did it
2078 // when dispatching it as is to newTouchedWindowHandle.
2079 if (newHoverWindowHandle != nullptr &&
2080 (maskedAction != AMOTION_EVENT_ACTION_HOVER_ENTER ||
2081 newHoverWindowHandle != newTouchedWindowHandle)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002082#if DEBUG_HOVER
2083 ALOGD("Sending hover enter event to window %s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002084 newHoverWindowHandle->getName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002085#endif
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002086 tempTouchState.addOrUpdateWindow(newHoverWindowHandle,
2087 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER,
2088 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002089 }
2090 }
2091
2092 // Check permission to inject into all touched foreground windows and ensure there
2093 // is at least one touched foreground window.
2094 {
2095 bool haveForegroundWindow = false;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002096 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002097 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
2098 haveForegroundWindow = true;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002099 if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002100 injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002101 injectionPermission = INJECTION_PERMISSION_DENIED;
2102 goto Failed;
2103 }
2104 }
2105 }
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002106 bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
Michael Wright3dd60e22019-03-27 22:06:44 +00002107 if (!haveForegroundWindow && !hasGestureMonitor) {
Siarhei Vishniakouf0007dd2020-04-13 11:40:37 -07002108 ALOGI("Dropping event because there is no touched foreground window in display "
2109 "%" PRId32 " or gesture monitor to receive it.",
2110 displayId);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002111 injectionResult = InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002112 goto Failed;
2113 }
2114
2115 // Permission granted to injection into all touched foreground windows.
2116 injectionPermission = INJECTION_PERMISSION_GRANTED;
2117 }
2118
2119 // Check whether windows listening for outside touches are owned by the same UID. If it is
2120 // set the policy flag that we will not reveal coordinate information to this window.
2121 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2122 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002123 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002124 if (foregroundWindowHandle) {
2125 const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002126 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002127 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2128 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
2129 if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002130 tempTouchState.addOrUpdateWindow(inputWindowHandle,
2131 InputTarget::FLAG_ZERO_COORDS,
2132 BitSet32(0));
Michael Wright3dd60e22019-03-27 22:06:44 +00002133 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002134 }
2135 }
2136 }
2137 }
2138
Michael Wrightd02c5b62014-02-10 15:10:22 -08002139 // If this is the first pointer going down and the touched window has a wallpaper
2140 // then also add the touched wallpaper windows so they are locked in for the duration
2141 // of the touch gesture.
2142 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
2143 // engine only supports touch events. We would need to add a mechanism similar
2144 // to View.onGenericMotionEvent to enable wallpapers to handle these events.
2145 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2146 sp<InputWindowHandle> foregroundWindowHandle =
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002147 tempTouchState.getFirstForegroundWindowHandle();
Michael Wright3dd60e22019-03-27 22:06:44 +00002148 if (foregroundWindowHandle && foregroundWindowHandle->getInfo()->hasWallpaper) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07002149 const std::vector<sp<InputWindowHandle>>& windowHandles =
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002150 getWindowHandlesLocked(displayId);
2151 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002152 const InputWindowInfo* info = windowHandle->getInfo();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002153 if (info->displayId == displayId &&
Michael Wright44753b12020-07-08 13:48:11 +01002154 windowHandle->getInfo()->type == InputWindowInfo::Type::WALLPAPER) {
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002155 tempTouchState
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002156 .addOrUpdateWindow(windowHandle,
2157 InputTarget::FLAG_WINDOW_IS_OBSCURED |
2158 InputTarget::
2159 FLAG_WINDOW_IS_PARTIALLY_OBSCURED |
2160 InputTarget::FLAG_DISPATCH_AS_IS,
2161 BitSet32(0));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002162 }
2163 }
2164 }
2165 }
2166
2167 // Success! Output targets.
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08002168 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002169
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002170 for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002171 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002172 touchedWindow.pointerIds, inputTargets);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002173 }
2174
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002175 for (const TouchedMonitor& touchedMonitor : tempTouchState.gestureMonitors) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002176 addMonitoringTargetLocked(touchedMonitor.monitor, touchedMonitor.xOffset,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002177 touchedMonitor.yOffset, inputTargets);
Michael Wright3dd60e22019-03-27 22:06:44 +00002178 }
2179
Michael Wrightd02c5b62014-02-10 15:10:22 -08002180 // Drop the outside or hover touch windows since we will not care about them
2181 // in the next iteration.
Siarhei Vishniakou33eceeb2020-03-24 19:50:03 -07002182 tempTouchState.filterNonAsIsTouchWindows();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002183
2184Failed:
2185 // Check injection permission once and for all.
2186 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002187 if (checkInjectionPermission(nullptr, entry.injectionState)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002188 injectionPermission = INJECTION_PERMISSION_GRANTED;
2189 } else {
2190 injectionPermission = INJECTION_PERMISSION_DENIED;
2191 }
2192 }
2193
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002194 if (injectionPermission != INJECTION_PERMISSION_GRANTED) {
2195 return injectionResult;
2196 }
2197
Michael Wrightd02c5b62014-02-10 15:10:22 -08002198 // Update final pieces of touch state if the injector had permission.
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002199 if (!wrongDevice) {
2200 if (switchedDevice) {
2201 if (DEBUG_FOCUS) {
2202 ALOGD("Conflicting pointer actions: Switched to a different device.");
2203 }
2204 *outConflictingPointerActions = true;
2205 }
2206
2207 if (isHoverAction) {
2208 // Started hovering, therefore no longer down.
2209 if (oldState && oldState->down) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002210 if (DEBUG_FOCUS) {
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002211 ALOGD("Conflicting pointer actions: Hover received while pointer was "
2212 "down.");
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002213 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002214 *outConflictingPointerActions = true;
2215 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002216 tempTouchState.reset();
2217 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2218 maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2219 tempTouchState.deviceId = entry.deviceId;
2220 tempTouchState.source = entry.source;
2221 tempTouchState.displayId = displayId;
2222 }
2223 } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
2224 maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2225 // All pointers up or canceled.
2226 tempTouchState.reset();
2227 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2228 // First pointer went down.
2229 if (oldState && oldState->down) {
2230 if (DEBUG_FOCUS) {
2231 ALOGD("Conflicting pointer actions: Down received while already down.");
2232 }
2233 *outConflictingPointerActions = true;
2234 }
2235 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2236 // One pointer went up.
2237 if (isSplit) {
2238 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
2239 uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002240
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002241 for (size_t i = 0; i < tempTouchState.windows.size();) {
2242 TouchedWindow& touchedWindow = tempTouchState.windows[i];
2243 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
2244 touchedWindow.pointerIds.clearBit(pointerId);
2245 if (touchedWindow.pointerIds.isEmpty()) {
2246 tempTouchState.windows.erase(tempTouchState.windows.begin() + i);
2247 continue;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002248 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002249 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002250 i += 1;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002251 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002252 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002253 }
Jeff Brownf086ddb2014-02-11 14:28:48 -08002254
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002255 // Save changes unless the action was scroll in which case the temporary touch
2256 // state was only valid for this one action.
2257 if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2258 if (tempTouchState.displayId >= 0) {
2259 mTouchStatesByDisplay[displayId] = tempTouchState;
2260 } else {
2261 mTouchStatesByDisplay.erase(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002262 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002263 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002264
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07002265 // Update hover state.
2266 mLastHoverWindowHandle = newHoverWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002267 }
2268
Michael Wrightd02c5b62014-02-10 15:10:22 -08002269 return injectionResult;
2270}
2271
2272void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002273 int32_t targetFlags, BitSet32 pointerIds,
2274 std::vector<InputTarget>& inputTargets) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002275 std::vector<InputTarget>::iterator it =
2276 std::find_if(inputTargets.begin(), inputTargets.end(),
2277 [&windowHandle](const InputTarget& inputTarget) {
2278 return inputTarget.inputChannel->getConnectionToken() ==
2279 windowHandle->getToken();
2280 });
Chavi Weingarten97b8eec2020-01-09 18:09:08 +00002281
Chavi Weingarten114b77f2020-01-15 22:35:10 +00002282 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002283
2284 if (it == inputTargets.end()) {
2285 InputTarget inputTarget;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05002286 std::shared_ptr<InputChannel> inputChannel =
2287 getInputChannelLocked(windowHandle->getToken());
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002288 if (inputChannel == nullptr) {
2289 ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
2290 return;
2291 }
2292 inputTarget.inputChannel = inputChannel;
2293 inputTarget.flags = targetFlags;
2294 inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
2295 inputTargets.push_back(inputTarget);
2296 it = inputTargets.end() - 1;
2297 }
2298
2299 ALOG_ASSERT(it->flags == targetFlags);
2300 ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
2301
chaviw1ff3d1e2020-07-01 15:53:47 -07002302 it->addPointers(pointerIds, windowInfo->transform);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002303}
2304
Michael Wright3dd60e22019-03-27 22:06:44 +00002305void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002306 int32_t displayId, float xOffset,
2307 float yOffset) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002308 std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
2309 mGlobalMonitorsByDisplay.find(displayId);
2310
2311 if (it != mGlobalMonitorsByDisplay.end()) {
2312 const std::vector<Monitor>& monitors = it->second;
2313 for (const Monitor& monitor : monitors) {
2314 addMonitoringTargetLocked(monitor, xOffset, yOffset, inputTargets);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08002315 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002316 }
2317}
2318
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002319void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xOffset,
2320 float yOffset,
2321 std::vector<InputTarget>& inputTargets) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002322 InputTarget target;
2323 target.inputChannel = monitor.inputChannel;
2324 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
chaviw1ff3d1e2020-07-01 15:53:47 -07002325 ui::Transform t;
2326 t.set(xOffset, yOffset);
2327 target.setDefaultPointerTransform(t);
Michael Wright3dd60e22019-03-27 22:06:44 +00002328 inputTargets.push_back(target);
2329}
2330
Michael Wrightd02c5b62014-02-10 15:10:22 -08002331bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002332 const InjectionState* injectionState) {
2333 if (injectionState &&
2334 (windowHandle == nullptr ||
2335 windowHandle->getInfo()->ownerUid != injectionState->injectorUid) &&
2336 !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002337 if (windowHandle != nullptr) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002338 ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002339 "owned by uid %d",
2340 injectionState->injectorPid, injectionState->injectorUid,
2341 windowHandle->getName().c_str(), windowHandle->getInfo()->ownerUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002342 } else {
2343 ALOGW("Permission denied: injecting event from pid %d uid %d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002344 injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002345 }
2346 return false;
2347 }
2348 return true;
2349}
2350
Robert Carrc9bf1d32020-04-13 17:21:08 -07002351/**
2352 * Indicate whether one window handle should be considered as obscuring
2353 * another window handle. We only check a few preconditions. Actually
2354 * checking the bounds is left to the caller.
2355 */
2356static bool canBeObscuredBy(const sp<InputWindowHandle>& windowHandle,
2357 const sp<InputWindowHandle>& otherHandle) {
2358 // Compare by token so cloned layers aren't counted
2359 if (haveSameToken(windowHandle, otherHandle)) {
2360 return false;
2361 }
2362 auto info = windowHandle->getInfo();
2363 auto otherInfo = otherHandle->getInfo();
2364 if (!otherInfo->visible) {
2365 return false;
Bernardo Rufino653d2e02020-10-20 17:32:40 +00002366 } else if (otherInfo->alpha == 0 &&
2367 otherInfo->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE)) {
2368 // Those act as if they were invisible, so we don't need to flag them.
2369 // We do want to potentially flag touchable windows even if they have 0
2370 // opacity, since they can consume touches and alter the effects of the
2371 // user interaction (eg. apps that rely on
2372 // FLAG_WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
2373 // windows), hence we also check for FLAG_NOT_TOUCHABLE.
2374 return false;
Bernardo Rufino8007daf2020-09-22 09:40:01 +00002375 } else if (info->ownerUid == otherInfo->ownerUid) {
2376 // If ownerUid is the same we don't generate occlusion events as there
2377 // is no security boundary within an uid.
Robert Carrc9bf1d32020-04-13 17:21:08 -07002378 return false;
Chris Yefcdff3e2020-05-10 15:16:04 -07002379 } else if (otherInfo->trustedOverlay) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002380 return false;
2381 } else if (otherInfo->displayId != info->displayId) {
2382 return false;
2383 }
2384 return true;
2385}
2386
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002387/**
2388 * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
2389 * untrusted, one should check:
2390 *
2391 * 1. If result.hasBlockingOcclusion is true.
2392 * If it's, it means the touch should be blocked due to a window with occlusion mode of
2393 * BLOCK_UNTRUSTED.
2394 *
2395 * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
2396 * If it is (and 1 is false), then the touch should be blocked because a stack of windows
2397 * (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
2398 * obscuring opacity above the threshold. Note that if there was no window of occlusion mode
2399 * USE_OPACITY, result.obscuringOpacity would've been 0 and since
2400 * mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
2401 *
2402 * If neither of those is true, then it means the touch can be allowed.
2403 */
2404InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
2405 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002406 const InputWindowInfo* windowInfo = windowHandle->getInfo();
2407 int32_t displayId = windowInfo->displayId;
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002408 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
2409 TouchOcclusionInfo info;
2410 info.hasBlockingOcclusion = false;
2411 info.obscuringOpacity = 0;
2412 info.obscuringUid = -1;
2413 std::map<int32_t, float> opacityByUid;
2414 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
2415 if (windowHandle == otherHandle) {
2416 break; // All future windows are below us. Exit early.
2417 }
2418 const InputWindowInfo* otherInfo = otherHandle->getInfo();
2419 if (canBeObscuredBy(windowHandle, otherHandle) &&
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002420 windowInfo->ownerUid != otherInfo->ownerUid && otherInfo->frameContainsPoint(x, y)) {
2421 if (DEBUG_TOUCH_OCCLUSION) {
2422 info.debugInfo.push_back(
2423 dumpWindowForTouchOcclusion(otherInfo, /* isTouchedWindow */ false));
2424 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002425 // canBeObscuredBy() has returned true above, which means this window is untrusted, so
2426 // we perform the checks below to see if the touch can be propagated or not based on the
2427 // window's touch occlusion mode
2428 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
2429 info.hasBlockingOcclusion = true;
2430 info.obscuringUid = otherInfo->ownerUid;
2431 info.obscuringPackage = otherInfo->packageName;
2432 break;
2433 }
2434 if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
2435 uint32_t uid = otherInfo->ownerUid;
2436 float opacity =
2437 (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
2438 // Given windows A and B:
2439 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
2440 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
2441 opacityByUid[uid] = opacity;
2442 if (opacity > info.obscuringOpacity) {
2443 info.obscuringOpacity = opacity;
2444 info.obscuringUid = uid;
2445 info.obscuringPackage = otherInfo->packageName;
2446 }
2447 }
2448 }
2449 }
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002450 if (DEBUG_TOUCH_OCCLUSION) {
2451 info.debugInfo.push_back(
2452 dumpWindowForTouchOcclusion(windowInfo, /* isTouchedWindow */ true));
2453 }
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002454 return info;
2455}
2456
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002457std::string InputDispatcher::dumpWindowForTouchOcclusion(const InputWindowInfo* info,
2458 bool isTouchedWindow) const {
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002459 return StringPrintf(INDENT2 "* %stype=%s, package=%s/%" PRId32 ", id=%" PRId32
2460 ", mode=%s, alpha=%.2f, "
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002461 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
2462 "], touchableRegion=%s, window={%s}, applicationInfo=%s, "
2463 "flags={%s}, inputFeatures={%s}, hasToken=%s\n",
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002464 (isTouchedWindow) ? "[TOUCHED] " : "",
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002465 NamedEnum::string(info->type, "%" PRId32).c_str(),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00002466 info->packageName.c_str(), info->ownerUid, info->id,
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00002467 toString(info->touchOcclusionMode).c_str(), info->alpha, info->frameLeft,
2468 info->frameTop, info->frameRight, info->frameBottom,
2469 dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00002470 info->applicationInfo.name.c_str(), info->flags.string().c_str(),
2471 info->inputFeatures.string().c_str(), toString(info->token != nullptr));
Bernardo Rufino4bae0ac2020-10-14 18:33:46 +00002472}
2473
Bernardo Rufinoea97d182020-08-19 14:43:14 +01002474bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
2475 if (occlusionInfo.hasBlockingOcclusion) {
2476 ALOGW("Untrusted touch due to occlusion by %s/%d", occlusionInfo.obscuringPackage.c_str(),
2477 occlusionInfo.obscuringUid);
2478 return false;
2479 }
2480 if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
2481 ALOGW("Untrusted touch due to occlusion by %s/%d (obscuring opacity = "
2482 "%.2f, maximum allowed = %.2f)",
2483 occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid,
2484 occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
2485 return false;
2486 }
2487 return true;
2488}
2489
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002490bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
2491 int32_t x, int32_t y) const {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002492 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002493 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002494 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002495 if (windowHandle == otherHandle) {
2496 break; // All future windows are below us. Exit early.
Michael Wrightd02c5b62014-02-10 15:10:22 -08002497 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002498 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002499 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002500 otherInfo->frameContainsPoint(x, y)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002501 return true;
2502 }
2503 }
2504 return false;
2505}
2506
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002507bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
2508 int32_t displayId = windowHandle->getInfo()->displayId;
Vishnu Nairad321cd2020-08-20 16:40:21 -07002509 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002510 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08002511 for (const sp<InputWindowHandle>& otherHandle : windowHandles) {
Robert Carrc9bf1d32020-04-13 17:21:08 -07002512 if (windowHandle == otherHandle) {
2513 break; // All future windows are below us. Exit early.
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002514 }
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002515 const InputWindowInfo* otherInfo = otherHandle->getInfo();
Robert Carrc9bf1d32020-04-13 17:21:08 -07002516 if (canBeObscuredBy(windowHandle, otherHandle) &&
minchelif28cc4e2020-03-19 11:18:11 +08002517 otherInfo->overlaps(windowInfo)) {
Michael Wrightcdcd8f22016-03-22 16:52:13 -07002518 return true;
2519 }
2520 }
2521 return false;
2522}
2523
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002524std::string InputDispatcher::getApplicationWindowLabel(
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05002525 const InputApplicationHandle* applicationHandle,
Michael Wrightd02c5b62014-02-10 15:10:22 -08002526 const sp<InputWindowHandle>& windowHandle) {
Yi Kong9b14ac62018-07-17 13:48:38 -07002527 if (applicationHandle != nullptr) {
2528 if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002529 return applicationHandle->getName() + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002530 } else {
2531 return applicationHandle->getName();
2532 }
Yi Kong9b14ac62018-07-17 13:48:38 -07002533 } else if (windowHandle != nullptr) {
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07002534 return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002535 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002536 return "<unknown application or window>";
Michael Wrightd02c5b62014-02-10 15:10:22 -08002537 }
2538}
2539
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002540void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
Prabir Pradhan99987712020-11-10 18:43:05 -08002541 if (eventEntry.type == EventEntry::Type::FOCUS ||
2542 eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
2543 // Focus or pointer capture changed events are passed to apps, but do not represent user
2544 // activity.
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002545 return;
2546 }
Tiger Huang721e26f2018-07-24 22:26:19 +08002547 int32_t displayId = getTargetDisplayId(eventEntry);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002548 sp<InputWindowHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
Tiger Huang721e26f2018-07-24 22:26:19 +08002549 if (focusedWindowHandle != nullptr) {
2550 const InputWindowInfo* info = focusedWindowHandle->getInfo();
Michael Wright44753b12020-07-08 13:48:11 +01002551 if (info->inputFeatures.test(InputWindowInfo::Feature::DISABLE_USER_ACTIVITY)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002552#if DEBUG_DISPATCH_CYCLE
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08002553 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002554#endif
2555 return;
2556 }
2557 }
2558
2559 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002560 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002561 case EventEntry::Type::MOTION: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002562 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2563 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002564 return;
2565 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002566
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002567 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002568 eventType = USER_ACTIVITY_EVENT_TOUCH;
2569 }
2570 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002571 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002572 case EventEntry::Type::KEY: {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002573 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2574 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002575 return;
2576 }
2577 eventType = USER_ACTIVITY_EVENT_BUTTON;
2578 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002579 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002580 case EventEntry::Type::FOCUS:
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002581 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08002582 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07002583 case EventEntry::Type::SENSOR:
Prabir Pradhan99987712020-11-10 18:43:05 -08002584 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002585 LOG_ALWAYS_FATAL("%s events are not user activity",
Chris Yef59a2f42020-10-16 12:55:26 -07002586 NamedEnum::string(eventEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002587 break;
2588 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002589 }
2590
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002591 std::unique_ptr<CommandEntry> commandEntry =
2592 std::make_unique<CommandEntry>(&InputDispatcher::doPokeUserActivityLockedInterruptible);
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002593 commandEntry->eventTime = eventEntry.eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002594 commandEntry->userActivityEventType = eventType;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002595 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002596}
2597
2598void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002599 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002600 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002601 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002602 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002603 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002604 StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002605 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002606 ATRACE_NAME(message.c_str());
2607 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002608#if DEBUG_DISPATCH_CYCLE
2609 ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002610 "globalScaleFactor=%f, pointerIds=0x%x %s",
2611 connection->getInputChannelName().c_str(), inputTarget.flags,
2612 inputTarget.globalScaleFactor, inputTarget.pointerIds.value,
2613 inputTarget.getPointerInfoString().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002614#endif
2615
2616 // Skip this event if the connection status is not normal.
2617 // We don't want to enqueue additional outbound events if the connection is broken.
2618 if (connection->status != Connection::STATUS_NORMAL) {
2619#if DEBUG_DISPATCH_CYCLE
2620 ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002621 connection->getInputChannelName().c_str(), connection->getStatusLabel());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002622#endif
2623 return;
2624 }
2625
2626 // Split a motion event if needed.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002627 if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
2628 LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
2629 "Entry type %s should not have FLAG_SPLIT",
Chris Yef59a2f42020-10-16 12:55:26 -07002630 NamedEnum::string(eventEntry->type).c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002631
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002632 const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002633 if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002634 std::unique_ptr<MotionEntry> splitMotionEntry =
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002635 splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002636 if (!splitMotionEntry) {
2637 return; // split event was dropped
2638 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002639 if (DEBUG_FOCUS) {
2640 ALOGD("channel '%s' ~ Split motion event.",
2641 connection->getInputChannelName().c_str());
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002642 logOutboundMotionDetails(" ", *splitMotionEntry);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01002643 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002644 enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
2645 inputTarget);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002646 return;
2647 }
2648 }
2649
2650 // Not splitting. Enqueue dispatch entries for the event as is.
2651 enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
2652}
2653
2654void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002655 const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002656 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002657 const InputTarget& inputTarget) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002658 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002659 std::string message =
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002660 StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, id=0x%" PRIx32 ")",
Garfield Tan6a5a14e2020-01-28 13:24:04 -08002661 connection->getInputChannelName().c_str(), eventEntry->id);
Michael Wright3dd60e22019-03-27 22:06:44 +00002662 ATRACE_NAME(message.c_str());
2663 }
2664
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002665 bool wasEmpty = connection->outboundQueue.empty();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002666
2667 // Enqueue dispatch entries for the requested modes.
chaviw8c9cf542019-03-25 13:02:48 -07002668 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002669 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002670 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002671 InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
chaviw8c9cf542019-03-25 13:02:48 -07002672 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002673 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
chaviw8c9cf542019-03-25 13:02:48 -07002674 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002675 InputTarget::FLAG_DISPATCH_AS_IS);
chaviw8c9cf542019-03-25 13:02:48 -07002676 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002677 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
chaviw8c9cf542019-03-25 13:02:48 -07002678 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002679 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002680
2681 // If the outbound queue was previously empty, start the dispatch cycle going.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002682 if (wasEmpty && !connection->outboundQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002683 startDispatchCycleLocked(currentTime, connection);
2684 }
2685}
2686
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002687void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002688 std::shared_ptr<EventEntry> eventEntry,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002689 const InputTarget& inputTarget,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002690 int32_t dispatchMode) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002691 if (ATRACE_ENABLED()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002692 std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
2693 connection->getInputChannelName().c_str(),
2694 dispatchModeToString(dispatchMode).c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002695 ATRACE_NAME(message.c_str());
2696 }
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002697 int32_t inputTargetFlags = inputTarget.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002698 if (!(inputTargetFlags & dispatchMode)) {
2699 return;
2700 }
2701 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2702
2703 // This is a new event.
2704 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002705 std::unique_ptr<DispatchEntry> dispatchEntry =
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002706 createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002707
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002708 // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
2709 // different EventEntry than what was passed in.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002710 EventEntry& newEntry = *(dispatchEntry->eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002711 // Apply target flags and update the connection's input state.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002712 switch (newEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002713 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002714 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002715 dispatchEntry->resolvedEventId = keyEntry.id;
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002716 dispatchEntry->resolvedAction = keyEntry.action;
2717 dispatchEntry->resolvedFlags = keyEntry.flags;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002718
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002719 if (!connection->inputState.trackKey(keyEntry, dispatchEntry->resolvedAction,
2720 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002721#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002722 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
2723 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002724#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002725 return; // skip the inconsistent event
2726 }
2727 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002728 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002729
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002730 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002731 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002732 // Assign a default value to dispatchEntry that will never be generated by InputReader,
2733 // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
2734 constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
2735 static_cast<int32_t>(IdGenerator::Source::OTHER);
2736 dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002737 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2738 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
2739 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
2740 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
2741 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
2742 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2743 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
2744 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
2745 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
2746 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
2747 } else {
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002748 dispatchEntry->resolvedAction = motionEntry.action;
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002749 dispatchEntry->resolvedEventId = motionEntry.id;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002750 }
2751 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002752 !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
2753 motionEntry.displayId)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002754#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002755 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
2756 "event",
2757 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002758#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002759 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
2760 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002761
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002762 dispatchEntry->resolvedFlags = motionEntry.flags;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002763 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
2764 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
2765 }
2766 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
2767 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
2768 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002769
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002770 if (!connection->inputState.trackMotion(motionEntry, dispatchEntry->resolvedAction,
2771 dispatchEntry->resolvedFlags)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08002772#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002773 ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion "
2774 "event",
2775 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002776#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002777 return; // skip the inconsistent event
2778 }
2779
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002780 dispatchEntry->resolvedEventId =
2781 dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
2782 ? mIdGenerator.nextId()
2783 : motionEntry.id;
2784 if (ATRACE_ENABLED() && dispatchEntry->resolvedEventId != motionEntry.id) {
2785 std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
2786 ") to MotionEvent(id=0x%" PRIx32 ").",
2787 motionEntry.id, dispatchEntry->resolvedEventId);
2788 ATRACE_NAME(message.c_str());
2789 }
2790
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07002791 dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002792 inputTarget.inputChannel->getConnectionToken());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002793
2794 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002795 }
Prabir Pradhan99987712020-11-10 18:43:05 -08002796 case EventEntry::Type::FOCUS:
2797 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01002798 break;
2799 }
Chris Yef59a2f42020-10-16 12:55:26 -07002800 case EventEntry::Type::SENSOR: {
2801 LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
2802 break;
2803 }
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002804 case EventEntry::Type::CONFIGURATION_CHANGED:
2805 case EventEntry::Type::DEVICE_RESET: {
2806 LOG_ALWAYS_FATAL("%s events should not go to apps",
Chris Yef59a2f42020-10-16 12:55:26 -07002807 NamedEnum::string(newEntry.type).c_str());
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002808 break;
2809 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002810 }
2811
2812 // Remember that we are waiting for this dispatch to complete.
2813 if (dispatchEntry->hasForegroundTarget()) {
Chavi Weingarten65f98b82020-01-16 18:56:50 +00002814 incrementPendingForegroundDispatches(newEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002815 }
2816
2817 // Enqueue the dispatch entry.
Siarhei Vishniakou5d6b6612020-01-08 16:03:04 -08002818 connection->outboundQueue.push_back(dispatchEntry.release());
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08002819 traceOutboundQueueLength(connection);
chaviw8c9cf542019-03-25 13:02:48 -07002820}
2821
Siarhei Vishniakou887b7d92020-06-18 00:43:02 +00002822/**
2823 * This function is purely for debugging. It helps us understand where the user interaction
2824 * was taking place. For example, if user is touching launcher, we will see a log that user
2825 * started interacting with launcher. In that example, the event would go to the wallpaper as well.
2826 * We will see both launcher and wallpaper in that list.
2827 * Once the interaction with a particular set of connections starts, no new logs will be printed
2828 * until the set of interacted connections changes.
2829 *
2830 * The following items are skipped, to reduce the logspam:
2831 * ACTION_OUTSIDE: any windows that are receiving ACTION_OUTSIDE are not logged
2832 * ACTION_UP: any windows that receive ACTION_UP are not logged (for both keys and motions).
2833 * This includes situations like the soft BACK button key. When the user releases (lifts up the
2834 * finger) the back button, then navigation bar will inject KEYCODE_BACK with ACTION_UP.
2835 * Both of those ACTION_UP events would not be logged
2836 * Monitors (both gesture and global): any gesture monitors or global monitors receiving events
2837 * will not be logged. This is omitted to reduce the amount of data printed.
2838 * If you see <none>, it's likely that one of the gesture monitors pilfered the event, and therefore
2839 * gesture monitor is the only connection receiving the remainder of the gesture.
2840 */
2841void InputDispatcher::updateInteractionTokensLocked(const EventEntry& entry,
2842 const std::vector<InputTarget>& targets) {
2843 // Skip ACTION_UP events, and all events other than keys and motions
2844 if (entry.type == EventEntry::Type::KEY) {
2845 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2846 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
2847 return;
2848 }
2849 } else if (entry.type == EventEntry::Type::MOTION) {
2850 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2851 if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
2852 motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2853 return;
2854 }
2855 } else {
2856 return; // Not a key or a motion
2857 }
2858
2859 std::unordered_set<sp<IBinder>, IBinderHash> newConnectionTokens;
2860 std::vector<sp<Connection>> newConnections;
2861 for (const InputTarget& target : targets) {
2862 if ((target.flags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) ==
2863 InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
2864 continue; // Skip windows that receive ACTION_OUTSIDE
2865 }
2866
2867 sp<IBinder> token = target.inputChannel->getConnectionToken();
2868 sp<Connection> connection = getConnectionLocked(token);
2869 if (connection == nullptr || connection->monitor) {
2870 continue; // We only need to keep track of the non-monitor connections.
2871 }
2872 newConnectionTokens.insert(std::move(token));
2873 newConnections.emplace_back(connection);
2874 }
2875 if (newConnectionTokens == mInteractionConnectionTokens) {
2876 return; // no change
2877 }
2878 mInteractionConnectionTokens = newConnectionTokens;
2879
2880 std::string windowList;
2881 for (const sp<Connection>& connection : newConnections) {
2882 windowList += connection->getWindowName() + ", ";
2883 }
2884 std::string message = "Interaction with windows: " + windowList;
2885 if (windowList.empty()) {
2886 message += "<none>";
2887 }
2888 android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
2889}
2890
chaviwfd6d3512019-03-25 13:23:49 -07002891void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
Vishnu Nairad321cd2020-08-20 16:40:21 -07002892 const sp<IBinder>& token) {
chaviw8c9cf542019-03-25 13:02:48 -07002893 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
chaviwfd6d3512019-03-25 13:23:49 -07002894 uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
2895 if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
chaviw8c9cf542019-03-25 13:02:48 -07002896 return;
2897 }
2898
Vishnu Nairad321cd2020-08-20 16:40:21 -07002899 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
2900 if (focusedToken == token) {
2901 // ignore since token is focused
chaviw8c9cf542019-03-25 13:02:48 -07002902 return;
2903 }
2904
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002905 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
2906 &InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible);
Vishnu Nairad321cd2020-08-20 16:40:21 -07002907 commandEntry->newToken = token;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07002908 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08002909}
2910
2911void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002912 const sp<Connection>& connection) {
Michael Wright3dd60e22019-03-27 22:06:44 +00002913 if (ATRACE_ENABLED()) {
2914 std::string message = StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002915 connection->getInputChannelName().c_str());
Michael Wright3dd60e22019-03-27 22:06:44 +00002916 ATRACE_NAME(message.c_str());
2917 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08002918#if DEBUG_DISPATCH_CYCLE
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002919 ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08002920#endif
2921
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07002922 while (connection->status == Connection::STATUS_NORMAL && !connection->outboundQueue.empty()) {
2923 DispatchEntry* dispatchEntry = connection->outboundQueue.front();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002924 dispatchEntry->deliveryTime = currentTime;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002925 const std::chrono::nanoseconds timeout =
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07002926 getDispatchingTimeoutLocked(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou70622952020-07-30 11:17:23 -05002927 dispatchEntry->timeoutTime = currentTime + timeout.count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08002928
2929 // Publish the event.
2930 status_t status;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002931 const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
2932 switch (eventEntry.type) {
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002933 case EventEntry::Type::KEY: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002934 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2935 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002936
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002937 // Publish the key event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002938 status = connection->inputPublisher
2939 .publishKeyEvent(dispatchEntry->seq,
2940 dispatchEntry->resolvedEventId, keyEntry.deviceId,
2941 keyEntry.source, keyEntry.displayId,
2942 std::move(hmac), dispatchEntry->resolvedAction,
2943 dispatchEntry->resolvedFlags, keyEntry.keyCode,
2944 keyEntry.scanCode, keyEntry.metaState,
2945 keyEntry.repeatCount, keyEntry.downTime,
2946 keyEntry.eventTime);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002947 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08002948 }
2949
Siarhei Vishniakou49483272019-10-22 13:13:47 -07002950 case EventEntry::Type::MOTION: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002951 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08002952
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002953 PointerCoords scaledCoords[MAX_POINTERS];
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002954 const PointerCoords* usingCoords = motionEntry.pointerCoords;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002955
chaviw82357092020-01-28 13:13:06 -08002956 // Set the X and Y offset and X and Y scale depending on the input source.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002957 if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002958 !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2959 float globalScaleFactor = dispatchEntry->globalScaleFactor;
chaviw82357092020-01-28 13:13:06 -08002960 if (globalScaleFactor != 1.0f) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002961 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
2962 scaledCoords[i] = motionEntry.pointerCoords[i];
chaviw82357092020-01-28 13:13:06 -08002963 // Don't apply window scale here since we don't want scale to affect raw
2964 // coordinates. The scale will be sent back to the client and applied
2965 // later when requesting relative coordinates.
2966 scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
2967 1 /* windowYScale */);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002968 }
2969 usingCoords = scaledCoords;
2970 }
2971 } else {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002972 // We don't want the dispatch target to know.
2973 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002974 for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002975 scaledCoords[i].clear();
2976 }
2977 usingCoords = scaledCoords;
2978 }
2979 }
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07002980
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002981 std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002982
2983 // Publish the motion event.
2984 status = connection->inputPublisher
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002985 .publishMotionEvent(dispatchEntry->seq,
2986 dispatchEntry->resolvedEventId,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002987 motionEntry.deviceId, motionEntry.source,
2988 motionEntry.displayId, std::move(hmac),
Garfield Tanff1f1bb2020-01-28 13:24:04 -08002989 dispatchEntry->resolvedAction,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002990 motionEntry.actionButton,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07002991 dispatchEntry->resolvedFlags,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002992 motionEntry.edgeFlags, motionEntry.metaState,
2993 motionEntry.buttonState,
2994 motionEntry.classification,
chaviw9eaa22c2020-07-01 16:21:27 -07002995 dispatchEntry->transform,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07002996 motionEntry.xPrecision, motionEntry.yPrecision,
2997 motionEntry.xCursorPosition,
2998 motionEntry.yCursorPosition,
2999 motionEntry.downTime, motionEntry.eventTime,
3000 motionEntry.pointerCount,
3001 motionEntry.pointerProperties, usingCoords);
3002 reportTouchEventForStatistics(motionEntry);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003003 break;
3004 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003005
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003006 case EventEntry::Type::FOCUS: {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003007 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003008 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003009 focusEntry.id,
3010 focusEntry.hasFocus,
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +01003011 mInTouchMode);
3012 break;
3013 }
3014
Prabir Pradhan99987712020-11-10 18:43:05 -08003015 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3016 const auto& captureEntry =
3017 static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3018 status = connection->inputPublisher
3019 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3020 captureEntry.pointerCaptureEnabled);
3021 break;
3022 }
3023
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003024 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003025 case EventEntry::Type::DEVICE_RESET:
3026 case EventEntry::Type::SENSOR: {
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003027 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
Chris Yef59a2f42020-10-16 12:55:26 -07003028 NamedEnum::string(eventEntry.type).c_str());
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003029 return;
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08003030 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003031 }
3032
3033 // Check the result.
3034 if (status) {
3035 if (status == WOULD_BLOCK) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003036 if (connection->waitQueue.empty()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003037 ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003038 "This is unexpected because the wait queue is empty, so the pipe "
3039 "should be empty and we shouldn't have any problems writing an "
3040 "event to it, status=%d",
3041 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003042 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3043 } else {
3044 // Pipe is full and we are waiting for the app to finish process some events
3045 // before sending more events to it.
3046#if DEBUG_DISPATCH_CYCLE
3047 ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003048 "waiting for the application to catch up",
3049 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003050#endif
Michael Wrightd02c5b62014-02-10 15:10:22 -08003051 }
3052 } else {
3053 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003054 "status=%d",
3055 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003056 abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
3057 }
3058 return;
3059 }
3060
3061 // Re-enqueue the event on the wait queue.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003062 connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
3063 connection->outboundQueue.end(),
3064 dispatchEntry));
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003065 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003066 connection->waitQueue.push_back(dispatchEntry);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07003067 if (connection->responsive) {
3068 mAnrTracker.insert(dispatchEntry->timeoutTime,
3069 connection->inputChannel->getConnectionToken());
3070 }
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003071 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003072 }
3073}
3074
chaviw09c8d2d2020-08-24 15:48:26 -07003075std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3076 size_t size;
3077 switch (event.type) {
3078 case VerifiedInputEvent::Type::KEY: {
3079 size = sizeof(VerifiedKeyEvent);
3080 break;
3081 }
3082 case VerifiedInputEvent::Type::MOTION: {
3083 size = sizeof(VerifiedMotionEvent);
3084 break;
3085 }
3086 }
3087 const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3088 return mHmacKeyManager.sign(start, size);
3089}
3090
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003091const std::array<uint8_t, 32> InputDispatcher::getSignature(
3092 const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3093 int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
3094 if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
3095 // Only sign events up and down events as the purely move events
3096 // are tied to their up/down counterparts so signing would be redundant.
3097 VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
3098 verifiedEvent.actionMasked = actionMasked;
3099 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
chaviw09c8d2d2020-08-24 15:48:26 -07003100 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003101 }
3102 return INVALID_HMAC;
3103}
3104
3105const std::array<uint8_t, 32> InputDispatcher::getSignature(
3106 const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3107 VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3108 verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3109 verifiedEvent.action = dispatchEntry.resolvedAction;
chaviw09c8d2d2020-08-24 15:48:26 -07003110 return sign(verifiedEvent);
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -07003111}
3112
Michael Wrightd02c5b62014-02-10 15:10:22 -08003113void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003114 const sp<Connection>& connection, uint32_t seq,
3115 bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003116#if DEBUG_DISPATCH_CYCLE
3117 ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003118 connection->getInputChannelName().c_str(), seq, toString(handled));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003119#endif
3120
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003121 if (connection->status == Connection::STATUS_BROKEN ||
3122 connection->status == Connection::STATUS_ZOMBIE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003123 return;
3124 }
3125
3126 // Notify other system components and prepare to start the next dispatch cycle.
3127 onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
3128}
3129
3130void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003131 const sp<Connection>& connection,
3132 bool notify) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003133#if DEBUG_DISPATCH_CYCLE
3134 ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003135 connection->getInputChannelName().c_str(), toString(notify));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003136#endif
3137
3138 // Clear the dispatch queues.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003139 drainDispatchQueue(connection->outboundQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003140 traceOutboundQueueLength(connection);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003141 drainDispatchQueue(connection->waitQueue);
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08003142 traceWaitQueueLength(connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003143
3144 // The connection appears to be unrecoverably broken.
3145 // Ignore already broken or zombie connections.
3146 if (connection->status == Connection::STATUS_NORMAL) {
3147 connection->status = Connection::STATUS_BROKEN;
3148
3149 if (notify) {
3150 // Notify other system components.
3151 onDispatchCycleBrokenLocked(currentTime, connection);
3152 }
3153 }
3154}
3155
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07003156void InputDispatcher::drainDispatchQueue(std::deque<DispatchEntry*>& queue) {
3157 while (!queue.empty()) {
3158 DispatchEntry* dispatchEntry = queue.front();
3159 queue.pop_front();
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003160 releaseDispatchEntry(dispatchEntry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003161 }
3162}
3163
Siarhei Vishniakou62683e82019-03-06 17:59:56 -08003164void InputDispatcher::releaseDispatchEntry(DispatchEntry* dispatchEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003165 if (dispatchEntry->hasForegroundTarget()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003166 decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003167 }
3168 delete dispatchEntry;
3169}
3170
3171int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
3172 InputDispatcher* d = static_cast<InputDispatcher*>(data);
3173
3174 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003175 std::scoped_lock _l(d->mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003176
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003177 if (d->mConnectionsByFd.find(fd) == d->mConnectionsByFd.end()) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003178 ALOGE("Received spurious receive callback for unknown input channel. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003179 "fd=%d, events=0x%x",
3180 fd, events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003181 return 0; // remove the callback
3182 }
3183
3184 bool notify;
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003185 sp<Connection> connection = d->mConnectionsByFd[fd];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003186 if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
3187 if (!(events & ALOOPER_EVENT_INPUT)) {
3188 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003189 "events=0x%x",
3190 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003191 return 1;
3192 }
3193
3194 nsecs_t currentTime = now();
3195 bool gotOne = false;
3196 status_t status;
3197 for (;;) {
3198 uint32_t seq;
3199 bool handled;
3200 status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
3201 if (status) {
3202 break;
3203 }
3204 d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
3205 gotOne = true;
3206 }
3207 if (gotOne) {
3208 d->runCommandsLockedInterruptible();
3209 if (status == WOULD_BLOCK) {
3210 return 1;
3211 }
3212 }
3213
3214 notify = status != DEAD_OBJECT || !connection->monitor;
3215 if (notify) {
3216 ALOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003217 connection->getInputChannelName().c_str(), status);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003218 }
3219 } else {
3220 // Monitor channels are never explicitly unregistered.
3221 // We do it automatically when the remote endpoint is closed so don't warn
3222 // about them.
arthurhungd352cb32020-04-28 17:09:28 +08003223 const bool stillHaveWindowHandle =
3224 d->getWindowHandleLocked(connection->inputChannel->getConnectionToken()) !=
3225 nullptr;
3226 notify = !connection->monitor && stillHaveWindowHandle;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003227 if (notify) {
3228 ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003229 "events=0x%x",
3230 connection->getInputChannelName().c_str(), events);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003231 }
3232 }
3233
Garfield Tan15601662020-09-22 15:32:38 -07003234 // Remove the channel.
3235 d->removeInputChannelLocked(connection->inputChannel->getConnectionToken(), notify);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003236 return 0; // remove the callback
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003237 } // release lock
Michael Wrightd02c5b62014-02-10 15:10:22 -08003238}
3239
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003240void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
Michael Wrightd02c5b62014-02-10 15:10:22 -08003241 const CancelationOptions& options) {
Siarhei Vishniakou2e2ea992020-12-15 02:57:19 +00003242 for (const auto& [fd, connection] : mConnectionsByFd) {
3243 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003244 }
3245}
3246
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003247void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003248 const CancelationOptions& options) {
Michael Wright3dd60e22019-03-27 22:06:44 +00003249 synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
3250 synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
3251}
3252
3253void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
3254 const CancelationOptions& options,
3255 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
3256 for (const auto& it : monitorsByDisplay) {
3257 const std::vector<Monitor>& monitors = it.second;
3258 for (const Monitor& monitor : monitors) {
3259 synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08003260 }
Michael Wrightfa13dcf2015-06-12 13:25:11 +01003261 }
3262}
3263
Michael Wrightd02c5b62014-02-10 15:10:22 -08003264void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05003265 const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07003266 sp<Connection> connection = getConnectionLocked(channel->getConnectionToken());
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003267 if (connection == nullptr) {
3268 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003269 }
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07003270
3271 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003272}
3273
3274void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
3275 const sp<Connection>& connection, const CancelationOptions& options) {
3276 if (connection->status == Connection::STATUS_BROKEN) {
3277 return;
3278 }
3279
3280 nsecs_t currentTime = now();
3281
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003282 std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
Siarhei Vishniakou00fca7c2019-10-29 13:05:57 -07003283 connection->inputState.synthesizeCancelationEvents(currentTime, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003284
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003285 if (cancelationEvents.empty()) {
3286 return;
3287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003288#if DEBUG_OUTBOUND_EVENT_DETAILS
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003289 ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
3290 "with reality: %s, mode=%d.",
3291 connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
3292 options.mode);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003293#endif
Svet Ganov5d3bc372020-01-26 23:11:07 -08003294
3295 InputTarget target;
3296 sp<InputWindowHandle> windowHandle =
3297 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3298 if (windowHandle != nullptr) {
3299 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003300 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003301 target.globalScaleFactor = windowInfo->globalScaleFactor;
3302 }
3303 target.inputChannel = connection->inputChannel;
3304 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3305
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003306 for (size_t i = 0; i < cancelationEvents.size(); i++) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003307 std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003308 switch (cancelationEventEntry->type) {
3309 case EventEntry::Type::KEY: {
3310 logOutboundKeyDetails("cancel - ",
3311 static_cast<const KeyEntry&>(*cancelationEventEntry));
3312 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003313 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003314 case EventEntry::Type::MOTION: {
3315 logOutboundMotionDetails("cancel - ",
3316 static_cast<const MotionEntry&>(*cancelationEventEntry));
3317 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003318 }
Prabir Pradhan99987712020-11-10 18:43:05 -08003319 case EventEntry::Type::FOCUS:
3320 case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3321 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
Chris Yef59a2f42020-10-16 12:55:26 -07003322 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003323 break;
3324 }
3325 case EventEntry::Type::CONFIGURATION_CHANGED:
Chris Yef59a2f42020-10-16 12:55:26 -07003326 case EventEntry::Type::DEVICE_RESET:
3327 case EventEntry::Type::SENSOR: {
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003328 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003329 NamedEnum::string(cancelationEventEntry->type).c_str());
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003330 break;
3331 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003332 }
3333
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003334 enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), target,
3335 InputTarget::FLAG_DISPATCH_AS_IS);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003336 }
Siarhei Vishniakoubd118892020-01-10 14:08:28 -08003337
3338 startDispatchCycleLocked(currentTime, connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003339}
3340
Svet Ganov5d3bc372020-01-26 23:11:07 -08003341void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
3342 const sp<Connection>& connection) {
3343 if (connection->status == Connection::STATUS_BROKEN) {
3344 return;
3345 }
3346
3347 nsecs_t currentTime = now();
3348
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003349 std::vector<std::unique_ptr<EventEntry>> downEvents =
Svet Ganov5d3bc372020-01-26 23:11:07 -08003350 connection->inputState.synthesizePointerDownEvents(currentTime);
3351
3352 if (downEvents.empty()) {
3353 return;
3354 }
3355
3356#if DEBUG_OUTBOUND_EVENT_DETAILS
3357 ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
3358 connection->getInputChannelName().c_str(), downEvents.size());
3359#endif
3360
3361 InputTarget target;
3362 sp<InputWindowHandle> windowHandle =
3363 getWindowHandleLocked(connection->inputChannel->getConnectionToken());
3364 if (windowHandle != nullptr) {
3365 const InputWindowInfo* windowInfo = windowHandle->getInfo();
chaviw1ff3d1e2020-07-01 15:53:47 -07003366 target.setDefaultPointerTransform(windowInfo->transform);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003367 target.globalScaleFactor = windowInfo->globalScaleFactor;
3368 }
3369 target.inputChannel = connection->inputChannel;
3370 target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
3371
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003372 for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003373 switch (downEventEntry->type) {
3374 case EventEntry::Type::MOTION: {
3375 logOutboundMotionDetails("down - ",
3376 static_cast<const MotionEntry&>(*downEventEntry));
3377 break;
3378 }
3379
3380 case EventEntry::Type::KEY:
3381 case EventEntry::Type::FOCUS:
3382 case EventEntry::Type::CONFIGURATION_CHANGED:
Prabir Pradhan99987712020-11-10 18:43:05 -08003383 case EventEntry::Type::DEVICE_RESET:
Chris Yef59a2f42020-10-16 12:55:26 -07003384 case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3385 case EventEntry::Type::SENSOR: {
Svet Ganov5d3bc372020-01-26 23:11:07 -08003386 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
Chris Yef59a2f42020-10-16 12:55:26 -07003387 NamedEnum::string(downEventEntry->type).c_str());
Svet Ganov5d3bc372020-01-26 23:11:07 -08003388 break;
3389 }
3390 }
3391
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003392 enqueueDispatchEntryLocked(connection, std::move(downEventEntry), target,
3393 InputTarget::FLAG_DISPATCH_AS_IS);
Svet Ganov5d3bc372020-01-26 23:11:07 -08003394 }
3395
3396 startDispatchCycleLocked(currentTime, connection);
3397}
3398
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003399std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
3400 const MotionEntry& originalMotionEntry, BitSet32 pointerIds) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003401 ALOG_ASSERT(pointerIds.value != 0);
3402
3403 uint32_t splitPointerIndexMap[MAX_POINTERS];
3404 PointerProperties splitPointerProperties[MAX_POINTERS];
3405 PointerCoords splitPointerCoords[MAX_POINTERS];
3406
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003407 uint32_t originalPointerCount = originalMotionEntry.pointerCount;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003408 uint32_t splitPointerCount = 0;
3409
3410 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003411 originalPointerIndex++) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003412 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003413 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003414 uint32_t pointerId = uint32_t(pointerProperties.id);
3415 if (pointerIds.hasBit(pointerId)) {
3416 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
3417 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
3418 splitPointerCoords[splitPointerCount].copyFrom(
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003419 originalMotionEntry.pointerCoords[originalPointerIndex]);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003420 splitPointerCount += 1;
3421 }
3422 }
3423
3424 if (splitPointerCount != pointerIds.count()) {
3425 // This is bad. We are missing some of the pointers that we expected to deliver.
3426 // Most likely this indicates that we received an ACTION_MOVE events that has
3427 // different pointer ids than we expected based on the previous ACTION_DOWN
3428 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
3429 // in this way.
3430 ALOGW("Dropping split motion event because the pointer count is %d but "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003431 "we expected there to be %d pointers. This probably means we received "
3432 "a broken sequence of pointer ids from the input device.",
3433 splitPointerCount, pointerIds.count());
Yi Kong9b14ac62018-07-17 13:48:38 -07003434 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003435 }
3436
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003437 int32_t action = originalMotionEntry.action;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003438 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003439 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN ||
3440 maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003441 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
3442 const PointerProperties& pointerProperties =
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003443 originalMotionEntry.pointerProperties[originalPointerIndex];
Michael Wrightd02c5b62014-02-10 15:10:22 -08003444 uint32_t pointerId = uint32_t(pointerProperties.id);
3445 if (pointerIds.hasBit(pointerId)) {
3446 if (pointerIds.count() == 1) {
3447 // The first/last pointer went down/up.
3448 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003449 ? AMOTION_EVENT_ACTION_DOWN
arthurhungea3f4fc2020-12-21 23:18:53 +08003450 : (originalMotionEntry.flags & AMOTION_EVENT_FLAG_CANCELED) != 0
3451 ? AMOTION_EVENT_ACTION_CANCEL
3452 : AMOTION_EVENT_ACTION_UP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003453 } else {
3454 // A secondary pointer went down/up.
3455 uint32_t splitPointerIndex = 0;
3456 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
3457 splitPointerIndex += 1;
3458 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003459 action = maskedAction |
3460 (splitPointerIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003461 }
3462 } else {
3463 // An unrelated pointer changed.
3464 action = AMOTION_EVENT_ACTION_MOVE;
3465 }
3466 }
3467
Garfield Tanff1f1bb2020-01-28 13:24:04 -08003468 int32_t newId = mIdGenerator.nextId();
3469 if (ATRACE_ENABLED()) {
3470 std::string message = StringPrintf("Split MotionEvent(id=0x%" PRIx32
3471 ") to MotionEvent(id=0x%" PRIx32 ").",
3472 originalMotionEntry.id, newId);
3473 ATRACE_NAME(message.c_str());
3474 }
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003475 std::unique_ptr<MotionEntry> splitMotionEntry =
3476 std::make_unique<MotionEntry>(newId, originalMotionEntry.eventTime,
3477 originalMotionEntry.deviceId, originalMotionEntry.source,
3478 originalMotionEntry.displayId,
3479 originalMotionEntry.policyFlags, action,
3480 originalMotionEntry.actionButton,
3481 originalMotionEntry.flags, originalMotionEntry.metaState,
3482 originalMotionEntry.buttonState,
3483 originalMotionEntry.classification,
3484 originalMotionEntry.edgeFlags,
3485 originalMotionEntry.xPrecision,
3486 originalMotionEntry.yPrecision,
3487 originalMotionEntry.xCursorPosition,
3488 originalMotionEntry.yCursorPosition,
3489 originalMotionEntry.downTime, splitPointerCount,
3490 splitPointerProperties, splitPointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003491
Siarhei Vishniakoud2770042019-10-29 11:08:14 -07003492 if (originalMotionEntry.injectionState) {
3493 splitMotionEntry->injectionState = originalMotionEntry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003494 splitMotionEntry->injectionState->refCount += 1;
3495 }
3496
3497 return splitMotionEntry;
3498}
3499
3500void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
3501#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003502 ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003503#endif
3504
3505 bool needWake;
3506 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003507 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003508
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003509 std::unique_ptr<ConfigurationChangedEntry> newEntry =
3510 std::make_unique<ConfigurationChangedEntry>(args->id, args->eventTime);
3511 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003512 } // release lock
3513
3514 if (needWake) {
3515 mLooper->wake();
3516 }
3517}
3518
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003519/**
3520 * If one of the meta shortcuts is detected, process them here:
3521 * Meta + Backspace -> generate BACK
3522 * Meta + Enter -> generate HOME
3523 * This will potentially overwrite keyCode and metaState.
3524 */
3525void InputDispatcher::accelerateMetaShortcuts(const int32_t deviceId, const int32_t action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003526 int32_t& keyCode, int32_t& metaState) {
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003527 if (metaState & AMETA_META_ON && action == AKEY_EVENT_ACTION_DOWN) {
3528 int32_t newKeyCode = AKEYCODE_UNKNOWN;
3529 if (keyCode == AKEYCODE_DEL) {
3530 newKeyCode = AKEYCODE_BACK;
3531 } else if (keyCode == AKEYCODE_ENTER) {
3532 newKeyCode = AKEYCODE_HOME;
3533 }
3534 if (newKeyCode != AKEYCODE_UNKNOWN) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003535 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003536 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003537 mReplacedKeys[replacement] = newKeyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003538 keyCode = newKeyCode;
3539 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3540 }
3541 } else if (action == AKEY_EVENT_ACTION_UP) {
3542 // In order to maintain a consistent stream of up and down events, check to see if the key
3543 // going up is one we've replaced in a down event and haven't yet replaced in an up event,
3544 // even if the modifier was released between the down and the up events.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003545 std::scoped_lock _l(mLock);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003546 struct KeyReplacement replacement = {keyCode, deviceId};
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07003547 auto replacementIt = mReplacedKeys.find(replacement);
3548 if (replacementIt != mReplacedKeys.end()) {
3549 keyCode = replacementIt->second;
3550 mReplacedKeys.erase(replacementIt);
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003551 metaState &= ~(AMETA_META_ON | AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON);
3552 }
3553 }
3554}
3555
Michael Wrightd02c5b62014-02-10 15:10:22 -08003556void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
3557#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003558 ALOGD("notifyKey - eventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
3559 "policyFlags=0x%x, action=0x%x, "
3560 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
3561 args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
3562 args->action, args->flags, args->keyCode, args->scanCode, args->metaState,
3563 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003564#endif
3565 if (!validateKeyEvent(args->action)) {
3566 return;
3567 }
3568
3569 uint32_t policyFlags = args->policyFlags;
3570 int32_t flags = args->flags;
3571 int32_t metaState = args->metaState;
Siarhei Vishniakou622bd322018-10-29 18:02:27 -07003572 // InputDispatcher tracks and generates key repeats on behalf of
3573 // whatever notifies it, so repeatCount should always be set to 0
3574 constexpr int32_t repeatCount = 0;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003575 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
3576 policyFlags |= POLICY_FLAG_VIRTUAL;
3577 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
3578 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003579 if (policyFlags & POLICY_FLAG_FUNCTION) {
3580 metaState |= AMETA_FUNCTION_ON;
3581 }
3582
3583 policyFlags |= POLICY_FLAG_TRUSTED;
3584
Michael Wright78f24442014-08-06 15:55:28 -07003585 int32_t keyCode = args->keyCode;
Siarhei Vishniakou61fafdd2018-04-13 11:00:58 -05003586 accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
Michael Wright78f24442014-08-06 15:55:28 -07003587
Michael Wrightd02c5b62014-02-10 15:10:22 -08003588 KeyEvent event;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003589 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
Garfield Tan4cc839f2020-01-24 11:26:14 -08003590 args->action, flags, keyCode, args->scanCode, metaState, repeatCount,
3591 args->downTime, args->eventTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003592
Michael Wright2b3c3302018-03-02 17:19:13 +00003593 android::base::Timer t;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003594 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003595 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3596 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003597 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003598 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003599
Michael Wrightd02c5b62014-02-10 15:10:22 -08003600 bool needWake;
3601 { // acquire lock
3602 mLock.lock();
3603
3604 if (shouldSendKeyToInputFilterLocked(args)) {
3605 mLock.unlock();
3606
3607 policyFlags |= POLICY_FLAG_FILTERED;
3608 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3609 return; // event was consumed by the filter
3610 }
3611
3612 mLock.lock();
3613 }
3614
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003615 std::unique_ptr<KeyEntry> newEntry =
3616 std::make_unique<KeyEntry>(args->id, args->eventTime, args->deviceId, args->source,
3617 args->displayId, policyFlags, args->action, flags,
3618 keyCode, args->scanCode, metaState, repeatCount,
3619 args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003620
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003621 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003622 mLock.unlock();
3623 } // release lock
3624
3625 if (needWake) {
3626 mLooper->wake();
3627 }
3628}
3629
3630bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
3631 return mInputFilterEnabled;
3632}
3633
3634void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
3635#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003636 ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3637 "displayId=%" PRId32 ", policyFlags=0x%x, "
Garfield Tan00f511d2019-06-12 16:55:40 -07003638 "action=0x%x, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
3639 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
Garfield Tanab0ab9c2019-07-10 18:58:28 -07003640 "yCursorPosition=%f, downTime=%" PRId64,
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003641 args->id, args->eventTime, args->deviceId, args->source, args->displayId,
3642 args->policyFlags, args->action, args->actionButton, args->flags, args->metaState,
3643 args->buttonState, args->edgeFlags, args->xPrecision, args->yPrecision,
3644 args->xCursorPosition, args->yCursorPosition, args->downTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003645 for (uint32_t i = 0; i < args->pointerCount; i++) {
3646 ALOGD(" Pointer %d: id=%d, toolType=%d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003647 "x=%f, y=%f, pressure=%f, size=%f, "
3648 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
3649 "orientation=%f",
3650 i, args->pointerProperties[i].id, args->pointerProperties[i].toolType,
3651 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
3652 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
3653 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
3654 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
3655 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
3656 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
3657 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
3658 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
3659 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003660 }
3661#endif
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003662 if (!validateMotionEvent(args->action, args->actionButton, args->pointerCount,
3663 args->pointerProperties)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003664 return;
3665 }
3666
3667 uint32_t policyFlags = args->policyFlags;
3668 policyFlags |= POLICY_FLAG_TRUSTED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003669
3670 android::base::Timer t;
Charles Chen3611f1f2019-01-29 17:26:18 +08003671 mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00003672 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3673 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003674 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00003675 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003676
3677 bool needWake;
3678 { // acquire lock
3679 mLock.lock();
3680
3681 if (shouldSendMotionToInputFilterLocked(args)) {
3682 mLock.unlock();
3683
3684 MotionEvent event;
chaviw9eaa22c2020-07-01 16:21:27 -07003685 ui::Transform transform;
Garfield Tan6a5a14e2020-01-28 13:24:04 -08003686 event.initialize(args->id, args->deviceId, args->source, args->displayId, INVALID_HMAC,
3687 args->action, args->actionButton, args->flags, args->edgeFlags,
chaviw9eaa22c2020-07-01 16:21:27 -07003688 args->metaState, args->buttonState, args->classification, transform,
3689 args->xPrecision, args->yPrecision, args->xCursorPosition,
3690 args->yCursorPosition, args->downTime, args->eventTime,
3691 args->pointerCount, args->pointerProperties, args->pointerCoords);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003692
3693 policyFlags |= POLICY_FLAG_FILTERED;
3694 if (!mPolicy->filterInputEvent(&event, policyFlags)) {
3695 return; // event was consumed by the filter
3696 }
3697
3698 mLock.lock();
3699 }
3700
3701 // Just enqueue a new motion event.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003702 std::unique_ptr<MotionEntry> newEntry =
3703 std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
3704 args->source, args->displayId, policyFlags,
3705 args->action, args->actionButton, args->flags,
3706 args->metaState, args->buttonState,
3707 args->classification, args->edgeFlags,
3708 args->xPrecision, args->yPrecision,
3709 args->xCursorPosition, args->yCursorPosition,
3710 args->downTime, args->pointerCount,
3711 args->pointerProperties, args->pointerCoords, 0, 0);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003712
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003713 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003714 mLock.unlock();
3715 } // release lock
3716
3717 if (needWake) {
3718 mLooper->wake();
3719 }
3720}
3721
Chris Yef59a2f42020-10-16 12:55:26 -07003722void InputDispatcher::notifySensor(const NotifySensorArgs* args) {
3723#if DEBUG_INBOUND_EVENT_DETAILS
3724 ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
3725 " sensorType=%s",
3726 args->id, args->eventTime, args->deviceId, args->source,
3727 NamedEnum::string(args->sensorType).c_str());
3728#endif
3729
3730 bool needWake;
3731 { // acquire lock
3732 mLock.lock();
3733
3734 // Just enqueue a new sensor event.
3735 std::unique_ptr<SensorEntry> newEntry =
3736 std::make_unique<SensorEntry>(args->id, args->eventTime, args->deviceId,
3737 args->source, 0 /* policyFlags*/, args->hwTimestamp,
3738 args->sensorType, args->accuracy,
3739 args->accuracyChanged, args->values);
3740
3741 needWake = enqueueInboundEventLocked(std::move(newEntry));
3742 mLock.unlock();
3743 } // release lock
3744
3745 if (needWake) {
3746 mLooper->wake();
3747 }
3748}
3749
Michael Wrightd02c5b62014-02-10 15:10:22 -08003750bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
Jackal Guof9696682018-10-05 12:23:23 +08003751 return mInputFilterEnabled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003752}
3753
3754void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
3755#if DEBUG_INBOUND_EVENT_DETAILS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -07003756 ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003757 "switchMask=0x%08x",
3758 args->eventTime, args->policyFlags, args->switchValues, args->switchMask);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003759#endif
3760
3761 uint32_t policyFlags = args->policyFlags;
3762 policyFlags |= POLICY_FLAG_TRUSTED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003763 mPolicy->notifySwitch(args->eventTime, args->switchValues, args->switchMask, policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003764}
3765
3766void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
3767#if DEBUG_INBOUND_EVENT_DETAILS
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003768 ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args->eventTime,
3769 args->deviceId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003770#endif
3771
3772 bool needWake;
3773 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003774 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003775
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003776 std::unique_ptr<DeviceResetEntry> newEntry =
3777 std::make_unique<DeviceResetEntry>(args->id, args->eventTime, args->deviceId);
3778 needWake = enqueueInboundEventLocked(std::move(newEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003779 } // release lock
3780
3781 if (needWake) {
3782 mLooper->wake();
3783 }
3784}
3785
Prabir Pradhan7e186182020-11-10 13:56:45 -08003786void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) {
3787#if DEBUG_INBOUND_EVENT_DETAILS
3788 ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args->eventTime,
3789 args->enabled ? "true" : "false");
3790#endif
3791
Prabir Pradhan99987712020-11-10 18:43:05 -08003792 bool needWake;
3793 { // acquire lock
3794 std::scoped_lock _l(mLock);
3795 auto entry = std::make_unique<PointerCaptureChangedEntry>(args->id, args->eventTime,
3796 args->enabled);
3797 needWake = enqueueInboundEventLocked(std::move(entry));
3798 } // release lock
3799
3800 if (needWake) {
3801 mLooper->wake();
3802 }
Prabir Pradhan7e186182020-11-10 13:56:45 -08003803}
3804
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003805InputEventInjectionResult InputDispatcher::injectInputEvent(
3806 const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
3807 InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003808#if DEBUG_INBOUND_EVENT_DETAILS
3809 ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003810 "syncMode=%d, timeout=%lld, policyFlags=0x%08x",
3811 event->getType(), injectorPid, injectorUid, syncMode, timeout.count(), policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003812#endif
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07003813 nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003814
3815 policyFlags |= POLICY_FLAG_INJECTED;
3816 if (hasInjectionPermission(injectorPid, injectorUid)) {
3817 policyFlags |= POLICY_FLAG_TRUSTED;
3818 }
3819
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003820 std::queue<std::unique_ptr<EventEntry>> injectedEntries;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003821 switch (event->getType()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003822 case AINPUT_EVENT_TYPE_KEY: {
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003823 const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
3824 int32_t action = incomingKey.getAction();
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003825 if (!validateKeyEvent(action)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003826 return InputEventInjectionResult::FAILED;
Michael Wright2b3c3302018-03-02 17:19:13 +00003827 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003828
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003829 int32_t flags = incomingKey.getFlags();
3830 int32_t keyCode = incomingKey.getKeyCode();
3831 int32_t metaState = incomingKey.getMetaState();
3832 accelerateMetaShortcuts(VIRTUAL_KEYBOARD_ID, action,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003833 /*byref*/ keyCode, /*byref*/ metaState);
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003834 KeyEvent keyEvent;
Garfield Tan4cc839f2020-01-24 11:26:14 -08003835 keyEvent.initialize(incomingKey.getId(), VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
Siarhei Vishniakou0d8ed6e2020-01-17 15:48:59 -08003836 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
3837 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
3838 incomingKey.getDownTime(), incomingKey.getEventTime());
Michael Wrightd02c5b62014-02-10 15:10:22 -08003839
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003840 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
3841 policyFlags |= POLICY_FLAG_VIRTUAL;
Michael Wright2b3c3302018-03-02 17:19:13 +00003842 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003843
3844 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3845 android::base::Timer t;
3846 mPolicy->interceptKeyBeforeQueueing(&keyEvent, /*byref*/ policyFlags);
3847 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3848 ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
3849 std::to_string(t.duration().count()).c_str());
3850 }
3851 }
3852
3853 mLock.lock();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003854 std::unique_ptr<KeyEntry> injectedEntry =
3855 std::make_unique<KeyEntry>(incomingKey.getId(), incomingKey.getEventTime(),
3856 VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
3857 incomingKey.getDisplayId(), policyFlags, action,
3858 flags, keyCode, incomingKey.getScanCode(), metaState,
3859 incomingKey.getRepeatCount(),
3860 incomingKey.getDownTime());
3861 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003862 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003863 }
3864
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003865 case AINPUT_EVENT_TYPE_MOTION: {
3866 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3867 int32_t action = motionEvent->getAction();
3868 size_t pointerCount = motionEvent->getPointerCount();
3869 const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3870 int32_t actionButton = motionEvent->getActionButton();
3871 int32_t displayId = motionEvent->getDisplayId();
3872 if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003873 return InputEventInjectionResult::FAILED;
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003874 }
3875
3876 if (!(policyFlags & POLICY_FLAG_FILTERED)) {
3877 nsecs_t eventTime = motionEvent->getEventTime();
3878 android::base::Timer t;
3879 mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
3880 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
3881 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
3882 std::to_string(t.duration().count()).c_str());
3883 }
3884 }
3885
3886 mLock.lock();
3887 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3888 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003889 std::unique_ptr<MotionEntry> injectedEntry =
3890 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3891 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3892 motionEvent->getDisplayId(), policyFlags, action,
3893 actionButton, motionEvent->getFlags(),
3894 motionEvent->getMetaState(),
3895 motionEvent->getButtonState(),
3896 motionEvent->getClassification(),
3897 motionEvent->getEdgeFlags(),
3898 motionEvent->getXPrecision(),
3899 motionEvent->getYPrecision(),
3900 motionEvent->getRawXCursorPosition(),
3901 motionEvent->getRawYCursorPosition(),
3902 motionEvent->getDownTime(),
3903 uint32_t(pointerCount), pointerProperties,
3904 samplePointerCoords, motionEvent->getXOffset(),
3905 motionEvent->getYOffset());
3906 injectedEntries.push(std::move(injectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003907 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3908 sampleEventTimes += 1;
3909 samplePointerCoords += pointerCount;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003910 std::unique_ptr<MotionEntry> nextInjectedEntry =
3911 std::make_unique<MotionEntry>(motionEvent->getId(), *sampleEventTimes,
3912 VIRTUAL_KEYBOARD_ID, motionEvent->getSource(),
3913 motionEvent->getDisplayId(), policyFlags,
3914 action, actionButton, motionEvent->getFlags(),
3915 motionEvent->getMetaState(),
3916 motionEvent->getButtonState(),
3917 motionEvent->getClassification(),
3918 motionEvent->getEdgeFlags(),
3919 motionEvent->getXPrecision(),
3920 motionEvent->getYPrecision(),
3921 motionEvent->getRawXCursorPosition(),
3922 motionEvent->getRawYCursorPosition(),
3923 motionEvent->getDownTime(),
3924 uint32_t(pointerCount), pointerProperties,
3925 samplePointerCoords,
3926 motionEvent->getXOffset(),
3927 motionEvent->getYOffset());
3928 injectedEntries.push(std::move(nextInjectedEntry));
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003929 }
3930 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003931 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08003932
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003933 default:
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08003934 ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003935 return InputEventInjectionResult::FAILED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003936 }
3937
3938 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003939 if (syncMode == InputEventInjectionSync::NONE) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003940 injectionState->injectionIsAsync = true;
3941 }
3942
3943 injectionState->refCount += 1;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003944 injectedEntries.back()->injectionState = injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003945
3946 bool needWake = false;
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003947 while (!injectedEntries.empty()) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07003948 needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07003949 injectedEntries.pop();
Michael Wrightd02c5b62014-02-10 15:10:22 -08003950 }
3951
3952 mLock.unlock();
3953
3954 if (needWake) {
3955 mLooper->wake();
3956 }
3957
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003958 InputEventInjectionResult injectionResult;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003959 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003960 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003961
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003962 if (syncMode == InputEventInjectionSync::NONE) {
3963 injectionResult = InputEventInjectionResult::SUCCEEDED;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003964 } else {
3965 for (;;) {
3966 injectionResult = injectionState->injectionResult;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003967 if (injectionResult != InputEventInjectionResult::PENDING) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003968 break;
3969 }
3970
3971 nsecs_t remainingTimeout = endTime - now();
3972 if (remainingTimeout <= 0) {
3973#if DEBUG_INJECTION
3974 ALOGD("injectInputEvent - Timed out waiting for injection result "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003975 "to become available.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003976#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003977 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003978 break;
3979 }
3980
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08003981 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08003982 }
3983
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003984 if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
3985 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08003986 while (injectionState->pendingForegroundDispatches != 0) {
3987#if DEBUG_INJECTION
3988 ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003989 injectionState->pendingForegroundDispatches);
Michael Wrightd02c5b62014-02-10 15:10:22 -08003990#endif
3991 nsecs_t remainingTimeout = endTime - now();
3992 if (remainingTimeout <= 0) {
3993#if DEBUG_INJECTION
Garfield Tan0fc2fa72019-08-29 17:22:15 -07003994 ALOGD("injectInputEvent - Timed out waiting for pending foreground "
3995 "dispatches to finish.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08003996#endif
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08003997 injectionResult = InputEventInjectionResult::TIMED_OUT;
Michael Wrightd02c5b62014-02-10 15:10:22 -08003998 break;
3999 }
4000
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004001 mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004002 }
4003 }
4004 }
4005
4006 injectionState->release();
4007 } // release lock
4008
4009#if DEBUG_INJECTION
Siarhei Vishniakou097c3db2020-05-06 14:18:38 -07004010 ALOGD("injectInputEvent - Finished with result %d. injectorPid=%d, injectorUid=%d",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004011 injectionResult, injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004012#endif
4013
4014 return injectionResult;
4015}
4016
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004017std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
Gang Wange9087892020-01-07 12:17:14 -05004018 std::array<uint8_t, 32> calculatedHmac;
4019 std::unique_ptr<VerifiedInputEvent> result;
4020 switch (event.getType()) {
4021 case AINPUT_EVENT_TYPE_KEY: {
4022 const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
4023 VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
4024 result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004025 calculatedHmac = sign(verifiedKeyEvent);
Gang Wange9087892020-01-07 12:17:14 -05004026 break;
4027 }
4028 case AINPUT_EVENT_TYPE_MOTION: {
4029 const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
4030 VerifiedMotionEvent verifiedMotionEvent =
4031 verifiedMotionEventFromMotionEvent(motionEvent);
4032 result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
chaviw09c8d2d2020-08-24 15:48:26 -07004033 calculatedHmac = sign(verifiedMotionEvent);
Gang Wange9087892020-01-07 12:17:14 -05004034 break;
4035 }
4036 default: {
4037 ALOGE("Cannot verify events of type %" PRId32, event.getType());
4038 return nullptr;
4039 }
4040 }
4041 if (calculatedHmac == INVALID_HMAC) {
4042 return nullptr;
4043 }
4044 if (calculatedHmac != event.getHmac()) {
4045 return nullptr;
4046 }
4047 return result;
Siarhei Vishniakou54d3e182020-01-15 17:38:38 -08004048}
4049
Michael Wrightd02c5b62014-02-10 15:10:22 -08004050bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004051 return injectorUid == 0 ||
4052 mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004053}
4054
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004055void InputDispatcher::setInjectionResult(EventEntry& entry,
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004056 InputEventInjectionResult injectionResult) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004057 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004058 if (injectionState) {
4059#if DEBUG_INJECTION
4060 ALOGD("Setting input event injection result to %d. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004061 "injectorPid=%d, injectorUid=%d",
4062 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004063#endif
4064
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004065 if (injectionState->injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08004066 // Log the outcome since the injector did not wait for the injection result.
4067 switch (injectionResult) {
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004068 case InputEventInjectionResult::SUCCEEDED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004069 ALOGV("Asynchronous input event injection succeeded.");
4070 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004071 case InputEventInjectionResult::FAILED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004072 ALOGW("Asynchronous input event injection failed.");
4073 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004074 case InputEventInjectionResult::PERMISSION_DENIED:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004075 ALOGW("Asynchronous input event injection permission denied.");
4076 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004077 case InputEventInjectionResult::TIMED_OUT:
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004078 ALOGW("Asynchronous input event injection timed out.");
4079 break;
Siarhei Vishniakouae6229e2019-12-30 16:23:19 -08004080 case InputEventInjectionResult::PENDING:
4081 ALOGE("Setting result to 'PENDING' for asynchronous injection");
4082 break;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004083 }
4084 }
4085
4086 injectionState->injectionResult = injectionResult;
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004087 mInjectionResultAvailable.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004088 }
4089}
4090
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004091void InputDispatcher::incrementPendingForegroundDispatches(EventEntry& entry) {
4092 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004093 if (injectionState) {
4094 injectionState->pendingForegroundDispatches += 1;
4095 }
4096}
4097
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004098void InputDispatcher::decrementPendingForegroundDispatches(EventEntry& entry) {
4099 InjectionState* injectionState = entry.injectionState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004100 if (injectionState) {
4101 injectionState->pendingForegroundDispatches -= 1;
4102
4103 if (injectionState->pendingForegroundDispatches == 0) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004104 mInjectionSyncFinished.notify_all();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004105 }
4106 }
4107}
4108
Vishnu Nairad321cd2020-08-20 16:40:21 -07004109const std::vector<sp<InputWindowHandle>>& InputDispatcher::getWindowHandlesLocked(
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004110 int32_t displayId) const {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004111 static const std::vector<sp<InputWindowHandle>> EMPTY_WINDOW_HANDLES;
4112 auto it = mWindowHandlesByDisplay.find(displayId);
4113 return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
Arthur Hungb92218b2018-08-14 12:00:21 +08004114}
4115
Michael Wrightd02c5b62014-02-10 15:10:22 -08004116sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
chaviwfbe5d9c2018-12-26 12:23:37 -08004117 const sp<IBinder>& windowHandleToken) const {
arthurhungbe737672020-06-24 12:29:21 +08004118 if (windowHandleToken == nullptr) {
4119 return nullptr;
4120 }
4121
Arthur Hungb92218b2018-08-14 12:00:21 +08004122 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004123 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004124 for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004125 if (windowHandle->getToken() == windowHandleToken) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004126 return windowHandle;
4127 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004128 }
4129 }
Yi Kong9b14ac62018-07-17 13:48:38 -07004130 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004131}
4132
Vishnu Nairad321cd2020-08-20 16:40:21 -07004133sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(const sp<IBinder>& windowHandleToken,
4134 int displayId) const {
4135 if (windowHandleToken == nullptr) {
4136 return nullptr;
4137 }
4138
4139 for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
4140 if (windowHandle->getToken() == windowHandleToken) {
4141 return windowHandle;
4142 }
4143 }
4144 return nullptr;
4145}
4146
4147sp<InputWindowHandle> InputDispatcher::getFocusedWindowHandleLocked(int displayId) const {
4148 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4149 return getWindowHandleLocked(focusedToken, displayId);
4150}
4151
Mady Mellor017bcd12020-06-23 19:12:00 +00004152bool InputDispatcher::hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const {
4153 for (auto& it : mWindowHandlesByDisplay) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004154 const std::vector<sp<InputWindowHandle>>& windowHandles = it.second;
Mady Mellor017bcd12020-06-23 19:12:00 +00004155 for (const sp<InputWindowHandle>& handle : windowHandles) {
arthurhungbe737672020-06-24 12:29:21 +08004156 if (handle->getId() == windowHandle->getId() &&
4157 handle->getToken() == windowHandle->getToken()) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004158 if (windowHandle->getInfo()->displayId != it.first) {
4159 ALOGE("Found window %s in display %" PRId32
4160 ", but it should belong to display %" PRId32,
4161 windowHandle->getName().c_str(), it.first,
4162 windowHandle->getInfo()->displayId);
4163 }
4164 return true;
Arthur Hungb92218b2018-08-14 12:00:21 +08004165 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004166 }
4167 }
4168 return false;
4169}
4170
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004171bool InputDispatcher::hasResponsiveConnectionLocked(InputWindowHandle& windowHandle) const {
4172 sp<Connection> connection = getConnectionLocked(windowHandle.getToken());
4173 const bool noInputChannel =
4174 windowHandle.getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4175 if (connection != nullptr && noInputChannel) {
4176 ALOGW("%s has feature NO_INPUT_CHANNEL, but it matched to connection %s",
4177 windowHandle.getName().c_str(), connection->inputChannel->getName().c_str());
4178 return false;
4179 }
4180
4181 if (connection == nullptr) {
4182 if (!noInputChannel) {
4183 ALOGI("Could not find connection for %s", windowHandle.getName().c_str());
4184 }
4185 return false;
4186 }
4187 if (!connection->responsive) {
4188 ALOGW("Window %s is not responsive", windowHandle.getName().c_str());
4189 return false;
4190 }
4191 return true;
4192}
4193
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004194std::shared_ptr<InputChannel> InputDispatcher::getInputChannelLocked(
4195 const sp<IBinder>& token) const {
Robert Carr5c8a0262018-10-03 16:30:44 -07004196 size_t count = mInputChannelsByToken.count(token);
4197 if (count == 0) {
4198 return nullptr;
4199 }
4200 return mInputChannelsByToken.at(token);
4201}
4202
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004203void InputDispatcher::updateWindowHandlesForDisplayLocked(
4204 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
4205 if (inputWindowHandles.empty()) {
4206 // Remove all handles on a display if there are no windows left.
4207 mWindowHandlesByDisplay.erase(displayId);
4208 return;
4209 }
4210
4211 // Since we compare the pointer of input window handles across window updates, we need
4212 // to make sure the handle object for the same window stays unchanged across updates.
4213 const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
chaviwaf87b3e2019-10-01 16:59:28 -07004214 std::unordered_map<int32_t /*id*/, sp<InputWindowHandle>> oldHandlesById;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004215 for (const sp<InputWindowHandle>& handle : oldHandles) {
chaviwaf87b3e2019-10-01 16:59:28 -07004216 oldHandlesById[handle->getId()] = handle;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004217 }
4218
4219 std::vector<sp<InputWindowHandle>> newHandles;
4220 for (const sp<InputWindowHandle>& handle : inputWindowHandles) {
4221 if (!handle->updateInfo()) {
4222 // handle no longer valid
4223 continue;
4224 }
4225
4226 const InputWindowInfo* info = handle->getInfo();
4227 if ((getInputChannelLocked(handle->getToken()) == nullptr &&
4228 info->portalToDisplayId == ADISPLAY_ID_NONE)) {
4229 const bool noInputChannel =
Michael Wright44753b12020-07-08 13:48:11 +01004230 info->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4231 const bool canReceiveInput = !info->flags.test(InputWindowInfo::Flag::NOT_TOUCHABLE) ||
4232 !info->flags.test(InputWindowInfo::Flag::NOT_FOCUSABLE);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004233 if (canReceiveInput && !noInputChannel) {
John Recke0710582019-09-26 13:46:12 -07004234 ALOGV("Window handle %s has no registered input channel",
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004235 handle->getName().c_str());
Robert Carr2984b7a2020-04-13 17:06:45 -07004236 continue;
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004237 }
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004238 }
4239
4240 if (info->displayId != displayId) {
4241 ALOGE("Window %s updated by wrong display %d, should belong to display %d",
4242 handle->getName().c_str(), displayId, info->displayId);
4243 continue;
4244 }
4245
Robert Carredd13602020-04-13 17:24:34 -07004246 if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
4247 (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
chaviwaf87b3e2019-10-01 16:59:28 -07004248 const sp<InputWindowHandle>& oldHandle = oldHandlesById.at(handle->getId());
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004249 oldHandle->updateFrom(handle);
4250 newHandles.push_back(oldHandle);
4251 } else {
4252 newHandles.push_back(handle);
4253 }
4254 }
4255
4256 // Insert or replace
4257 mWindowHandlesByDisplay[displayId] = newHandles;
4258}
4259
Arthur Hung72d8dc32020-03-28 00:48:39 +00004260void InputDispatcher::setInputWindows(
4261 const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
4262 { // acquire lock
4263 std::scoped_lock _l(mLock);
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004264 for (const auto& [displayId, handles] : handlesPerDisplay) {
4265 setInputWindowsLocked(handles, displayId);
Arthur Hung72d8dc32020-03-28 00:48:39 +00004266 }
4267 }
4268 // Wake up poll loop since it may need to make new input dispatching choices.
4269 mLooper->wake();
4270}
4271
Arthur Hungb92218b2018-08-14 12:00:21 +08004272/**
4273 * Called from InputManagerService, update window handle list by displayId that can receive input.
4274 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
4275 * If set an empty list, remove all handles from the specific display.
4276 * For focused handle, check if need to change and send a cancel event to previous one.
4277 * For removed handle, check if need to send a cancel event if already in touch.
4278 */
Arthur Hung72d8dc32020-03-28 00:48:39 +00004279void InputDispatcher::setInputWindowsLocked(
4280 const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004281 if (DEBUG_FOCUS) {
4282 std::string windowList;
4283 for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
4284 windowList += iwh->getName() + " ";
4285 }
4286 ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
4287 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004288
Siarhei Vishniakoua2862a02020-07-20 16:36:46 -05004289 // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
4290 for (const sp<InputWindowHandle>& window : inputWindowHandles) {
4291 const bool noInputWindow =
4292 window->getInfo()->inputFeatures.test(InputWindowInfo::Feature::NO_INPUT_CHANNEL);
4293 if (noInputWindow && window->getToken() != nullptr) {
4294 ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
4295 window->getName().c_str());
4296 window->releaseChannel();
4297 }
4298 }
4299
Arthur Hung72d8dc32020-03-28 00:48:39 +00004300 // Copy old handles for release if they are no longer present.
4301 const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004302
Arthur Hung72d8dc32020-03-28 00:48:39 +00004303 updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
Siarhei Vishniakoub3ad35c2019-04-05 10:50:52 -07004304
Vishnu Nair958da932020-08-21 17:12:37 -07004305 const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
4306 if (mLastHoverWindowHandle &&
4307 std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
4308 windowHandles.end()) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004309 mLastHoverWindowHandle = nullptr;
4310 }
4311
Vishnu Nair958da932020-08-21 17:12:37 -07004312 sp<IBinder> focusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4313 if (focusedToken) {
4314 FocusResult result = checkTokenFocusableLocked(focusedToken, displayId);
4315 if (result != FocusResult::OK) {
4316 onFocusChangedLocked(focusedToken, nullptr, displayId, typeToString(result));
4317 }
4318 }
4319
4320 std::optional<FocusRequest> focusRequest =
4321 getOptionalValueByKey(mPendingFocusRequests, displayId);
4322 if (focusRequest) {
4323 // If the window from the pending request is now visible, provide it focus.
4324 FocusResult result = handleFocusRequestLocked(*focusRequest);
4325 if (result != FocusResult::NOT_VISIBLE) {
4326 // Drop the request if we were able to change the focus or we cannot change
4327 // it for another reason.
4328 mPendingFocusRequests.erase(displayId);
4329 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004330 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004331
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004332 std::unordered_map<int32_t, TouchState>::iterator stateIt =
4333 mTouchStatesByDisplay.find(displayId);
4334 if (stateIt != mTouchStatesByDisplay.end()) {
4335 TouchState& state = stateIt->second;
Arthur Hung72d8dc32020-03-28 00:48:39 +00004336 for (size_t i = 0; i < state.windows.size();) {
4337 TouchedWindow& touchedWindow = state.windows[i];
Mady Mellor017bcd12020-06-23 19:12:00 +00004338 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004339 if (DEBUG_FOCUS) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004340 ALOGD("Touched window was removed: %s in display %" PRId32,
4341 touchedWindow.windowHandle->getName().c_str(), displayId);
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004342 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004343 std::shared_ptr<InputChannel> touchedInputChannel =
Arthur Hung72d8dc32020-03-28 00:48:39 +00004344 getInputChannelLocked(touchedWindow.windowHandle->getToken());
4345 if (touchedInputChannel != nullptr) {
4346 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
4347 "touched window was removed");
4348 synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004349 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004350 state.windows.erase(state.windows.begin() + i);
4351 } else {
4352 ++i;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004353 }
4354 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004355 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004356
Arthur Hung72d8dc32020-03-28 00:48:39 +00004357 // Release information for windows that are no longer present.
4358 // This ensures that unused input channels are released promptly.
4359 // Otherwise, they might stick around until the window handle is destroyed
4360 // which might not happen until the next GC.
4361 for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
Mady Mellor017bcd12020-06-23 19:12:00 +00004362 if (!hasWindowHandleLocked(oldWindowHandle)) {
Arthur Hung72d8dc32020-03-28 00:48:39 +00004363 if (DEBUG_FOCUS) {
4364 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
Arthur Hung25e2af12020-03-26 12:58:37 +00004365 }
Arthur Hung72d8dc32020-03-28 00:48:39 +00004366 oldWindowHandle->releaseChannel();
Siarhei Vishniakou2508b872020-12-03 16:33:53 -10004367 // To avoid making too many calls into the compat framework, only
4368 // check for window flags when windows are going away.
4369 // TODO(b/157929241) : delete this. This is only needed temporarily
4370 // in order to gather some data about the flag usage
4371 if (oldWindowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
4372 ALOGW("%s has FLAG_SLIPPERY. Please report this in b/157929241",
4373 oldWindowHandle->getName().c_str());
4374 if (mCompatService != nullptr) {
4375 mCompatService->reportChangeByUid(IInputConstants::BLOCK_FLAG_SLIPPERY,
4376 oldWindowHandle->getInfo()->ownerUid);
4377 }
4378 }
Arthur Hung25e2af12020-03-26 12:58:37 +00004379 }
chaviw291d88a2019-02-14 10:33:58 -08004380 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004381}
4382
4383void InputDispatcher::setFocusedApplication(
Chris Yea209fde2020-07-22 13:54:51 -07004384 int32_t displayId, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004385 if (DEBUG_FOCUS) {
4386 ALOGD("setFocusedApplication displayId=%" PRId32 " %s", displayId,
4387 inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
4388 }
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004389 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004390 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004391
Chris Yea209fde2020-07-22 13:54:51 -07004392 std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
Tiger Huang721e26f2018-07-24 22:26:19 +08004393 getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004394
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004395 if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
4396 return; // This application is already focused. No need to wake up or change anything.
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004397 }
4398
Chris Yea209fde2020-07-22 13:54:51 -07004399 // Set the new application handle.
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004400 if (inputApplicationHandle != nullptr) {
4401 mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
4402 } else {
4403 mFocusedApplicationHandlesByDisplay.erase(displayId);
4404 }
4405
4406 // No matter what the old focused application was, stop waiting on it because it is
4407 // no longer focused.
4408 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004409 } // release lock
4410
4411 // Wake up poll loop since it may need to make new input dispatching choices.
4412 mLooper->wake();
4413}
4414
Tiger Huang721e26f2018-07-24 22:26:19 +08004415/**
4416 * Sets the focused display, which is responsible for receiving focus-dispatched input events where
4417 * the display not specified.
4418 *
4419 * We track any unreleased events for each window. If a window loses the ability to receive the
4420 * released event, we will send a cancel event to it. So when the focused display is changed, we
4421 * cancel all the unreleased display-unspecified events for the focused window on the old focused
4422 * display. The display-specified events won't be affected.
4423 */
4424void InputDispatcher::setFocusedDisplay(int32_t displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004425 if (DEBUG_FOCUS) {
4426 ALOGD("setFocusedDisplay displayId=%" PRId32, displayId);
4427 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004428 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004429 std::scoped_lock _l(mLock);
Tiger Huang721e26f2018-07-24 22:26:19 +08004430
4431 if (mFocusedDisplayId != displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07004432 sp<IBinder> oldFocusedWindowToken =
4433 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
4434 if (oldFocusedWindowToken != nullptr) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004435 std::shared_ptr<InputChannel> inputChannel =
Vishnu Nairad321cd2020-08-20 16:40:21 -07004436 getInputChannelLocked(oldFocusedWindowToken);
Tiger Huang721e26f2018-07-24 22:26:19 +08004437 if (inputChannel != nullptr) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004438 CancelationOptions
4439 options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
4440 "The display which contains this window no longer has focus.");
Michael Wright3dd60e22019-03-27 22:06:44 +00004441 options.displayId = ADISPLAY_ID_NONE;
Tiger Huang721e26f2018-07-24 22:26:19 +08004442 synthesizeCancelationEventsForInputChannelLocked(inputChannel, options);
4443 }
4444 }
4445 mFocusedDisplayId = displayId;
4446
Chris Ye3c2d6f52020-08-09 10:39:48 -07004447 // Find new focused window and validate
Vishnu Nairad321cd2020-08-20 16:40:21 -07004448 sp<IBinder> newFocusedWindowToken =
4449 getValueByKey(mFocusedWindowTokenByDisplay, displayId);
4450 notifyFocusChangedLocked(oldFocusedWindowToken, newFocusedWindowToken);
Robert Carrf759f162018-11-13 12:57:11 -08004451
Vishnu Nairad321cd2020-08-20 16:40:21 -07004452 if (newFocusedWindowToken == nullptr) {
Tiger Huang721e26f2018-07-24 22:26:19 +08004453 ALOGW("Focused display #%" PRId32 " does not have a focused window.", displayId);
Vishnu Nairad321cd2020-08-20 16:40:21 -07004454 if (!mFocusedWindowTokenByDisplay.empty()) {
4455 ALOGE("But another display has a focused window\n%s",
4456 dumpFocusedWindowsLocked().c_str());
Tiger Huang721e26f2018-07-24 22:26:19 +08004457 }
4458 }
4459 }
4460
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004461 if (DEBUG_FOCUS) {
4462 logDispatchStateLocked();
4463 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004464 } // release lock
4465
4466 // Wake up poll loop since it may need to make new input dispatching choices.
4467 mLooper->wake();
4468}
4469
Michael Wrightd02c5b62014-02-10 15:10:22 -08004470void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004471 if (DEBUG_FOCUS) {
4472 ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
4473 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004474
4475 bool changed;
4476 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004477 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004478
4479 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
4480 if (mDispatchFrozen && !frozen) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004481 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004482 }
4483
4484 if (mDispatchEnabled && !enabled) {
4485 resetAndDropEverythingLocked("dispatcher is being disabled");
4486 }
4487
4488 mDispatchEnabled = enabled;
4489 mDispatchFrozen = frozen;
4490 changed = true;
4491 } else {
4492 changed = false;
4493 }
4494
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004495 if (DEBUG_FOCUS) {
4496 logDispatchStateLocked();
4497 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004498 } // release lock
4499
4500 if (changed) {
4501 // Wake up poll loop since it may need to make new input dispatching choices.
4502 mLooper->wake();
4503 }
4504}
4505
4506void InputDispatcher::setInputFilterEnabled(bool enabled) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004507 if (DEBUG_FOCUS) {
4508 ALOGD("setInputFilterEnabled: enabled=%d", enabled);
4509 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004510
4511 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004512 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004513
4514 if (mInputFilterEnabled == enabled) {
4515 return;
4516 }
4517
4518 mInputFilterEnabled = enabled;
4519 resetAndDropEverythingLocked("input filter is being enabled or disabled");
4520 } // release lock
4521
4522 // Wake up poll loop since there might be work to do to drop everything.
4523 mLooper->wake();
4524}
4525
Siarhei Vishniakouf3bc1aa2019-11-25 13:48:53 -08004526void InputDispatcher::setInTouchMode(bool inTouchMode) {
4527 std::scoped_lock lock(mLock);
4528 mInTouchMode = inTouchMode;
4529}
4530
Bernardo Rufinoea97d182020-08-19 14:43:14 +01004531void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
4532 if (opacity < 0 || opacity > 1) {
4533 LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
4534 return;
4535 }
4536
4537 std::scoped_lock lock(mLock);
4538 mMaximumObscuringOpacityForTouch = opacity;
4539}
4540
4541void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) {
4542 std::scoped_lock lock(mLock);
4543 mBlockUntrustedTouchesMode = mode;
4544}
4545
chaviwfbe5d9c2018-12-26 12:23:37 -08004546bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
4547 if (fromToken == toToken) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004548 if (DEBUG_FOCUS) {
4549 ALOGD("Trivial transfer to same window.");
4550 }
chaviwfbe5d9c2018-12-26 12:23:37 -08004551 return true;
4552 }
4553
Michael Wrightd02c5b62014-02-10 15:10:22 -08004554 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004555 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004556
chaviwfbe5d9c2018-12-26 12:23:37 -08004557 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
4558 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
Yi Kong9b14ac62018-07-17 13:48:38 -07004559 if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
chaviwfbe5d9c2018-12-26 12:23:37 -08004560 ALOGW("Cannot transfer focus because from or to window not found.");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004561 return false;
4562 }
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004563 if (DEBUG_FOCUS) {
4564 ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
4565 fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
4566 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004567 if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004568 if (DEBUG_FOCUS) {
4569 ALOGD("Cannot transfer focus because windows are on different displays.");
4570 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004571 return false;
4572 }
4573
4574 bool found = false;
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004575 for (std::pair<const int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4576 TouchState& state = pair.second;
Jeff Brownf086ddb2014-02-11 14:28:48 -08004577 for (size_t i = 0; i < state.windows.size(); i++) {
4578 const TouchedWindow& touchedWindow = state.windows[i];
4579 if (touchedWindow.windowHandle == fromWindowHandle) {
4580 int32_t oldTargetFlags = touchedWindow.targetFlags;
4581 BitSet32 pointerIds = touchedWindow.pointerIds;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004582
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004583 state.windows.erase(state.windows.begin() + i);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004584
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004585 int32_t newTargetFlags = oldTargetFlags &
4586 (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT |
4587 InputTarget::FLAG_DISPATCH_AS_IS);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004588 state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004589
Jeff Brownf086ddb2014-02-11 14:28:48 -08004590 found = true;
4591 goto Found;
4592 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004593 }
4594 }
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004595 Found:
Michael Wrightd02c5b62014-02-10 15:10:22 -08004596
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004597 if (!found) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004598 if (DEBUG_FOCUS) {
4599 ALOGD("Focus transfer failed because from window did not have focus.");
4600 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004601 return false;
4602 }
4603
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07004604 sp<Connection> fromConnection = getConnectionLocked(fromToken);
4605 sp<Connection> toConnection = getConnectionLocked(toToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004606 if (fromConnection != nullptr && toConnection != nullptr) {
Svet Ganov5d3bc372020-01-26 23:11:07 -08004607 fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004608 CancelationOptions
4609 options(CancelationOptions::CANCEL_POINTER_EVENTS,
4610 "transferring touch focus from this window to another window");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004611 synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
Svet Ganov5d3bc372020-01-26 23:11:07 -08004612 synthesizePointerDownEventsForConnectionLocked(toConnection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004613 }
4614
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004615 if (DEBUG_FOCUS) {
4616 logDispatchStateLocked();
4617 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004618 } // release lock
4619
4620 // Wake up poll loop since it may need to make new input dispatching choices.
4621 mLooper->wake();
4622 return true;
4623}
4624
4625void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
Siarhei Vishniakou86587282019-09-09 18:20:15 +01004626 if (DEBUG_FOCUS) {
4627 ALOGD("Resetting and dropping all events (%s).", reason);
4628 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004629
4630 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
4631 synthesizeCancelationEventsForAllConnectionsLocked(options);
4632
4633 resetKeyRepeatLocked();
4634 releasePendingEventLocked();
4635 drainInboundQueueLocked();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004636 resetNoFocusedWindowTimeoutLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004637
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004638 mAnrTracker.clear();
Jeff Brownf086ddb2014-02-11 14:28:48 -08004639 mTouchStatesByDisplay.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004640 mLastHoverWindowHandle.clear();
Michael Wright78f24442014-08-06 15:55:28 -07004641 mReplacedKeys.clear();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004642}
4643
4644void InputDispatcher::logDispatchStateLocked() {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004645 std::string dump;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004646 dumpDispatchStateLocked(dump);
4647
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004648 std::istringstream stream(dump);
4649 std::string line;
4650
4651 while (std::getline(stream, line, '\n')) {
4652 ALOGD("%s", line.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004653 }
4654}
4655
Vishnu Nairad321cd2020-08-20 16:40:21 -07004656std::string InputDispatcher::dumpFocusedWindowsLocked() {
4657 if (mFocusedWindowTokenByDisplay.empty()) {
4658 return INDENT "FocusedWindows: <none>\n";
4659 }
4660
4661 std::string dump;
4662 dump += INDENT "FocusedWindows:\n";
4663 for (auto& it : mFocusedWindowTokenByDisplay) {
4664 const int32_t displayId = it.first;
4665 const sp<InputWindowHandle> windowHandle = getFocusedWindowHandleLocked(displayId);
4666 if (windowHandle) {
4667 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", name='%s'\n", displayId,
4668 windowHandle->getName().c_str());
4669 } else {
4670 dump += StringPrintf(INDENT2 "displayId=%" PRId32
4671 " has focused token without a window'\n",
4672 displayId);
4673 }
4674 }
4675 return dump;
4676}
4677
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004678std::string InputDispatcher::dumpPendingFocusRequestsLocked() {
4679 if (mPendingFocusRequests.empty()) {
4680 return INDENT "mPendingFocusRequests: <none>\n";
4681 }
4682
4683 std::string dump;
4684 dump += INDENT "mPendingFocusRequests:\n";
4685 for (const auto& [displayId, focusRequest] : mPendingFocusRequests) {
4686 // Rather than printing raw values for focusRequest.token and focusRequest.focusedToken,
4687 // try to resolve them to actual windows.
4688 std::string windowName = getConnectionNameLocked(focusRequest.token);
4689 std::string focusedWindowName = getConnectionNameLocked(focusRequest.focusedToken);
4690 dump += StringPrintf(INDENT2 "displayId=%" PRId32 ", token->%s, focusedToken->%s\n",
4691 displayId, windowName.c_str(), focusedWindowName.c_str());
4692 }
4693 return dump;
4694}
4695
Prabir Pradhan99987712020-11-10 18:43:05 -08004696std::string InputDispatcher::dumpPointerCaptureStateLocked() {
4697 std::string dump;
4698
4699 dump += StringPrintf(INDENT "FocusedWindowRequestedPointerCapture: %s\n",
4700 toString(mFocusedWindowRequestedPointerCapture));
4701
4702 std::string windowName = "None";
4703 if (mWindowTokenWithPointerCapture) {
4704 const sp<InputWindowHandle> captureWindowHandle =
4705 getWindowHandleLocked(mWindowTokenWithPointerCapture);
4706 windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
4707 : "token has capture without window";
4708 }
4709 dump += StringPrintf(INDENT "CurrentWindowWithPointerCapture: %s\n", windowName.c_str());
4710
4711 return dump;
4712}
4713
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004714void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
Siarhei Vishniakou043a3ec2019-05-01 11:30:46 -07004715 dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
4716 dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
4717 dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
Tiger Huang721e26f2018-07-24 22:26:19 +08004718 dump += StringPrintf(INDENT "FocusedDisplayId: %" PRId32 "\n", mFocusedDisplayId);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004719
Tiger Huang721e26f2018-07-24 22:26:19 +08004720 if (!mFocusedApplicationHandlesByDisplay.empty()) {
4721 dump += StringPrintf(INDENT "FocusedApplications:\n");
4722 for (auto& it : mFocusedApplicationHandlesByDisplay) {
4723 const int32_t displayId = it.first;
Chris Yea209fde2020-07-22 13:54:51 -07004724 const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004725 const std::chrono::duration timeout =
4726 applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004727 dump += StringPrintf(INDENT2 "displayId=%" PRId32
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004728 ", name='%s', dispatchingTimeout=%" PRId64 "ms\n",
Siarhei Vishniakou70622952020-07-30 11:17:23 -05004729 displayId, applicationHandle->getName().c_str(), millis(timeout));
Tiger Huang721e26f2018-07-24 22:26:19 +08004730 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004731 } else {
Tiger Huang721e26f2018-07-24 22:26:19 +08004732 dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
Michael Wrightd02c5b62014-02-10 15:10:22 -08004733 }
Tiger Huang721e26f2018-07-24 22:26:19 +08004734
Vishnu Nairad321cd2020-08-20 16:40:21 -07004735 dump += dumpFocusedWindowsLocked();
Siarhei Vishniakouad991402020-10-28 11:40:09 -05004736 dump += dumpPendingFocusRequestsLocked();
Prabir Pradhan99987712020-11-10 18:43:05 -08004737 dump += dumpPointerCaptureStateLocked();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004738
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004739 if (!mTouchStatesByDisplay.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004740 dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004741 for (const std::pair<int32_t, TouchState>& pair : mTouchStatesByDisplay) {
4742 const TouchState& state = pair.second;
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004743 dump += StringPrintf(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004744 state.displayId, toString(state.down), toString(state.split),
4745 state.deviceId, state.source);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004746 if (!state.windows.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004747 dump += INDENT3 "Windows:\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004748 for (size_t i = 0; i < state.windows.size(); i++) {
4749 const TouchedWindow& touchedWindow = state.windows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004750 dump += StringPrintf(INDENT4
4751 "%zu: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
4752 i, touchedWindow.windowHandle->getName().c_str(),
4753 touchedWindow.pointerIds.value, touchedWindow.targetFlags);
Jeff Brownf086ddb2014-02-11 14:28:48 -08004754 }
4755 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004756 dump += INDENT3 "Windows: <none>\n";
Jeff Brownf086ddb2014-02-11 14:28:48 -08004757 }
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004758 if (!state.portalWindows.empty()) {
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004759 dump += INDENT3 "Portal windows:\n";
4760 for (size_t i = 0; i < state.portalWindows.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004761 const sp<InputWindowHandle> portalWindowHandle = state.portalWindows[i];
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004762 dump += StringPrintf(INDENT4 "%zu: name='%s'\n", i,
4763 portalWindowHandle->getName().c_str());
Tiger Huang85b8c5e2019-01-17 18:34:54 +08004764 }
4765 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004766 }
4767 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004768 dump += INDENT "TouchStates: <no displays touched>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004769 }
4770
Arthur Hungb92218b2018-08-14 12:00:21 +08004771 if (!mWindowHandlesByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004772 for (auto& it : mWindowHandlesByDisplay) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004773 const std::vector<sp<InputWindowHandle>> windowHandles = it.second;
Arthur Hung3b413f22018-10-26 18:05:34 +08004774 dump += StringPrintf(INDENT "Display: %" PRId32 "\n", it.first);
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004775 if (!windowHandles.empty()) {
Arthur Hungb92218b2018-08-14 12:00:21 +08004776 dump += INDENT2 "Windows:\n";
4777 for (size_t i = 0; i < windowHandles.size(); i++) {
Arthur Hung7c3ae9c2019-03-11 11:23:03 +08004778 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
Arthur Hungb92218b2018-08-14 12:00:21 +08004779 const InputWindowInfo* windowInfo = windowHandle->getInfo();
Michael Wrightd02c5b62014-02-10 15:10:22 -08004780
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004781 dump += StringPrintf(INDENT3 "%zu: name='%s', id=%" PRId32 ", displayId=%d, "
Vishnu Nair47074b82020-08-14 11:54:47 -07004782 "portalToDisplayId=%d, paused=%s, focusable=%s, "
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004783 "hasWallpaper=%s, visible=%s, alpha=%.2f, "
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004784 "flags=%s, type=%s, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004785 "frame=[%d,%d][%d,%d], globalScale=%f, "
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004786 "applicationInfo=%s, "
chaviw1ff3d1e2020-07-01 15:53:47 -07004787 "touchableRegion=",
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004788 i, windowInfo->name.c_str(), windowInfo->id,
4789 windowInfo->displayId, windowInfo->portalToDisplayId,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004790 toString(windowInfo->paused),
Vishnu Nair47074b82020-08-14 11:54:47 -07004791 toString(windowInfo->focusable),
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004792 toString(windowInfo->hasWallpaper),
Bernardo Rufino0f6a36e2020-11-11 10:10:59 +00004793 toString(windowInfo->visible), windowInfo->alpha,
Michael Wright8759d672020-07-21 00:46:45 +01004794 windowInfo->flags.string().c_str(),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004795 NamedEnum::string(windowInfo->type).c_str(),
Michael Wright44753b12020-07-08 13:48:11 +01004796 windowInfo->frameLeft, windowInfo->frameTop,
4797 windowInfo->frameRight, windowInfo->frameBottom,
Siarhei Vishniakoue41c4512020-09-08 19:35:58 -05004798 windowInfo->globalScaleFactor,
4799 windowInfo->applicationInfo.name.c_str());
Bernardo Rufino53fc31e2020-11-03 11:01:07 +00004800 dump += dumpRegion(windowInfo->touchableRegion);
Michael Wright44753b12020-07-08 13:48:11 +01004801 dump += StringPrintf(", inputFeatures=%s",
4802 windowInfo->inputFeatures.string().c_str());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004803 dump += StringPrintf(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%" PRId64
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004804 "ms, trustedOverlay=%s, hasToken=%s, "
4805 "touchOcclusionMode=%s\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004806 windowInfo->ownerPid, windowInfo->ownerUid,
Bernardo Rufinoc2f1fad2020-11-04 17:30:57 +00004807 millis(windowInfo->dispatchingTimeout),
4808 toString(windowInfo->trustedOverlay),
Bernardo Rufino5fd822d2020-11-13 16:11:39 +00004809 toString(windowInfo->token != nullptr),
4810 toString(windowInfo->touchOcclusionMode).c_str());
chaviw85b44202020-07-24 11:46:21 -07004811 windowInfo->transform.dump(dump, "transform", INDENT4);
Arthur Hungb92218b2018-08-14 12:00:21 +08004812 }
4813 } else {
4814 dump += INDENT2 "Windows: <none>\n";
4815 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004816 }
4817 } else {
Arthur Hungb92218b2018-08-14 12:00:21 +08004818 dump += INDENT "Displays: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004819 }
4820
Michael Wright3dd60e22019-03-27 22:06:44 +00004821 if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004822 for (auto& it : mGlobalMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004823 const std::vector<Monitor>& monitors = it.second;
4824 dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
4825 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004826 }
4827 for (auto& it : mGestureMonitorsByDisplay) {
Michael Wright3dd60e22019-03-27 22:06:44 +00004828 const std::vector<Monitor>& monitors = it.second;
4829 dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
4830 dumpMonitors(dump, monitors);
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004831 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08004832 } else {
Michael Wright3dd60e22019-03-27 22:06:44 +00004833 dump += INDENT "Monitors: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004834 }
4835
4836 nsecs_t currentTime = now();
4837
4838 // Dump recently dispatched or dropped events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004839 if (!mRecentQueue.empty()) {
4840 dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004841 for (std::shared_ptr<EventEntry>& entry : mRecentQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004842 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004843 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004844 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004845 }
4846 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004847 dump += INDENT "RecentQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004848 }
4849
4850 // Dump event currently being dispatched.
4851 if (mPendingEvent) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004852 dump += INDENT "PendingEvent:\n";
4853 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004854 dump += mPendingEvent->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004855 dump += StringPrintf(", age=%" PRId64 "ms\n",
4856 ns2ms(currentTime - mPendingEvent->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004857 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004858 dump += INDENT "PendingEvent: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004859 }
4860
4861 // Dump inbound events from oldest to newest.
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07004862 if (!mInboundQueue.empty()) {
4863 dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07004864 for (std::shared_ptr<EventEntry>& entry : mInboundQueue) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004865 dump += INDENT2;
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004866 dump += entry->getDescription();
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004867 dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004868 }
4869 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004870 dump += INDENT "InboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004871 }
4872
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004873 if (!mReplacedKeys.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004874 dump += INDENT "ReplacedKeys:\n";
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07004875 for (const std::pair<KeyReplacement, int32_t>& pair : mReplacedKeys) {
4876 const KeyReplacement& replacement = pair.first;
4877 int32_t newKeyCode = pair.second;
4878 dump += StringPrintf(INDENT2 "originalKeyCode=%d, deviceId=%d -> newKeyCode=%d\n",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004879 replacement.keyCode, replacement.deviceId, newKeyCode);
Michael Wright78f24442014-08-06 15:55:28 -07004880 }
4881 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004882 dump += INDENT "ReplacedKeys: <empty>\n";
Michael Wright78f24442014-08-06 15:55:28 -07004883 }
4884
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004885 if (!mConnectionsByFd.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004886 dump += INDENT "Connections:\n";
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004887 for (const auto& pair : mConnectionsByFd) {
4888 const sp<Connection>& connection = pair.second;
4889 dump += StringPrintf(INDENT2 "%i: channelName='%s', windowName='%s', "
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004890 "status=%s, monitor=%s, responsive=%s\n",
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004891 pair.first, connection->getInputChannelName().c_str(),
4892 connection->getWindowName().c_str(), connection->getStatusLabel(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07004893 toString(connection->monitor), toString(connection->responsive));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004894
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004895 if (!connection->outboundQueue.empty()) {
4896 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
4897 connection->outboundQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004898 dump += dumpQueue(connection->outboundQueue, currentTime);
4899
Michael Wrightd02c5b62014-02-10 15:10:22 -08004900 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004901 dump += INDENT3 "OutboundQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004902 }
4903
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07004904 if (!connection->waitQueue.empty()) {
4905 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
4906 connection->waitQueue.size());
Siarhei Vishniakou14411c92020-09-18 21:15:05 -05004907 dump += dumpQueue(connection->waitQueue, currentTime);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004908 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004909 dump += INDENT3 "WaitQueue: <empty>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004910 }
4911 }
4912 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004913 dump += INDENT "Connections: <none>\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004914 }
4915
4916 if (isAppSwitchPendingLocked()) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004917 dump += StringPrintf(INDENT "AppSwitch: pending, due in %" PRId64 "ms\n",
4918 ns2ms(mAppSwitchDueTime - now()));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004919 } else {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004920 dump += INDENT "AppSwitch: not pending\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08004921 }
4922
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08004923 dump += INDENT "Configuration:\n";
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07004924 dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
4925 dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
4926 ns2ms(mConfig.keyRepeatTimeout));
Michael Wrightd02c5b62014-02-10 15:10:22 -08004927}
4928
Michael Wright3dd60e22019-03-27 22:06:44 +00004929void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) {
4930 const size_t numMonitors = monitors.size();
4931 for (size_t i = 0; i < numMonitors; i++) {
4932 const Monitor& monitor = monitors[i];
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05004933 const std::shared_ptr<InputChannel>& channel = monitor.inputChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004934 dump += StringPrintf(INDENT2 "%zu: '%s', ", i, channel->getName().c_str());
4935 dump += "\n";
4936 }
4937}
4938
Garfield Tan15601662020-09-22 15:32:38 -07004939base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(
4940 const std::string& name) {
4941#if DEBUG_CHANNEL_CREATION
4942 ALOGD("channel '%s' ~ createInputChannel", name.c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08004943#endif
4944
Garfield Tan15601662020-09-22 15:32:38 -07004945 std::shared_ptr<InputChannel> serverChannel;
4946 std::unique_ptr<InputChannel> clientChannel;
4947 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4948
4949 if (result) {
4950 return base::Error(result) << "Failed to open input channel pair with name " << name;
4951 }
4952
Michael Wrightd02c5b62014-02-10 15:10:22 -08004953 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08004954 std::scoped_lock _l(mLock);
Garfield Tan15601662020-09-22 15:32:38 -07004955 sp<Connection> connection = new Connection(serverChannel, false /*monitor*/, mIdGenerator);
Michael Wrightd02c5b62014-02-10 15:10:22 -08004956
Garfield Tan15601662020-09-22 15:32:38 -07004957 int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004958 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004959 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004960
Michael Wrightd02c5b62014-02-10 15:10:22 -08004961 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
4962 } // release lock
4963
4964 // Wake the looper because some connections have changed.
4965 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07004966 return clientChannel;
Michael Wrightd02c5b62014-02-10 15:10:22 -08004967}
4968
Garfield Tan15601662020-09-22 15:32:38 -07004969base::Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004970 int32_t displayId, bool isGestureMonitor, const std::string& name, int32_t pid) {
Garfield Tan15601662020-09-22 15:32:38 -07004971 std::shared_ptr<InputChannel> serverChannel;
4972 std::unique_ptr<InputChannel> clientChannel;
4973 status_t result = openInputChannelPair(name, serverChannel, clientChannel);
4974 if (result) {
4975 return base::Error(result) << "Failed to open input channel pair with name " << name;
4976 }
4977
Michael Wright3dd60e22019-03-27 22:06:44 +00004978 { // acquire lock
4979 std::scoped_lock _l(mLock);
4980
4981 if (displayId < 0) {
Garfield Tan15601662020-09-22 15:32:38 -07004982 return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
4983 << " without a specified display.";
Michael Wright3dd60e22019-03-27 22:06:44 +00004984 }
4985
Garfield Tan15601662020-09-22 15:32:38 -07004986 sp<Connection> connection = new Connection(serverChannel, true /*monitor*/, mIdGenerator);
Michael Wright3dd60e22019-03-27 22:06:44 +00004987
Garfield Tan15601662020-09-22 15:32:38 -07004988 const int fd = serverChannel->getFd();
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07004989 mConnectionsByFd[fd] = connection;
Garfield Tan15601662020-09-22 15:32:38 -07004990 mInputChannelsByToken[serverChannel->getConnectionToken()] = serverChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00004991
Garfield Tan0fc2fa72019-08-29 17:22:15 -07004992 auto& monitorsByDisplay =
4993 isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
Siarhei Vishniakou58cfc602020-12-14 23:21:30 +00004994 monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
Michael Wright3dd60e22019-03-27 22:06:44 +00004995
4996 mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Michael Wright3dd60e22019-03-27 22:06:44 +00004997 }
Garfield Tan15601662020-09-22 15:32:38 -07004998
Michael Wright3dd60e22019-03-27 22:06:44 +00004999 // Wake the looper because some connections have changed.
5000 mLooper->wake();
Garfield Tan15601662020-09-22 15:32:38 -07005001 return clientChannel;
Michael Wright3dd60e22019-03-27 22:06:44 +00005002}
5003
Garfield Tan15601662020-09-22 15:32:38 -07005004status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005005 { // acquire lock
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005006 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005007
Garfield Tan15601662020-09-22 15:32:38 -07005008 status_t status = removeInputChannelLocked(connectionToken, false /*notify*/);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005009 if (status) {
5010 return status;
5011 }
5012 } // release lock
5013
5014 // Wake the poll loop because removing the connection may have changed the current
5015 // synchronization state.
5016 mLooper->wake();
5017 return OK;
5018}
5019
Garfield Tan15601662020-09-22 15:32:38 -07005020status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
5021 bool notify) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005022 sp<Connection> connection = getConnectionLocked(connectionToken);
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005023 if (connection == nullptr) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005024 ALOGW("Attempted to unregister already unregistered input channel");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005025 return BAD_VALUE;
5026 }
5027
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005028 removeConnectionLocked(connection);
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005029 mInputChannelsByToken.erase(connectionToken);
Robert Carr5c8a0262018-10-03 16:30:44 -07005030
Michael Wrightd02c5b62014-02-10 15:10:22 -08005031 if (connection->monitor) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005032 removeMonitorChannelLocked(connectionToken);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005033 }
5034
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005035 mLooper->removeFd(connection->inputChannel->getFd());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005036
5037 nsecs_t currentTime = now();
5038 abortBrokenDispatchCycleLocked(currentTime, connection, notify);
5039
5040 connection->status = Connection::STATUS_ZOMBIE;
5041 return OK;
5042}
5043
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005044void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
5045 removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
5046 removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
Michael Wright3dd60e22019-03-27 22:06:44 +00005047}
5048
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005049void InputDispatcher::removeMonitorChannelLocked(
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005050 const sp<IBinder>& connectionToken,
Michael Wright3dd60e22019-03-27 22:06:44 +00005051 std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005052 for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005053 std::vector<Monitor>& monitors = it->second;
5054 const size_t numMonitors = monitors.size();
5055 for (size_t i = 0; i < numMonitors; i++) {
Siarhei Vishniakouadefc3e2020-09-02 22:28:29 -05005056 if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005057 monitors.erase(monitors.begin() + i);
5058 break;
5059 }
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005060 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005061 if (monitors.empty()) {
5062 it = monitorsByDisplay.erase(it);
Arthur Hung2fbf37f2018-09-13 18:16:41 +08005063 } else {
5064 ++it;
5065 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005066 }
5067}
5068
Michael Wright3dd60e22019-03-27 22:06:44 +00005069status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
5070 { // acquire lock
5071 std::scoped_lock _l(mLock);
5072 std::optional<int32_t> foundDisplayId = findGestureMonitorDisplayByTokenLocked(token);
5073
5074 if (!foundDisplayId) {
5075 ALOGW("Attempted to pilfer pointers from an un-registered monitor or invalid token");
5076 return BAD_VALUE;
5077 }
5078 int32_t displayId = foundDisplayId.value();
5079
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005080 std::unordered_map<int32_t, TouchState>::iterator stateIt =
5081 mTouchStatesByDisplay.find(displayId);
5082 if (stateIt == mTouchStatesByDisplay.end()) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005083 ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
5084 return BAD_VALUE;
5085 }
5086
Siarhei Vishniakou4700f822020-03-24 19:05:54 -07005087 TouchState& state = stateIt->second;
Michael Wright3dd60e22019-03-27 22:06:44 +00005088 std::optional<int32_t> foundDeviceId;
5089 for (const TouchedMonitor& touchedMonitor : state.gestureMonitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005090 if (touchedMonitor.monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005091 foundDeviceId = state.deviceId;
5092 }
5093 }
5094 if (!foundDeviceId || !state.down) {
5095 ALOGW("Attempted to pilfer points from a monitor without any on-going pointer streams."
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005096 " Ignoring.");
Michael Wright3dd60e22019-03-27 22:06:44 +00005097 return BAD_VALUE;
5098 }
5099 int32_t deviceId = foundDeviceId.value();
5100
5101 // Send cancel events to all the input channels we're stealing from.
5102 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005103 "gesture monitor stole pointer stream");
Michael Wright3dd60e22019-03-27 22:06:44 +00005104 options.deviceId = deviceId;
5105 options.displayId = displayId;
5106 for (const TouchedWindow& window : state.windows) {
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -05005107 std::shared_ptr<InputChannel> channel =
5108 getInputChannelLocked(window.windowHandle->getToken());
Michael Wright3a240c42019-12-10 20:53:41 +00005109 if (channel != nullptr) {
5110 synthesizeCancelationEventsForInputChannelLocked(channel, options);
5111 }
Michael Wright3dd60e22019-03-27 22:06:44 +00005112 }
5113 // Then clear the current touch state so we stop dispatching to them as well.
5114 state.filterNonMonitors();
5115 }
5116 return OK;
5117}
5118
Prabir Pradhan99987712020-11-10 18:43:05 -08005119void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
5120 { // acquire lock
5121 std::scoped_lock _l(mLock);
5122 if (DEBUG_FOCUS) {
5123 const sp<InputWindowHandle> windowHandle = getWindowHandleLocked(windowToken);
5124 ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
5125 windowHandle != nullptr ? windowHandle->getName().c_str()
5126 : "token without window");
5127 }
5128
5129 const sp<IBinder> focusedToken =
5130 getValueByKey(mFocusedWindowTokenByDisplay, mFocusedDisplayId);
5131 if (focusedToken != windowToken) {
5132 ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
5133 enabled ? "enable" : "disable");
5134 return;
5135 }
5136
5137 if (enabled == mFocusedWindowRequestedPointerCapture) {
5138 ALOGW("Ignoring request to %s Pointer Capture: "
5139 "window has %s requested pointer capture.",
5140 enabled ? "enable" : "disable", enabled ? "already" : "not");
5141 return;
5142 }
5143
5144 mFocusedWindowRequestedPointerCapture = enabled;
5145 setPointerCaptureLocked(enabled);
5146 } // release lock
5147
5148 // Wake the thread to process command entries.
5149 mLooper->wake();
5150}
5151
Michael Wright3dd60e22019-03-27 22:06:44 +00005152std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
5153 const sp<IBinder>& token) {
5154 for (const auto& it : mGestureMonitorsByDisplay) {
5155 const std::vector<Monitor>& monitors = it.second;
5156 for (const Monitor& monitor : monitors) {
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005157 if (monitor.inputChannel->getConnectionToken() == token) {
Michael Wright3dd60e22019-03-27 22:06:44 +00005158 return it.first;
5159 }
5160 }
5161 }
5162 return std::nullopt;
5163}
5164
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005165std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
5166 std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
5167 if (gesturePid.has_value()) {
5168 return gesturePid;
5169 }
5170 return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
5171}
5172
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005173sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005174 if (inputConnectionToken == nullptr) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005175 return nullptr;
Arthur Hung3b413f22018-10-26 18:05:34 +08005176 }
5177
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005178 for (const auto& pair : mConnectionsByFd) {
Siarhei Vishniakoud0d71b62019-10-14 14:50:45 -07005179 const sp<Connection>& connection = pair.second;
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005180 if (connection->inputChannel->getConnectionToken() == inputConnectionToken) {
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005181 return connection;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005182 }
5183 }
Robert Carr4e670e52018-08-15 13:26:12 -07005184
Siarhei Vishniakou146ecfd2019-07-29 16:04:31 -07005185 return nullptr;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005186}
5187
Siarhei Vishniakouad991402020-10-28 11:40:09 -05005188std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
5189 sp<Connection> connection = getConnectionLocked(connectionToken);
5190 if (connection == nullptr) {
5191 return "<nullptr>";
5192 }
5193 return connection->getInputChannelName();
5194}
5195
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005196void InputDispatcher::removeConnectionLocked(const sp<Connection>& connection) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005197 mAnrTracker.eraseToken(connection->inputChannel->getConnectionToken());
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005198 removeByValue(mConnectionsByFd, connection);
5199}
5200
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005201void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime,
5202 const sp<Connection>& connection, uint32_t seq,
5203 bool handled) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005204 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5205 &InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005206 commandEntry->connection = connection;
5207 commandEntry->eventTime = currentTime;
5208 commandEntry->seq = seq;
5209 commandEntry->handled = handled;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005210 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005211}
5212
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005213void InputDispatcher::onDispatchCycleBrokenLocked(nsecs_t currentTime,
5214 const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005215 ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005216 connection->getInputChannelName().c_str());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005217
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005218 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5219 &InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005220 commandEntry->connection = connection;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005221 postCommandLocked(std::move(commandEntry));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005222}
5223
Vishnu Nairad321cd2020-08-20 16:40:21 -07005224void InputDispatcher::notifyFocusChangedLocked(const sp<IBinder>& oldToken,
5225 const sp<IBinder>& newToken) {
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005226 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5227 &InputDispatcher::doNotifyFocusChangedLockedInterruptible);
chaviw0c06c6e2019-01-09 13:27:07 -08005228 commandEntry->oldToken = oldToken;
5229 commandEntry->newToken = newToken;
Siarhei Vishniakoue7c94b92019-07-29 09:17:54 -07005230 postCommandLocked(std::move(commandEntry));
Robert Carrf759f162018-11-13 12:57:11 -08005231}
5232
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005233void InputDispatcher::onAnrLocked(const sp<Connection>& connection) {
5234 if (connection == nullptr) {
5235 LOG_ALWAYS_FATAL("Caller must check for nullness");
5236 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005237 // Since we are allowing the policy to extend the timeout, maybe the waitQueue
5238 // is already healthy again. Don't raise ANR in this situation
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005239 if (connection->waitQueue.empty()) {
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005240 ALOGI("Not raising ANR because the connection %s has recovered",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005241 connection->inputChannel->getName().c_str());
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005242 return;
5243 }
5244 /**
5245 * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
5246 * may not be the one that caused the timeout to occur. One possibility is that window timeout
5247 * has changed. This could cause newer entries to time out before the already dispatched
5248 * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
5249 * processes the events linearly. So providing information about the oldest entry seems to be
5250 * most useful.
5251 */
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005252 DispatchEntry* oldestEntry = *connection->waitQueue.begin();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005253 const nsecs_t currentWait = now() - oldestEntry->deliveryTime;
5254 std::string reason =
5255 android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005256 connection->inputChannel->getName().c_str(),
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005257 ns2ms(currentWait),
5258 oldestEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005259 sp<IBinder> connectionToken = connection->inputChannel->getConnectionToken();
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005260 updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005261
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005262 processConnectionUnresponsiveLocked(*connection, std::move(reason));
5263
5264 // Stop waking up for events on this connection, it is already unresponsive
5265 cancelEventsForAnrLocked(connection);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005266}
5267
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005268void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
5269 std::string reason =
5270 StringPrintf("%s does not have a focused window", application->getName().c_str());
5271 updateLastAnrStateLocked(*application, reason);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005272
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005273 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5274 &InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible);
5275 commandEntry->inputApplicationHandle = std::move(application);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005276 postCommandLocked(std::move(commandEntry));
5277}
5278
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005279void InputDispatcher::onUntrustedTouchLocked(const std::string& obscuringPackage) {
5280 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
5281 &InputDispatcher::doNotifyUntrustedTouchLockedInterruptible);
5282 commandEntry->obscuringPackage = obscuringPackage;
5283 postCommandLocked(std::move(commandEntry));
5284}
5285
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005286void InputDispatcher::updateLastAnrStateLocked(const sp<InputWindowHandle>& window,
5287 const std::string& reason) {
5288 const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
5289 updateLastAnrStateLocked(windowLabel, reason);
5290}
5291
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005292void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
5293 const std::string& reason) {
5294 const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005295 updateLastAnrStateLocked(windowLabel, reason);
5296}
5297
5298void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
5299 const std::string& reason) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005300 // Capture a record of the InputDispatcher state at the time of the ANR.
Yi Kong9b14ac62018-07-17 13:48:38 -07005301 time_t t = time(nullptr);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005302 struct tm tm;
5303 localtime_r(&t, &tm);
5304 char timestr[64];
5305 strftime(timestr, sizeof(timestr), "%F %T", &tm);
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005306 mLastAnrState.clear();
5307 mLastAnrState += INDENT "ANR:\n";
5308 mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005309 mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
5310 mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005311 dumpDispatchStateLocked(mLastAnrState);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005312}
5313
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005314void InputDispatcher::doNotifyConfigurationChangedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005315 mLock.unlock();
5316
5317 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
5318
5319 mLock.lock();
5320}
5321
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005322void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005323 sp<Connection> connection = commandEntry->connection;
5324
5325 if (connection->status != Connection::STATUS_ZOMBIE) {
5326 mLock.unlock();
5327
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005328 mPolicy->notifyInputChannelBroken(connection->inputChannel->getConnectionToken());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005329
5330 mLock.lock();
5331 }
5332}
5333
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005334void InputDispatcher::doNotifyFocusChangedLockedInterruptible(CommandEntry* commandEntry) {
chaviw0c06c6e2019-01-09 13:27:07 -08005335 sp<IBinder> oldToken = commandEntry->oldToken;
5336 sp<IBinder> newToken = commandEntry->newToken;
Robert Carrf759f162018-11-13 12:57:11 -08005337 mLock.unlock();
chaviw0c06c6e2019-01-09 13:27:07 -08005338 mPolicy->notifyFocusChanged(oldToken, newToken);
Robert Carrf759f162018-11-13 12:57:11 -08005339 mLock.lock();
5340}
5341
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005342void InputDispatcher::doNotifyNoFocusedWindowAnrLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005343 mLock.unlock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005344
5345 mPolicy->notifyNoFocusedWindowAnr(commandEntry->inputApplicationHandle);
5346
5347 mLock.lock();
5348}
5349
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005350void InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005351 mLock.unlock();
5352
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005353 mPolicy->notifyWindowUnresponsive(commandEntry->connectionToken, commandEntry->reason);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005354
5355 mLock.lock();
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005356}
5357
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005358void InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible(CommandEntry* commandEntry) {
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005359 mLock.unlock();
5360
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005361 mPolicy->notifyMonitorUnresponsive(commandEntry->pid, commandEntry->reason);
5362
5363 mLock.lock();
5364}
5365
5366void InputDispatcher::doNotifyWindowResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5367 mLock.unlock();
5368
5369 mPolicy->notifyWindowResponsive(commandEntry->connectionToken);
5370
5371 mLock.lock();
5372}
5373
5374void InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible(CommandEntry* commandEntry) {
5375 mLock.unlock();
5376
5377 mPolicy->notifyMonitorResponsive(commandEntry->pid);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005378
5379 mLock.lock();
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005380}
5381
Bernardo Rufino2e1f6512020-10-08 13:42:07 +00005382void InputDispatcher::doNotifyUntrustedTouchLockedInterruptible(CommandEntry* commandEntry) {
5383 mLock.unlock();
5384
5385 mPolicy->notifyUntrustedTouch(commandEntry->obscuringPackage);
5386
5387 mLock.lock();
5388}
5389
Michael Wrightd02c5b62014-02-10 15:10:22 -08005390void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
5391 CommandEntry* commandEntry) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005392 KeyEntry& entry = *(commandEntry->keyEntry);
5393 KeyEvent event = createKeyEvent(entry);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005394
5395 mLock.unlock();
5396
Michael Wright2b3c3302018-03-02 17:19:13 +00005397 android::base::Timer t;
Siarhei Vishniakou2b4782c2020-11-07 01:51:18 -06005398 const sp<IBinder>& token = commandEntry->connectionToken;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005399 nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(token, &event, entry.policyFlags);
Michael Wright2b3c3302018-03-02 17:19:13 +00005400 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
5401 ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005402 std::to_string(t.duration().count()).c_str());
Michael Wright2b3c3302018-03-02 17:19:13 +00005403 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005404
5405 mLock.lock();
5406
5407 if (delay < 0) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005408 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005409 } else if (!delay) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005410 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005411 } else {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005412 entry.interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
5413 entry.interceptKeyWakeupTime = now() + delay;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005414 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005415}
5416
chaviwfd6d3512019-03-25 13:23:49 -07005417void InputDispatcher::doOnPointerDownOutsideFocusLockedInterruptible(CommandEntry* commandEntry) {
5418 mLock.unlock();
5419 mPolicy->onPointerDownOutsideFocus(commandEntry->newToken);
5420 mLock.lock();
5421}
5422
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005423/**
5424 * Connection is responsive if it has no events in the waitQueue that are older than the
5425 * current time.
5426 */
5427static bool isConnectionResponsive(const Connection& connection) {
5428 const nsecs_t currentTime = now();
5429 for (const DispatchEntry* entry : connection.waitQueue) {
5430 if (entry->timeoutTime < currentTime) {
5431 return false;
5432 }
5433 }
5434 return true;
5435}
5436
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005437void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005438 sp<Connection> connection = commandEntry->connection;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005439 const nsecs_t finishTime = commandEntry->eventTime;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005440 uint32_t seq = commandEntry->seq;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005441 const bool handled = commandEntry->handled;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005442
5443 // Handle post-event policy actions.
Garfield Tane84e6f92019-08-29 17:28:41 -07005444 std::deque<DispatchEntry*>::iterator dispatchEntryIt = connection->findWaitQueueEntry(seq);
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005445 if (dispatchEntryIt == connection->waitQueue.end()) {
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005446 return;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005447 }
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005448 DispatchEntry* dispatchEntry = *dispatchEntryIt;
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005449 const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005450 if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
Siarhei Vishniakou4cb50ca2020-05-26 21:43:02 -07005451 ALOGI("%s spent %" PRId64 "ms processing %s", connection->getWindowName().c_str(),
5452 ns2ms(eventDuration), dispatchEntry->eventEntry->getDescription().c_str());
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005453 }
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005454 reportDispatchStatistics(std::chrono::nanoseconds(eventDuration), *connection, handled);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005455
5456 bool restartEvent;
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005457 if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005458 KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005459 restartEvent =
5460 afterKeyEventLockedInterruptible(connection, dispatchEntry, keyEntry, handled);
Siarhei Vishniakou49483272019-10-22 13:13:47 -07005461 } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) {
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005462 MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry));
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005463 restartEvent = afterMotionEventLockedInterruptible(connection, dispatchEntry, motionEntry,
5464 handled);
5465 } else {
5466 restartEvent = false;
5467 }
5468
5469 // Dequeue the event and start the next cycle.
Siarhei Vishniakou850ce122020-05-26 22:39:43 -07005470 // Because the lock might have been released, it is possible that the
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005471 // contents of the wait queue to have been drained, so we need to double-check
5472 // a few things.
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005473 dispatchEntryIt = connection->findWaitQueueEntry(seq);
5474 if (dispatchEntryIt != connection->waitQueue.end()) {
5475 dispatchEntry = *dispatchEntryIt;
5476 connection->waitQueue.erase(dispatchEntryIt);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005477 const sp<IBinder>& connectionToken = connection->inputChannel->getConnectionToken();
5478 mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005479 if (!connection->responsive) {
5480 connection->responsive = isConnectionResponsive(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005481 if (connection->responsive) {
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005482 // The connection was unresponsive, and now it's responsive.
5483 processConnectionResponsiveLocked(*connection);
Siarhei Vishniakou234129c2020-10-22 22:28:12 -05005484 }
Siarhei Vishniakoud44dddf2020-03-25 16:16:40 -07005485 }
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005486 traceWaitQueueLength(connection);
5487 if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005488 connection->outboundQueue.push_front(dispatchEntry);
Siarhei Vishniakou4e68fbf2019-07-31 14:00:52 -07005489 traceOutboundQueueLength(connection);
5490 } else {
5491 releaseDispatchEntry(dispatchEntry);
5492 }
5493 }
5494
5495 // Start the next dispatch cycle for this connection.
5496 startDispatchCycleLocked(now(), connection);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005497}
5498
Siarhei Vishniakou3c63fa42020-12-15 02:59:54 +00005499void InputDispatcher::sendMonitorUnresponsiveCommandLocked(int32_t pid, std::string reason) {
5500 std::unique_ptr<CommandEntry> monitorUnresponsiveCommand = std::make_unique<CommandEntry>(
5501 &InputDispatcher::doNotifyMonitorUnresponsiveLockedInterruptible);
5502 monitorUnresponsiveCommand->pid = pid;
5503 monitorUnresponsiveCommand->reason = std::move(reason);
5504 postCommandLocked(std::move(monitorUnresponsiveCommand));
5505}
5506
5507void InputDispatcher::sendWindowUnresponsiveCommandLocked(sp<IBinder> connectionToken,
5508 std::string reason) {
5509 std::unique_ptr<CommandEntry> windowUnresponsiveCommand = std::make_unique<CommandEntry>(
5510 &InputDispatcher::doNotifyWindowUnresponsiveLockedInterruptible);
5511 windowUnresponsiveCommand->connectionToken = std::move(connectionToken);
5512 windowUnresponsiveCommand->reason = std::move(reason);
5513 postCommandLocked(std::move(windowUnresponsiveCommand));
5514}
5515
5516void InputDispatcher::sendMonitorResponsiveCommandLocked(int32_t pid) {
5517 std::unique_ptr<CommandEntry> monitorResponsiveCommand = std::make_unique<CommandEntry>(
5518 &InputDispatcher::doNotifyMonitorResponsiveLockedInterruptible);
5519 monitorResponsiveCommand->pid = pid;
5520 postCommandLocked(std::move(monitorResponsiveCommand));
5521}
5522
5523void InputDispatcher::sendWindowResponsiveCommandLocked(sp<IBinder> connectionToken) {
5524 std::unique_ptr<CommandEntry> windowResponsiveCommand = std::make_unique<CommandEntry>(
5525 &InputDispatcher::doNotifyWindowResponsiveLockedInterruptible);
5526 windowResponsiveCommand->connectionToken = std::move(connectionToken);
5527 postCommandLocked(std::move(windowResponsiveCommand));
5528}
5529
5530/**
5531 * Tell the policy that a connection has become unresponsive so that it can start ANR.
5532 * Check whether the connection of interest is a monitor or a window, and add the corresponding
5533 * command entry to the command queue.
5534 */
5535void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
5536 std::string reason) {
5537 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5538 if (connection.monitor) {
5539 ALOGW("Monitor %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5540 reason.c_str());
5541 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5542 if (!pid.has_value()) {
5543 ALOGE("Could not find unresponsive monitor for connection %s",
5544 connection.inputChannel->getName().c_str());
5545 return;
5546 }
5547 sendMonitorUnresponsiveCommandLocked(pid.value(), std::move(reason));
5548 return;
5549 }
5550 // If not a monitor, must be a window
5551 ALOGW("Window %s is unresponsive: %s", connection.inputChannel->getName().c_str(),
5552 reason.c_str());
5553 sendWindowUnresponsiveCommandLocked(connectionToken, std::move(reason));
5554}
5555
5556/**
5557 * Tell the policy that a connection has become responsive so that it can stop ANR.
5558 */
5559void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
5560 const sp<IBinder>& connectionToken = connection.inputChannel->getConnectionToken();
5561 if (connection.monitor) {
5562 std::optional<int32_t> pid = findMonitorPidByTokenLocked(connectionToken);
5563 if (!pid.has_value()) {
5564 ALOGE("Could not find responsive monitor for connection %s",
5565 connection.inputChannel->getName().c_str());
5566 return;
5567 }
5568 sendMonitorResponsiveCommandLocked(pid.value());
5569 return;
5570 }
5571 // If not a monitor, must be a window
5572 sendWindowResponsiveCommandLocked(connectionToken);
5573}
5574
Michael Wrightd02c5b62014-02-10 15:10:22 -08005575bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005576 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005577 KeyEntry& keyEntry, bool handled) {
5578 if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005579 if (!handled) {
5580 // Report the key as unhandled, since the fallback was not handled.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005581 mReporter->reportUnhandledKey(keyEntry.id);
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005582 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005583 return false;
5584 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005585
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005586 // Get the fallback key state.
5587 // Clear it out after dispatching the UP.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005588 int32_t originalKeyCode = keyEntry.keyCode;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005589 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005590 if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005591 connection->inputState.removeFallbackKey(originalKeyCode);
5592 }
5593
5594 if (handled || !dispatchEntry->hasForegroundTarget()) {
5595 // If the application handles the original key for which we previously
5596 // generated a fallback or if the window is not a foreground window,
5597 // then cancel the associated fallback key, if any.
5598 if (fallbackKeyCode != -1) {
5599 // Dispatch the unhandled key to the policy with the cancel flag.
Michael Wrightd02c5b62014-02-10 15:10:22 -08005600#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005601 ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005602 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005603 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005604#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005605 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005606 event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005607
5608 mLock.unlock();
5609
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005610 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(), &event,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005611 keyEntry.policyFlags, &event);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005612
5613 mLock.lock();
5614
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005615 // Cancel the fallback key.
5616 if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005617 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005618 "application handled the original non-fallback key "
5619 "or is no longer a foreground target, "
5620 "canceling previously dispatched fallback key");
Michael Wrightd02c5b62014-02-10 15:10:22 -08005621 options.keyCode = fallbackKeyCode;
5622 synthesizeCancelationEventsForConnectionLocked(connection, options);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005623 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005624 connection->inputState.removeFallbackKey(originalKeyCode);
5625 }
5626 } else {
5627 // If the application did not handle a non-fallback key, first check
5628 // that we are in a good state to perform unhandled key event processing
5629 // Then ask the policy what to do with it.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005630 bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005631 if (fallbackKeyCode == -1 && !initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005632#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005633 ALOGD("Unhandled key event: Skipping unhandled key event processing "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005634 "since this is not an initial down. "
5635 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005636 originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005637#endif
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005638 return false;
5639 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005640
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005641 // Dispatch the unhandled key to the policy.
5642#if DEBUG_OUTBOUND_EVENT_DETAILS
5643 ALOGD("Unhandled key event: Asking policy to perform fallback action. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005644 "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005645 keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005646#endif
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005647 KeyEvent event = createKeyEvent(keyEntry);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005648
5649 mLock.unlock();
5650
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -07005651 bool fallback =
5652 mPolicy->dispatchUnhandledKey(connection->inputChannel->getConnectionToken(),
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005653 &event, keyEntry.policyFlags, &event);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005654
5655 mLock.lock();
5656
5657 if (connection->status != Connection::STATUS_NORMAL) {
5658 connection->inputState.removeFallbackKey(originalKeyCode);
5659 return false;
5660 }
5661
5662 // Latch the fallback keycode for this key on an initial down.
5663 // The fallback keycode cannot change at any other point in the lifecycle.
5664 if (initialDown) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005665 if (fallback) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005666 fallbackKeyCode = event.getKeyCode();
5667 } else {
5668 fallbackKeyCode = AKEYCODE_UNKNOWN;
5669 }
5670 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
5671 }
5672
5673 ALOG_ASSERT(fallbackKeyCode != -1);
5674
5675 // Cancel the fallback key if the policy decides not to send it anymore.
5676 // We will continue to dispatch the key to the policy but we will no
5677 // longer dispatch a fallback key to the application.
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005678 if (fallbackKeyCode != AKEYCODE_UNKNOWN &&
5679 (!fallback || fallbackKeyCode != event.getKeyCode())) {
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005680#if DEBUG_OUTBOUND_EVENT_DETAILS
5681 if (fallback) {
5682 ALOGD("Unhandled key event: Policy requested to send key %d"
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005683 "as a fallback for %d, but on the DOWN it had requested "
5684 "to send %d instead. Fallback canceled.",
5685 event.getKeyCode(), originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005686 } else {
5687 ALOGD("Unhandled key event: Policy did not request fallback for %d, "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005688 "but on the DOWN it had requested to send %d. "
5689 "Fallback canceled.",
5690 originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005691 }
5692#endif
5693
5694 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
5695 "canceling fallback, policy no longer desires it");
5696 options.keyCode = fallbackKeyCode;
5697 synthesizeCancelationEventsForConnectionLocked(connection, options);
5698
5699 fallback = false;
5700 fallbackKeyCode = AKEYCODE_UNKNOWN;
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005701 if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005702 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005703 }
5704 }
Michael Wrightd02c5b62014-02-10 15:10:22 -08005705
5706#if DEBUG_OUTBOUND_EVENT_DETAILS
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005707 {
5708 std::string msg;
5709 const KeyedVector<int32_t, int32_t>& fallbackKeys =
5710 connection->inputState.getFallbackKeys();
5711 for (size_t i = 0; i < fallbackKeys.size(); i++) {
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005712 msg += StringPrintf(", %d->%d", fallbackKeys.keyAt(i), fallbackKeys.valueAt(i));
Michael Wrightd02c5b62014-02-10 15:10:22 -08005713 }
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005714 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005715 fallbackKeys.size(), msg.c_str());
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005716 }
5717#endif
5718
5719 if (fallback) {
5720 // Restart the dispatch cycle using the fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005721 keyEntry.eventTime = event.getEventTime();
5722 keyEntry.deviceId = event.getDeviceId();
5723 keyEntry.source = event.getSource();
5724 keyEntry.displayId = event.getDisplayId();
5725 keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
5726 keyEntry.keyCode = fallbackKeyCode;
5727 keyEntry.scanCode = event.getScanCode();
5728 keyEntry.metaState = event.getMetaState();
5729 keyEntry.repeatCount = event.getRepeatCount();
5730 keyEntry.downTime = event.getDownTime();
5731 keyEntry.syntheticRepeat = false;
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005732
5733#if DEBUG_OUTBOUND_EVENT_DETAILS
5734 ALOGD("Unhandled key event: Dispatching fallback key. "
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005735 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005736 originalKeyCode, fallbackKeyCode, keyEntry.metaState);
Prabir Pradhanf557dcf2018-12-18 16:38:14 -08005737#endif
5738 return true; // restart the event
5739 } else {
5740#if DEBUG_OUTBOUND_EVENT_DETAILS
5741 ALOGD("Unhandled key event: No fallback key.");
5742#endif
Prabir Pradhanf93562f2018-11-29 12:13:37 -08005743
5744 // Report the key as unhandled, since there is no fallback key.
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005745 mReporter->reportUnhandledKey(keyEntry.id);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005746 }
5747 }
5748 return false;
5749}
5750
5751bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
Garfield Tan0fc2fa72019-08-29 17:22:15 -07005752 DispatchEntry* dispatchEntry,
Siarhei Vishniakoua9a7ee82019-10-14 16:28:19 -07005753 MotionEntry& motionEntry, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005754 return false;
5755}
5756
5757void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
5758 mLock.unlock();
5759
5760 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
5761
5762 mLock.lock();
5763}
5764
Siarhei Vishniakou767917f2020-03-24 20:49:09 -07005765void InputDispatcher::reportDispatchStatistics(std::chrono::nanoseconds eventDuration,
5766 const Connection& connection, bool handled) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005767 // TODO Write some statistics about how long we spend waiting.
5768}
5769
Siarhei Vishniakoude4bf152019-08-16 11:12:52 -05005770/**
5771 * Report the touch event latency to the statsd server.
5772 * Input events are reported for statistics if:
5773 * - This is a touchscreen event
5774 * - InputFilter is not enabled
5775 * - Event is not injected or synthesized
5776 *
5777 * Statistics should be reported before calling addValue, to prevent a fresh new sample
5778 * from getting aggregated with the "old" data.
5779 */
5780void InputDispatcher::reportTouchEventForStatistics(const MotionEntry& motionEntry)
5781 REQUIRES(mLock) {
5782 const bool reportForStatistics = (motionEntry.source == AINPUT_SOURCE_TOUCHSCREEN) &&
5783 !(motionEntry.isSynthesized()) && !mInputFilterEnabled;
5784 if (!reportForStatistics) {
5785 return;
5786 }
5787
5788 if (mTouchStatistics.shouldReport()) {
5789 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
5790 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
5791 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
5792 mTouchStatistics.reset();
5793 }
5794 const float latencyMicros = nanoseconds_to_microseconds(now() - motionEntry.eventTime);
5795 mTouchStatistics.addValue(latencyMicros);
5796}
5797
Michael Wrightd02c5b62014-02-10 15:10:22 -08005798void InputDispatcher::traceInboundQueueLengthLocked() {
5799 if (ATRACE_ENABLED()) {
Siarhei Vishniakou44a2aed2019-07-29 08:59:52 -07005800 ATRACE_INT("iq", mInboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005801 }
5802}
5803
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005804void InputDispatcher::traceOutboundQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005805 if (ATRACE_ENABLED()) {
5806 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005807 snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005808 ATRACE_INT(counterName, connection->outboundQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005809 }
5810}
5811
Siarhei Vishniakou61291d42019-02-11 18:13:20 -08005812void InputDispatcher::traceWaitQueueLength(const sp<Connection>& connection) {
Michael Wrightd02c5b62014-02-10 15:10:22 -08005813 if (ATRACE_ENABLED()) {
5814 char counterName[40];
Siarhei Vishniakou587c3f02018-01-04 11:46:44 -08005815 snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName().c_str());
Siarhei Vishniakou13bda6c2019-07-29 08:34:33 -07005816 ATRACE_INT(counterName, connection->waitQueue.size());
Michael Wrightd02c5b62014-02-10 15:10:22 -08005817 }
5818}
5819
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005820void InputDispatcher::dump(std::string& dump) {
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005821 std::scoped_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005822
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005823 dump += "Input Dispatcher State:\n";
Michael Wrightd02c5b62014-02-10 15:10:22 -08005824 dumpDispatchStateLocked(dump);
5825
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005826 if (!mLastAnrState.empty()) {
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08005827 dump += "\nInput Dispatcher State at time of last ANR:\n";
Siarhei Vishniakoub1a16272020-05-06 16:09:19 -07005828 dump += mLastAnrState;
Michael Wrightd02c5b62014-02-10 15:10:22 -08005829 }
5830}
5831
5832void InputDispatcher::monitor() {
5833 // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005834 std::unique_lock _l(mLock);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005835 mLooper->wake();
Siarhei Vishniakou443ad902019-03-06 17:25:41 -08005836 mDispatcherIsAlive.wait(_l);
Michael Wrightd02c5b62014-02-10 15:10:22 -08005837}
5838
Siarhei Vishniakou2bfa9052019-11-21 18:10:54 -08005839/**
5840 * Wake up the dispatcher and wait until it processes all events and commands.
5841 * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
5842 * this method can be safely called from any thread, as long as you've ensured that
5843 * the work you are interested in completing has already been queued.
5844 */
5845bool InputDispatcher::waitForIdle() {
5846 /**
5847 * Timeout should represent the longest possible time that a device might spend processing
5848 * events and commands.
5849 */
5850 constexpr std::chrono::duration TIMEOUT = 100ms;
5851 std::unique_lock lock(mLock);
5852 mLooper->wake();
5853 std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
5854 return result == std::cv_status::no_timeout;
5855}
5856
Vishnu Naire798b472020-07-23 13:52:21 -07005857/**
5858 * Sets focus to the window identified by the token. This must be called
5859 * after updating any input window handles.
5860 *
5861 * Params:
5862 * request.token - input channel token used to identify the window that should gain focus.
5863 * request.focusedToken - the token that the caller expects currently to be focused. If the
5864 * specified token does not match the currently focused window, this request will be dropped.
5865 * If the specified focused token matches the currently focused window, the call will succeed.
5866 * Set this to "null" if this call should succeed no matter what the currently focused token is.
5867 * request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
5868 * when requesting the focus change. This determines which request gets
5869 * precedence if there is a focus change request from another source such as pointer down.
5870 */
Vishnu Nair958da932020-08-21 17:12:37 -07005871void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
5872 { // acquire lock
5873 std::scoped_lock _l(mLock);
5874
5875 const int32_t displayId = request.displayId;
5876 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5877 if (request.focusedToken && oldFocusedToken != request.focusedToken) {
5878 ALOGD_IF(DEBUG_FOCUS,
5879 "setFocusedWindow on display %" PRId32
5880 " ignored, reason: focusedToken is not focused",
5881 displayId);
5882 return;
5883 }
5884
5885 mPendingFocusRequests.erase(displayId);
5886 FocusResult result = handleFocusRequestLocked(request);
5887 if (result == FocusResult::NOT_VISIBLE) {
5888 // The requested window is not currently visible. Wait for the window to become visible
5889 // and then provide it focus. This is to handle situations where a user action triggers
5890 // a new window to appear. We want to be able to queue any key events after the user
5891 // action and deliver it to the newly focused window. In order for this to happen, we
5892 // take focus from the currently focused window so key events can be queued.
5893 ALOGD_IF(DEBUG_FOCUS,
5894 "setFocusedWindow on display %" PRId32
5895 " pending, reason: window is not visible",
5896 displayId);
5897 mPendingFocusRequests[displayId] = request;
5898 onFocusChangedLocked(oldFocusedToken, nullptr, displayId,
5899 "setFocusedWindow_AwaitingWindowVisibility");
5900 } else if (result != FocusResult::OK) {
5901 ALOGW("setFocusedWindow on display %" PRId32 " ignored, reason:%s", displayId,
5902 typeToString(result));
5903 }
5904 } // release lock
5905 // Wake up poll loop since it may need to make new input dispatching choices.
5906 mLooper->wake();
5907}
5908
5909InputDispatcher::FocusResult InputDispatcher::handleFocusRequestLocked(
5910 const FocusRequest& request) {
5911 const int32_t displayId = request.displayId;
5912 const sp<IBinder> newFocusedToken = request.token;
5913 const sp<IBinder> oldFocusedToken = getValueByKey(mFocusedWindowTokenByDisplay, displayId);
5914
5915 if (oldFocusedToken == request.token) {
5916 ALOGD_IF(DEBUG_FOCUS,
5917 "setFocusedWindow on display %" PRId32 " ignored, reason: already focused",
5918 displayId);
5919 return FocusResult::OK;
5920 }
5921
5922 FocusResult result = checkTokenFocusableLocked(newFocusedToken, displayId);
5923 if (result != FocusResult::OK) {
5924 return result;
5925 }
5926
5927 std::string_view reason =
5928 (request.focusedToken) ? "setFocusedWindow_FocusCheck" : "setFocusedWindow";
5929 onFocusChangedLocked(oldFocusedToken, newFocusedToken, displayId, reason);
5930 return FocusResult::OK;
5931}
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005932
Vishnu Nairad321cd2020-08-20 16:40:21 -07005933void InputDispatcher::onFocusChangedLocked(const sp<IBinder>& oldFocusedToken,
5934 const sp<IBinder>& newFocusedToken, int32_t displayId,
5935 std::string_view reason) {
5936 if (oldFocusedToken) {
5937 std::shared_ptr<InputChannel> focusedInputChannel = getInputChannelLocked(oldFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005938 if (focusedInputChannel) {
5939 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
5940 "focus left window");
5941 synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
Vishnu Nairad321cd2020-08-20 16:40:21 -07005942 enqueueFocusEventLocked(oldFocusedToken, false /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005943 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005944 mFocusedWindowTokenByDisplay.erase(displayId);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005945 }
Vishnu Nairad321cd2020-08-20 16:40:21 -07005946 if (newFocusedToken) {
5947 mFocusedWindowTokenByDisplay[displayId] = newFocusedToken;
5948 enqueueFocusEventLocked(newFocusedToken, true /*hasFocus*/, reason);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005949 }
5950
Prabir Pradhan99987712020-11-10 18:43:05 -08005951 // If a window has pointer capture, then it must have focus. We need to ensure that this
5952 // contract is upheld when pointer capture is being disabled due to a loss of window focus.
5953 // If the window loses focus before it loses pointer capture, then the window can be in a state
5954 // where it has pointer capture but not focus, violating the contract. Therefore we must
5955 // dispatch the pointer capture event before the focus event. Since focus events are added to
5956 // the front of the queue (above), we add the pointer capture event to the front of the queue
5957 // after the focus events are added. This ensures the pointer capture event ends up at the
5958 // front.
5959 disablePointerCaptureForcedLocked();
5960
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005961 if (mFocusedDisplayId == displayId) {
Vishnu Nairad321cd2020-08-20 16:40:21 -07005962 notifyFocusChangedLocked(oldFocusedToken, newFocusedToken);
Vishnu Nair7d3d00d2020-08-03 11:20:42 -07005963 }
5964}
Vishnu Nair958da932020-08-21 17:12:37 -07005965
Prabir Pradhan99987712020-11-10 18:43:05 -08005966void InputDispatcher::disablePointerCaptureForcedLocked() {
5967 if (!mFocusedWindowRequestedPointerCapture && !mWindowTokenWithPointerCapture) {
5968 return;
5969 }
5970
5971 ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
5972
5973 if (mFocusedWindowRequestedPointerCapture) {
5974 mFocusedWindowRequestedPointerCapture = false;
5975 setPointerCaptureLocked(false);
5976 }
5977
5978 if (!mWindowTokenWithPointerCapture) {
5979 // No need to send capture changes because no window has capture.
5980 return;
5981 }
5982
5983 if (mPendingEvent != nullptr) {
5984 // Move the pending event to the front of the queue. This will give the chance
5985 // for the pending event to be dropped if it is a captured event.
5986 mInboundQueue.push_front(mPendingEvent);
5987 mPendingEvent = nullptr;
5988 }
5989
5990 auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
5991 false /* hasCapture */);
5992 mInboundQueue.push_front(std::move(entry));
5993}
5994
Vishnu Nair958da932020-08-21 17:12:37 -07005995/**
5996 * Checks if the window token can be focused on a display. The token can be focused if there is
5997 * at least one window handle that is visible with the same token and all window handles with the
5998 * same token are focusable.
5999 *
6000 * In the case of mirroring, two windows may share the same window token and their visibility
6001 * might be different. Example, the mirrored window can cover the window its mirroring. However,
6002 * we expect the focusability of the windows to match since its hard to reason why one window can
6003 * receive focus events and the other cannot when both are backed by the same input channel.
6004 */
6005InputDispatcher::FocusResult InputDispatcher::checkTokenFocusableLocked(const sp<IBinder>& token,
6006 int32_t displayId) const {
6007 bool allWindowsAreFocusable = true;
6008 bool visibleWindowFound = false;
6009 bool windowFound = false;
6010 for (const sp<InputWindowHandle>& window : getWindowHandlesLocked(displayId)) {
6011 if (window->getToken() != token) {
6012 continue;
6013 }
6014 windowFound = true;
6015 if (window->getInfo()->visible) {
6016 // Check if at least a single window is visible.
6017 visibleWindowFound = true;
6018 }
6019 if (!window->getInfo()->focusable) {
6020 // Check if all windows with the window token are focusable.
6021 allWindowsAreFocusable = false;
6022 break;
6023 }
6024 }
6025
6026 if (!windowFound) {
6027 return FocusResult::NO_WINDOW;
6028 }
6029 if (!allWindowsAreFocusable) {
6030 return FocusResult::NOT_FOCUSABLE;
6031 }
6032 if (!visibleWindowFound) {
6033 return FocusResult::NOT_VISIBLE;
6034 }
6035
6036 return FocusResult::OK;
6037}
Prabir Pradhan99987712020-11-10 18:43:05 -08006038
6039void InputDispatcher::setPointerCaptureLocked(bool enabled) {
6040 std::unique_ptr<CommandEntry> commandEntry = std::make_unique<CommandEntry>(
6041 &InputDispatcher::doSetPointerCaptureLockedInterruptible);
6042 commandEntry->enabled = enabled;
6043 postCommandLocked(std::move(commandEntry));
6044}
6045
6046void InputDispatcher::doSetPointerCaptureLockedInterruptible(
6047 android::inputdispatcher::CommandEntry* commandEntry) {
6048 mLock.unlock();
6049
6050 mPolicy->setPointerCapture(commandEntry->enabled);
6051
6052 mLock.lock();
6053}
6054
Garfield Tane84e6f92019-08-29 17:28:41 -07006055} // namespace android::inputdispatcher