blob: b3a36ebf5a8854c8d102738f11d196a7e600eda3 [file] [log] [blame]
Jeff Brown5912f952013-07-01 19:10:31 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// Provides a shared memory transport for input events.
5//
6#define LOG_TAG "InputTransport"
Zimd8402b62023-06-02 11:56:26 +01007#define ATRACE_TAG ATRACE_TAG_INPUT
Jeff Brown5912f952013-07-01 19:10:31 -07008
Jeff Brown5912f952013-07-01 19:10:31 -07009#include <errno.h>
10#include <fcntl.h>
Michael Wrightd0a4a622014-06-09 19:03:32 -070011#include <inttypes.h>
Jeff Brown5912f952013-07-01 19:10:31 -070012#include <math.h>
Egor Paskoa0d32af2023-12-14 17:45:41 +010013#include <poll.h>
Jeff Brown5912f952013-07-01 19:10:31 -070014#include <sys/socket.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070015#include <sys/types.h>
Jeff Brown5912f952013-07-01 19:10:31 -070016#include <unistd.h>
17
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -070018#include <android-base/logging.h>
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +000019#include <android-base/properties.h>
Michael Wright3dd60e22019-03-27 22:06:44 +000020#include <android-base/stringprintf.h>
21#include <binder/Parcel.h>
Jeff Brown5912f952013-07-01 19:10:31 -070022#include <cutils/properties.h>
Dominik Laskowski75788452021-02-09 18:51:25 -080023#include <ftl/enum.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070024#include <log/log.h>
Michael Wright3dd60e22019-03-27 22:06:44 +000025#include <utils/Trace.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070026
Siarhei Vishniakou96818962023-08-23 10:19:02 -070027#include <com_android_input_flags.h>
Jeff Brown5912f952013-07-01 19:10:31 -070028#include <input/InputTransport.h>
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -080029#include <input/PrintTools.h>
Prabir Pradhana37bad12023-08-18 15:55:32 +000030#include <input/TraceTools.h>
Jeff Brown5912f952013-07-01 19:10:31 -070031
Siarhei Vishniakou96818962023-08-23 10:19:02 -070032namespace input_flags = com::android::input::flags;
33
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -080034namespace android {
35
Prabir Pradhan60dd97a2023-02-23 02:23:02 +000036namespace {
37
38/**
39 * Log debug messages about channel messages (send message, receive message).
40 * Enable this via "adb shell setprop log.tag.InputTransportMessages DEBUG"
41 * (requires restart)
42 */
43const bool DEBUG_CHANNEL_MESSAGES =
44 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Messages", ANDROID_LOG_INFO);
45
46/**
47 * Log debug messages whenever InputChannel objects are created/destroyed.
48 * Enable this via "adb shell setprop log.tag.InputTransportLifecycle DEBUG"
49 * (requires restart)
50 */
51const bool DEBUG_CHANNEL_LIFECYCLE =
52 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Lifecycle", ANDROID_LOG_INFO);
53
54/**
55 * Log debug messages relating to the consumer end of the transport channel.
56 * Enable this via "adb shell setprop log.tag.InputTransportConsumer DEBUG" (requires restart)
57 */
58
59const bool DEBUG_TRANSPORT_CONSUMER =
60 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Consumer", ANDROID_LOG_INFO);
61
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +000062const bool IS_DEBUGGABLE_BUILD =
63#if defined(__ANDROID__)
64 android::base::GetBoolProperty("ro.debuggable", false);
65#else
66 true;
67#endif
68
Prabir Pradhan60dd97a2023-02-23 02:23:02 +000069/**
70 * Log debug messages relating to the producer end of the transport channel.
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +000071 * Enable this via "adb shell setprop log.tag.InputTransportPublisher DEBUG".
72 * This requires a restart on non-debuggable (e.g. user) builds, but should take effect immediately
73 * on debuggable builds (e.g. userdebug).
Prabir Pradhan60dd97a2023-02-23 02:23:02 +000074 */
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +000075bool debugTransportPublisher() {
76 if (!IS_DEBUGGABLE_BUILD) {
77 static const bool DEBUG_TRANSPORT_PUBLISHER =
78 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Publisher", ANDROID_LOG_INFO);
79 return DEBUG_TRANSPORT_PUBLISHER;
80 }
81 return __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Publisher", ANDROID_LOG_INFO);
82}
Prabir Pradhan60dd97a2023-02-23 02:23:02 +000083
84/**
85 * Log debug messages about touch event resampling.
Harry Cutts6c658cc2023-08-02 14:40:40 +000086 *
87 * Enable this via "adb shell setprop log.tag.InputTransportResampling DEBUG".
88 * This requires a restart on non-debuggable (e.g. user) builds, but should take effect immediately
89 * on debuggable builds (e.g. userdebug).
Prabir Pradhan60dd97a2023-02-23 02:23:02 +000090 */
Harry Cutts6c658cc2023-08-02 14:40:40 +000091bool debugResampling() {
92 if (!IS_DEBUGGABLE_BUILD) {
93 static const bool DEBUG_TRANSPORT_RESAMPLING =
94 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Resampling",
95 ANDROID_LOG_INFO);
96 return DEBUG_TRANSPORT_RESAMPLING;
97 }
98 return __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "Resampling", ANDROID_LOG_INFO);
99}
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000100
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800101android::base::unique_fd dupChannelFd(int fd) {
102 android::base::unique_fd newFd(::dup(fd));
103 if (!newFd.ok()) {
104 ALOGE("Could not duplicate fd %i : %s", fd, strerror(errno));
105 const bool hitFdLimit = errno == EMFILE || errno == ENFILE;
106 // If this process is out of file descriptors, then throwing that might end up exploding
107 // on the other side of a binder call, which isn't really helpful.
108 // Better to just crash here and hope that the FD leak is slow.
109 // Other failures could be client errors, so we still propagate those back to the caller.
110 LOG_ALWAYS_FATAL_IF(hitFdLimit, "Too many open files, could not duplicate input channel");
111 return {};
112 }
113 return newFd;
114}
115
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -0800116void initializeKeyEvent(KeyEvent& event, const InputMessage& msg) {
117 event.initialize(msg.body.key.eventId, msg.body.key.deviceId, msg.body.key.source,
118 msg.body.key.displayId, msg.body.key.hmac, msg.body.key.action,
119 msg.body.key.flags, msg.body.key.keyCode, msg.body.key.scanCode,
120 msg.body.key.metaState, msg.body.key.repeatCount, msg.body.key.downTime,
121 msg.body.key.eventTime);
122}
123
124void initializeFocusEvent(FocusEvent& event, const InputMessage& msg) {
125 event.initialize(msg.body.focus.eventId, msg.body.focus.hasFocus);
126}
127
128void initializeCaptureEvent(CaptureEvent& event, const InputMessage& msg) {
129 event.initialize(msg.body.capture.eventId, msg.body.capture.pointerCaptureEnabled);
130}
131
132void initializeDragEvent(DragEvent& event, const InputMessage& msg) {
133 event.initialize(msg.body.drag.eventId, msg.body.drag.x, msg.body.drag.y,
134 msg.body.drag.isExiting);
135}
136
137void initializeMotionEvent(MotionEvent& event, const InputMessage& msg) {
138 uint32_t pointerCount = msg.body.motion.pointerCount;
139 PointerProperties pointerProperties[pointerCount];
140 PointerCoords pointerCoords[pointerCount];
141 for (uint32_t i = 0; i < pointerCount; i++) {
142 pointerProperties[i] = msg.body.motion.pointers[i].properties;
143 pointerCoords[i] = msg.body.motion.pointers[i].coords;
144 }
145
146 ui::Transform transform;
147 transform.set({msg.body.motion.dsdx, msg.body.motion.dtdx, msg.body.motion.tx,
148 msg.body.motion.dtdy, msg.body.motion.dsdy, msg.body.motion.ty, 0, 0, 1});
149 ui::Transform displayTransform;
150 displayTransform.set({msg.body.motion.dsdxRaw, msg.body.motion.dtdxRaw, msg.body.motion.txRaw,
151 msg.body.motion.dtdyRaw, msg.body.motion.dsdyRaw, msg.body.motion.tyRaw,
152 0, 0, 1});
153 event.initialize(msg.body.motion.eventId, msg.body.motion.deviceId, msg.body.motion.source,
154 msg.body.motion.displayId, msg.body.motion.hmac, msg.body.motion.action,
155 msg.body.motion.actionButton, msg.body.motion.flags, msg.body.motion.edgeFlags,
156 msg.body.motion.metaState, msg.body.motion.buttonState,
157 msg.body.motion.classification, transform, msg.body.motion.xPrecision,
158 msg.body.motion.yPrecision, msg.body.motion.xCursorPosition,
159 msg.body.motion.yCursorPosition, displayTransform, msg.body.motion.downTime,
160 msg.body.motion.eventTime, pointerCount, pointerProperties, pointerCoords);
161}
162
163void addSample(MotionEvent& event, const InputMessage& msg) {
164 uint32_t pointerCount = msg.body.motion.pointerCount;
165 PointerCoords pointerCoords[pointerCount];
166 for (uint32_t i = 0; i < pointerCount; i++) {
167 pointerCoords[i] = msg.body.motion.pointers[i].coords;
168 }
169
170 event.setMetaState(event.getMetaState() | msg.body.motion.metaState);
171 event.addSample(msg.body.motion.eventTime, pointerCoords);
172}
173
174void initializeTouchModeEvent(TouchModeEvent& event, const InputMessage& msg) {
175 event.initialize(msg.body.touchMode.eventId, msg.body.touchMode.isInTouchMode);
176}
177
Jeff Brown5912f952013-07-01 19:10:31 -0700178// Socket buffer size. The default is typically about 128KB, which is much larger than
179// we really need. So we make it smaller. It just needs to be big enough to hold
180// a few dozen large multi-finger motion events in the case where an application gets
181// behind processing touches.
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -0800182static constexpr size_t SOCKET_BUFFER_SIZE = 32 * 1024;
Jeff Brown5912f952013-07-01 19:10:31 -0700183
184// Nanoseconds per milliseconds.
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -0800185static constexpr nsecs_t NANOS_PER_MS = 1000000;
Jeff Brown5912f952013-07-01 19:10:31 -0700186
187// Latency added during resampling. A few milliseconds doesn't hurt much but
188// reduces the impact of mispredicted touch positions.
Siarhei Vishniakou0ced3cc2017-11-21 15:33:17 -0800189const std::chrono::duration RESAMPLE_LATENCY = 5ms;
Jeff Brown5912f952013-07-01 19:10:31 -0700190
191// Minimum time difference between consecutive samples before attempting to resample.
192static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
193
Andrew de los Reyesde18f6c2015-10-01 15:57:25 -0700194// Maximum time difference between consecutive samples before attempting to resample
195// by extrapolation.
196static const nsecs_t RESAMPLE_MAX_DELTA = 20 * NANOS_PER_MS;
197
Jeff Brown5912f952013-07-01 19:10:31 -0700198// Maximum time to predict forward from the last known state, to avoid predicting too
199// far into the future. This time is further bounded by 50% of the last time delta.
200static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
201
Siarhei Vishniakoub5433e92019-02-21 09:27:39 -0600202/**
203 * System property for enabling / disabling touch resampling.
204 * Resampling extrapolates / interpolates the reported touch event coordinates to better
205 * align them to the VSYNC signal, thus resulting in smoother scrolling performance.
206 * Resampling is not needed (and should be disabled) on hardware that already
207 * has touch events triggered by VSYNC.
208 * Set to "1" to enable resampling (default).
209 * Set to "0" to disable resampling.
210 * Resampling is enabled by default.
211 */
212static const char* PROPERTY_RESAMPLING_ENABLED = "ro.input.resampling";
213
Siarhei Vishniakou92c8fd52023-01-29 14:57:43 -0800214/**
215 * Crash if the events that are getting sent to the InputPublisher are inconsistent.
216 * Enable this via "adb shell setprop log.tag.InputTransportVerifyEvents DEBUG"
217 */
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -0800218bool verifyEvents() {
Siarhei Vishniakou96818962023-08-23 10:19:02 -0700219 return input_flags::enable_outbound_event_verification() ||
220 __android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "VerifyEvents", ANDROID_LOG_INFO);
Siarhei Vishniakou92c8fd52023-01-29 14:57:43 -0800221}
222
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -0800223inline float lerp(float a, float b, float alpha) {
Jeff Brown5912f952013-07-01 19:10:31 -0700224 return a + alpha * (b - a);
225}
226
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -0800227inline bool isPointerEvent(int32_t source) {
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800228 return (source & AINPUT_SOURCE_CLASS_POINTER) == AINPUT_SOURCE_CLASS_POINTER;
229}
230
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -0800231bool shouldResampleTool(ToolType toolType) {
Siarhei Vishniakou6d73f832022-07-21 17:27:03 -0700232 return toolType == ToolType::FINGER || toolType == ToolType::UNKNOWN;
233}
234
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -0800235} // namespace
236
237using android::base::Result;
238using android::base::StringPrintf;
239
Jeff Brown5912f952013-07-01 19:10:31 -0700240// --- InputMessage ---
241
242bool InputMessage::isValid(size_t actualSize) const {
Siarhei Vishniakoudbdb6732021-04-26 19:40:26 +0000243 if (size() != actualSize) {
244 ALOGE("Received message of incorrect size %zu (expected %zu)", actualSize, size());
245 return false;
246 }
247
248 switch (header.type) {
249 case Type::KEY:
250 return true;
251 case Type::MOTION: {
252 const bool valid =
253 body.motion.pointerCount > 0 && body.motion.pointerCount <= MAX_POINTERS;
254 if (!valid) {
255 ALOGE("Received invalid MOTION: pointerCount = %" PRIu32, body.motion.pointerCount);
256 }
257 return valid;
258 }
259 case Type::FINISHED:
260 case Type::FOCUS:
261 case Type::CAPTURE:
262 case Type::DRAG:
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700263 case Type::TOUCH_MODE:
Siarhei Vishniakoudbdb6732021-04-26 19:40:26 +0000264 return true;
265 case Type::TIMELINE: {
266 const nsecs_t gpuCompletedTime =
267 body.timeline.graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME];
268 const nsecs_t presentTime =
269 body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME];
270 const bool valid = presentTime > gpuCompletedTime;
271 if (!valid) {
272 ALOGE("Received invalid TIMELINE: gpuCompletedTime = %" PRId64
273 " presentTime = %" PRId64,
274 gpuCompletedTime, presentTime);
275 }
276 return valid;
Jeff Brown5912f952013-07-01 19:10:31 -0700277 }
278 }
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000279 ALOGE("Invalid message type: %s", ftl::enum_string(header.type).c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700280 return false;
281}
282
283size_t InputMessage::size() const {
284 switch (header.type) {
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700285 case Type::KEY:
286 return sizeof(Header) + body.key.size();
287 case Type::MOTION:
288 return sizeof(Header) + body.motion.size();
289 case Type::FINISHED:
290 return sizeof(Header) + body.finished.size();
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800291 case Type::FOCUS:
292 return sizeof(Header) + body.focus.size();
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800293 case Type::CAPTURE:
294 return sizeof(Header) + body.capture.size();
arthurhung7632c332020-12-30 16:58:01 +0800295 case Type::DRAG:
296 return sizeof(Header) + body.drag.size();
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000297 case Type::TIMELINE:
298 return sizeof(Header) + body.timeline.size();
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700299 case Type::TOUCH_MODE:
300 return sizeof(Header) + body.touchMode.size();
Jeff Brown5912f952013-07-01 19:10:31 -0700301 }
302 return sizeof(Header);
303}
304
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800305/**
306 * There could be non-zero bytes in-between InputMessage fields. Force-initialize the entire
307 * memory to zero, then only copy the valid bytes on a per-field basis.
308 */
309void InputMessage::getSanitizedCopy(InputMessage* msg) const {
310 memset(msg, 0, sizeof(*msg));
311
312 // Write the header
313 msg->header.type = header.type;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500314 msg->header.seq = header.seq;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800315
316 // Write the body
317 switch(header.type) {
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700318 case InputMessage::Type::KEY: {
Garfield Tan1c7bc862020-01-28 13:24:04 -0800319 // int32_t eventId
320 msg->body.key.eventId = body.key.eventId;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800321 // nsecs_t eventTime
322 msg->body.key.eventTime = body.key.eventTime;
323 // int32_t deviceId
324 msg->body.key.deviceId = body.key.deviceId;
325 // int32_t source
326 msg->body.key.source = body.key.source;
327 // int32_t displayId
328 msg->body.key.displayId = body.key.displayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600329 // std::array<uint8_t, 32> hmac
330 msg->body.key.hmac = body.key.hmac;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800331 // int32_t action
332 msg->body.key.action = body.key.action;
333 // int32_t flags
334 msg->body.key.flags = body.key.flags;
335 // int32_t keyCode
336 msg->body.key.keyCode = body.key.keyCode;
337 // int32_t scanCode
338 msg->body.key.scanCode = body.key.scanCode;
339 // int32_t metaState
340 msg->body.key.metaState = body.key.metaState;
341 // int32_t repeatCount
342 msg->body.key.repeatCount = body.key.repeatCount;
343 // nsecs_t downTime
344 msg->body.key.downTime = body.key.downTime;
345 break;
346 }
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700347 case InputMessage::Type::MOTION: {
Garfield Tan1c7bc862020-01-28 13:24:04 -0800348 // int32_t eventId
349 msg->body.motion.eventId = body.motion.eventId;
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700350 // uint32_t pointerCount
351 msg->body.motion.pointerCount = body.motion.pointerCount;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800352 // nsecs_t eventTime
353 msg->body.motion.eventTime = body.motion.eventTime;
354 // int32_t deviceId
355 msg->body.motion.deviceId = body.motion.deviceId;
356 // int32_t source
357 msg->body.motion.source = body.motion.source;
358 // int32_t displayId
359 msg->body.motion.displayId = body.motion.displayId;
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600360 // std::array<uint8_t, 32> hmac
361 msg->body.motion.hmac = body.motion.hmac;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800362 // int32_t action
363 msg->body.motion.action = body.motion.action;
364 // int32_t actionButton
365 msg->body.motion.actionButton = body.motion.actionButton;
366 // int32_t flags
367 msg->body.motion.flags = body.motion.flags;
368 // int32_t metaState
369 msg->body.motion.metaState = body.motion.metaState;
370 // int32_t buttonState
371 msg->body.motion.buttonState = body.motion.buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800372 // MotionClassification classification
373 msg->body.motion.classification = body.motion.classification;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800374 // int32_t edgeFlags
375 msg->body.motion.edgeFlags = body.motion.edgeFlags;
376 // nsecs_t downTime
377 msg->body.motion.downTime = body.motion.downTime;
chaviw9eaa22c2020-07-01 16:21:27 -0700378
379 msg->body.motion.dsdx = body.motion.dsdx;
380 msg->body.motion.dtdx = body.motion.dtdx;
381 msg->body.motion.dtdy = body.motion.dtdy;
382 msg->body.motion.dsdy = body.motion.dsdy;
383 msg->body.motion.tx = body.motion.tx;
384 msg->body.motion.ty = body.motion.ty;
385
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800386 // float xPrecision
387 msg->body.motion.xPrecision = body.motion.xPrecision;
388 // float yPrecision
389 msg->body.motion.yPrecision = body.motion.yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700390 // float xCursorPosition
391 msg->body.motion.xCursorPosition = body.motion.xCursorPosition;
392 // float yCursorPosition
393 msg->body.motion.yCursorPosition = body.motion.yCursorPosition;
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700394
395 msg->body.motion.dsdxRaw = body.motion.dsdxRaw;
396 msg->body.motion.dtdxRaw = body.motion.dtdxRaw;
397 msg->body.motion.dtdyRaw = body.motion.dtdyRaw;
398 msg->body.motion.dsdyRaw = body.motion.dsdyRaw;
399 msg->body.motion.txRaw = body.motion.txRaw;
400 msg->body.motion.tyRaw = body.motion.tyRaw;
401
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800402 //struct Pointer pointers[MAX_POINTERS]
403 for (size_t i = 0; i < body.motion.pointerCount; i++) {
404 // PointerProperties properties
405 msg->body.motion.pointers[i].properties.id = body.motion.pointers[i].properties.id;
406 msg->body.motion.pointers[i].properties.toolType =
407 body.motion.pointers[i].properties.toolType,
408 // PointerCoords coords
409 msg->body.motion.pointers[i].coords.bits = body.motion.pointers[i].coords.bits;
410 const uint32_t count = BitSet64::count(body.motion.pointers[i].coords.bits);
411 memcpy(&msg->body.motion.pointers[i].coords.values[0],
412 &body.motion.pointers[i].coords.values[0],
413 count * (sizeof(body.motion.pointers[i].coords.values[0])));
Philip Quinnafb31282022-12-20 18:17:55 -0800414 msg->body.motion.pointers[i].coords.isResampled =
415 body.motion.pointers[i].coords.isResampled;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800416 }
417 break;
418 }
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700419 case InputMessage::Type::FINISHED: {
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800420 msg->body.finished.handled = body.finished.handled;
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000421 msg->body.finished.consumeTime = body.finished.consumeTime;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800422 break;
423 }
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800424 case InputMessage::Type::FOCUS: {
Garfield Tan1c7bc862020-01-28 13:24:04 -0800425 msg->body.focus.eventId = body.focus.eventId;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800426 msg->body.focus.hasFocus = body.focus.hasFocus;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800427 break;
428 }
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800429 case InputMessage::Type::CAPTURE: {
430 msg->body.capture.eventId = body.capture.eventId;
431 msg->body.capture.pointerCaptureEnabled = body.capture.pointerCaptureEnabled;
432 break;
433 }
arthurhung7632c332020-12-30 16:58:01 +0800434 case InputMessage::Type::DRAG: {
435 msg->body.drag.eventId = body.drag.eventId;
436 msg->body.drag.x = body.drag.x;
437 msg->body.drag.y = body.drag.y;
438 msg->body.drag.isExiting = body.drag.isExiting;
439 break;
440 }
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000441 case InputMessage::Type::TIMELINE: {
442 msg->body.timeline.eventId = body.timeline.eventId;
443 msg->body.timeline.graphicsTimeline = body.timeline.graphicsTimeline;
444 break;
445 }
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700446 case InputMessage::Type::TOUCH_MODE: {
447 msg->body.touchMode.eventId = body.touchMode.eventId;
448 msg->body.touchMode.isInTouchMode = body.touchMode.isInTouchMode;
449 }
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800450 }
451}
Jeff Brown5912f952013-07-01 19:10:31 -0700452
453// --- InputChannel ---
454
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500455std::unique_ptr<InputChannel> InputChannel::create(const std::string& name,
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500456 android::base::unique_fd fd, sp<IBinder> token) {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700457 const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
458 if (result != 0) {
459 LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
460 strerror(errno));
461 return nullptr;
462 }
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500463 // using 'new' to access a non-public constructor
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500464 return std::unique_ptr<InputChannel>(new InputChannel(name, std::move(fd), token));
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700465}
466
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800467std::unique_ptr<InputChannel> InputChannel::create(
468 android::os::InputChannelCore&& parceledChannel) {
469 return InputChannel::create(parceledChannel.name, parceledChannel.fd.release(),
470 parceledChannel.token);
471}
472
473InputChannel::InputChannel(const std::string name, android::base::unique_fd fd, sp<IBinder> token) {
474 this->name = std::move(name);
475 this->fd.reset(std::move(fd));
476 this->token = std::move(token);
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000477 ALOGD_IF(DEBUG_CHANNEL_LIFECYCLE, "Input channel constructed: name='%s', fd=%d",
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800478 getName().c_str(), getFd());
Jeff Brown5912f952013-07-01 19:10:31 -0700479}
480
481InputChannel::~InputChannel() {
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000482 ALOGD_IF(DEBUG_CHANNEL_LIFECYCLE, "Input channel destroyed: name='%s', fd=%d",
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800483 getName().c_str(), getFd());
Robert Carr3720ed02018-08-08 16:08:27 -0700484}
485
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800486status_t InputChannel::openInputChannelPair(const std::string& name,
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500487 std::unique_ptr<InputChannel>& outServerChannel,
488 std::unique_ptr<InputChannel>& outClientChannel) {
Jeff Brown5912f952013-07-01 19:10:31 -0700489 int sockets[2];
490 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
491 status_t result = -errno;
Siarhei Vishniakou09b02ac2021-04-14 22:24:04 +0000492 ALOGE("channel '%s' ~ Could not create socket pair. errno=%s(%d)", name.c_str(),
493 strerror(errno), errno);
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500494 outServerChannel.reset();
495 outClientChannel.reset();
Jeff Brown5912f952013-07-01 19:10:31 -0700496 return result;
497 }
498
499 int bufferSize = SOCKET_BUFFER_SIZE;
500 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
501 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
502 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
503 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
504
Siarhei Vishniakou4c155eb2023-06-30 11:47:12 -0700505 sp<IBinder> token = sp<BBinder>::make();
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700506
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700507 std::string serverChannelName = name + " (server)";
508 android::base::unique_fd serverFd(sockets[0]);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700509 outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd), token);
Jeff Brown5912f952013-07-01 19:10:31 -0700510
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700511 std::string clientChannelName = name + " (client)";
512 android::base::unique_fd clientFd(sockets[1]);
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700513 outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd), token);
Jeff Brown5912f952013-07-01 19:10:31 -0700514 return OK;
515}
516
517status_t InputChannel::sendMessage(const InputMessage* msg) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +0000518 ATRACE_NAME_IF(ATRACE_ENABLED(),
519 StringPrintf("sendMessage(inputChannel=%s, seq=0x%" PRIx32 ", type=0x%" PRIx32
520 ")",
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800521 name.c_str(), msg->header.seq, msg->header.type));
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800522 const size_t msgLength = msg->size();
523 InputMessage cleanMsg;
524 msg->getSanitizedCopy(&cleanMsg);
Jeff Brown5912f952013-07-01 19:10:31 -0700525 ssize_t nWrite;
526 do {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800527 nWrite = ::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
Jeff Brown5912f952013-07-01 19:10:31 -0700528 } while (nWrite == -1 && errno == EINTR);
529
530 if (nWrite < 0) {
531 int error = errno;
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000532 ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ error sending message of type %s, %s",
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800533 name.c_str(), ftl::enum_string(msg->header.type).c_str(), strerror(error));
Jeff Brown5912f952013-07-01 19:10:31 -0700534 if (error == EAGAIN || error == EWOULDBLOCK) {
535 return WOULD_BLOCK;
536 }
537 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) {
538 return DEAD_OBJECT;
539 }
540 return -error;
541 }
542
543 if (size_t(nWrite) != msgLength) {
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000544 ALOGD_IF(DEBUG_CHANNEL_MESSAGES,
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800545 "channel '%s' ~ error sending message type %s, send was incomplete", name.c_str(),
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000546 ftl::enum_string(msg->header.type).c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700547 return DEAD_OBJECT;
548 }
549
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800550 ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ sent message of type %s", name.c_str(),
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000551 ftl::enum_string(msg->header.type).c_str());
Zimd8402b62023-06-02 11:56:26 +0100552
Jeff Brown5912f952013-07-01 19:10:31 -0700553 return OK;
554}
555
556status_t InputChannel::receiveMessage(InputMessage* msg) {
557 ssize_t nRead;
558 do {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800559 nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT);
Jeff Brown5912f952013-07-01 19:10:31 -0700560 } while (nRead == -1 && errno == EINTR);
561
562 if (nRead < 0) {
563 int error = errno;
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000564 ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ receive message failed, errno=%d",
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800565 name.c_str(), errno);
Jeff Brown5912f952013-07-01 19:10:31 -0700566 if (error == EAGAIN || error == EWOULDBLOCK) {
567 return WOULD_BLOCK;
568 }
569 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
570 return DEAD_OBJECT;
571 }
572 return -error;
573 }
574
575 if (nRead == 0) { // check for EOF
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000576 ALOGD_IF(DEBUG_CHANNEL_MESSAGES,
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800577 "channel '%s' ~ receive message failed because peer was closed", name.c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700578 return DEAD_OBJECT;
579 }
580
581 if (!msg->isValid(nRead)) {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800582 ALOGE("channel '%s' ~ received invalid message of size %zd", name.c_str(), nRead);
Jeff Brown5912f952013-07-01 19:10:31 -0700583 return BAD_VALUE;
584 }
585
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800586 ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ received message of type %s", name.c_str(),
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000587 ftl::enum_string(msg->header.type).c_str());
Zimd8402b62023-06-02 11:56:26 +0100588 if (ATRACE_ENABLED()) {
Prabir Pradhana37bad12023-08-18 15:55:32 +0000589 // Add an additional trace point to include data about the received message.
Zimd8402b62023-06-02 11:56:26 +0100590 std::string message = StringPrintf("receiveMessage(inputChannel=%s, seq=0x%" PRIx32
591 ", type=0x%" PRIx32 ")",
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800592 name.c_str(), msg->header.seq, msg->header.type);
Zimd8402b62023-06-02 11:56:26 +0100593 ATRACE_NAME(message.c_str());
594 }
Jeff Brown5912f952013-07-01 19:10:31 -0700595 return OK;
596}
597
Egor Paskoa0d32af2023-12-14 17:45:41 +0100598bool InputChannel::probablyHasInput() const {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800599 struct pollfd pfds = {.fd = fd.get(), .events = POLLIN};
Egor Paskoa0d32af2023-12-14 17:45:41 +0100600 if (::poll(&pfds, /*nfds=*/1, /*timeout=*/0) <= 0) {
Egor Pasko5a67a562024-01-16 16:46:45 +0100601 // This can be a false negative because EINTR and ENOMEM are not handled. The latter should
602 // be extremely rare. The EINTR is also unlikely because it happens only when the signal
603 // arrives while the syscall is executed, and the syscall is quick. Hitting EINTR too often
Egor Paskoa0d32af2023-12-14 17:45:41 +0100604 // would be a sign of having too many signals, which is a bigger performance problem. A
Egor Pasko5a67a562024-01-16 16:46:45 +0100605 // common tradition is to repeat the syscall on each EINTR, but it is not necessary here.
Egor Paskoa0d32af2023-12-14 17:45:41 +0100606 // In other words, the missing one liner is replaced by a multiline explanation.
607 return false;
608 }
609 // From poll(2): The bits returned in |revents| can include any of those specified in |events|,
610 // or one of the values POLLERR, POLLHUP, or POLLNVAL.
611 return (pfds.revents & POLLIN) != 0;
612}
613
Egor Pasko5a67a562024-01-16 16:46:45 +0100614void InputChannel::waitForMessage(std::chrono::milliseconds timeout) const {
615 if (timeout < 0ms) {
616 LOG(FATAL) << "Timeout cannot be negative, received " << timeout.count();
617 }
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800618 struct pollfd pfds = {.fd = fd.get(), .events = POLLIN};
Egor Pasko5a67a562024-01-16 16:46:45 +0100619 int ret;
620 std::chrono::time_point<std::chrono::steady_clock> stopTime =
621 std::chrono::steady_clock::now() + timeout;
622 std::chrono::milliseconds remaining = timeout;
623 do {
624 ret = ::poll(&pfds, /*nfds=*/1, /*timeout=*/remaining.count());
625 remaining = std::chrono::duration_cast<std::chrono::milliseconds>(
626 stopTime - std::chrono::steady_clock::now());
627 } while (ret == -1 && errno == EINTR && remaining > 0ms);
628}
629
Siarhei Vishniakoud2588272020-07-10 11:15:40 -0500630std::unique_ptr<InputChannel> InputChannel::dup() const {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800631 base::unique_fd newFd(dupChannelFd(fd.get()));
Chris Ye0783e992020-06-02 21:34:49 -0700632 return InputChannel::create(getName(), std::move(newFd), getConnectionToken());
Jeff Brown5912f952013-07-01 19:10:31 -0700633}
634
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800635void InputChannel::copyTo(android::os::InputChannelCore& outChannel) const {
636 outChannel.name = getName();
637 outChannel.fd.reset(dupChannelFd(fd.get()));
638 outChannel.token = getConnectionToken();
Robert Carr3720ed02018-08-08 16:08:27 -0700639}
640
Siarhei Vishniakou7b9f4f52024-02-02 13:07:16 -0800641void InputChannel::moveChannel(std::unique_ptr<InputChannel> from,
642 android::os::InputChannelCore& outChannel) {
643 outChannel.name = from->getName();
644 outChannel.fd = android::os::ParcelFileDescriptor(std::move(from->fd));
645 outChannel.token = from->getConnectionToken();
646}
647
Siarhei Vishniakou26d3cfb2019-10-15 17:02:32 -0700648sp<IBinder> InputChannel::getConnectionToken() const {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800649 return token;
Garfield Tan15601662020-09-22 15:32:38 -0700650}
651
Jeff Brown5912f952013-07-01 19:10:31 -0700652// --- InputPublisher ---
653
Siarhei Vishniakou92c8fd52023-01-29 14:57:43 -0800654InputPublisher::InputPublisher(const std::shared_ptr<InputChannel>& channel)
Siarhei Vishniakou7b9f4f52024-02-02 13:07:16 -0800655 : mChannel(channel), mInputVerifier(mChannel->getName()) {}
Jeff Brown5912f952013-07-01 19:10:31 -0700656
657InputPublisher::~InputPublisher() {
658}
659
Garfield Tan1c7bc862020-01-28 13:24:04 -0800660status_t InputPublisher::publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId,
661 int32_t source, int32_t displayId,
662 std::array<uint8_t, 32> hmac, int32_t action,
663 int32_t flags, int32_t keyCode, int32_t scanCode,
664 int32_t metaState, int32_t repeatCount, nsecs_t downTime,
665 nsecs_t eventTime) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +0000666 ATRACE_NAME_IF(ATRACE_ENABLED(),
667 StringPrintf("publishKeyEvent(inputChannel=%s, action=%s, keyCode=%s)",
668 mChannel->getName().c_str(), KeyEvent::actionToString(action),
669 KeyEvent::getLabel(keyCode)));
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +0000670 ALOGD_IF(debugTransportPublisher(),
Prabir Pradhan96282b02023-02-24 22:36:17 +0000671 "channel '%s' publisher ~ %s: seq=%u, id=%d, deviceId=%d, source=%s, "
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000672 "action=%s, flags=0x%x, keyCode=%s, scanCode=%d, metaState=0x%x, repeatCount=%d,"
673 "downTime=%" PRId64 ", eventTime=%" PRId64,
Prabir Pradhan96282b02023-02-24 22:36:17 +0000674 mChannel->getName().c_str(), __func__, seq, eventId, deviceId,
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000675 inputEventSourceToString(source).c_str(), KeyEvent::actionToString(action), flags,
676 KeyEvent::getLabel(keyCode), scanCode, metaState, repeatCount, downTime, eventTime);
Jeff Brown5912f952013-07-01 19:10:31 -0700677
678 if (!seq) {
679 ALOGE("Attempted to publish a key event with sequence number 0.");
680 return BAD_VALUE;
681 }
682
683 InputMessage msg;
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700684 msg.header.type = InputMessage::Type::KEY;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500685 msg.header.seq = seq;
Garfield Tan1c7bc862020-01-28 13:24:04 -0800686 msg.body.key.eventId = eventId;
Jeff Brown5912f952013-07-01 19:10:31 -0700687 msg.body.key.deviceId = deviceId;
688 msg.body.key.source = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100689 msg.body.key.displayId = displayId;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -0700690 msg.body.key.hmac = std::move(hmac);
Jeff Brown5912f952013-07-01 19:10:31 -0700691 msg.body.key.action = action;
692 msg.body.key.flags = flags;
693 msg.body.key.keyCode = keyCode;
694 msg.body.key.scanCode = scanCode;
695 msg.body.key.metaState = metaState;
696 msg.body.key.repeatCount = repeatCount;
697 msg.body.key.downTime = downTime;
698 msg.body.key.eventTime = eventTime;
699 return mChannel->sendMessage(&msg);
700}
701
702status_t InputPublisher::publishMotionEvent(
Garfield Tan1c7bc862020-01-28 13:24:04 -0800703 uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source, int32_t displayId,
Siarhei Vishniakou9c858ac2020-01-23 14:20:11 -0600704 std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
705 int32_t edgeFlags, int32_t metaState, int32_t buttonState,
chaviw9eaa22c2020-07-01 16:21:27 -0700706 MotionClassification classification, const ui::Transform& transform, float xPrecision,
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700707 float yPrecision, float xCursorPosition, float yCursorPosition,
708 const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
Evan Rosky09576692021-07-01 12:22:09 -0700709 uint32_t pointerCount, const PointerProperties* pointerProperties,
710 const PointerCoords* pointerCoords) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +0000711 ATRACE_NAME_IF(ATRACE_ENABLED(),
712 StringPrintf("publishMotionEvent(inputChannel=%s, action=%s)",
713 mChannel->getName().c_str(),
714 MotionEvent::actionToString(action).c_str()));
Siarhei Vishniakou92c8fd52023-01-29 14:57:43 -0800715 if (verifyEvents()) {
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -0700716 Result<void> result =
Siarhei Vishniakou2d151ac2023-09-19 13:30:24 -0700717 mInputVerifier.processMovement(deviceId, source, action, pointerCount,
718 pointerProperties, pointerCoords, flags);
Siarhei Vishniakou5c02a712023-05-15 15:45:02 -0700719 if (!result.ok()) {
720 LOG(FATAL) << "Bad stream: " << result.error();
721 }
Siarhei Vishniakou92c8fd52023-01-29 14:57:43 -0800722 }
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +0000723 if (debugTransportPublisher()) {
chaviw9eaa22c2020-07-01 16:21:27 -0700724 std::string transformString;
chaviw85b44202020-07-24 11:46:21 -0700725 transform.dump(transformString, "transform", " ");
Prabir Pradhan96282b02023-02-24 22:36:17 +0000726 ALOGD("channel '%s' publisher ~ %s: seq=%u, id=%d, deviceId=%d, source=%s, "
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -0800727 "displayId=%" PRId32 ", "
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000728 "action=%s, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
chaviw9eaa22c2020-07-01 16:21:27 -0700729 "metaState=0x%x, buttonState=0x%x, classification=%s,"
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -0800730 "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
Siarhei Vishniakouf77f60a2023-10-23 17:26:05 -0700731 "pointerCount=%" PRIu32 "\n%s",
Prabir Pradhan96282b02023-02-24 22:36:17 +0000732 mChannel->getName().c_str(), __func__, seq, eventId, deviceId,
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000733 inputEventSourceToString(source).c_str(), displayId,
734 MotionEvent::actionToString(action).c_str(), actionButton, flags, edgeFlags,
735 metaState, buttonState, motionClassificationToString(classification), xPrecision,
736 yPrecision, downTime, eventTime, pointerCount, transformString.c_str());
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -0800737 }
Jeff Brown5912f952013-07-01 19:10:31 -0700738
739 if (!seq) {
740 ALOGE("Attempted to publish a motion event with sequence number 0.");
741 return BAD_VALUE;
742 }
743
744 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Michael Wright63ff3a82014-06-10 13:03:17 -0700745 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %" PRIu32 ".",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800746 mChannel->getName().c_str(), pointerCount);
Jeff Brown5912f952013-07-01 19:10:31 -0700747 return BAD_VALUE;
748 }
749
750 InputMessage msg;
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700751 msg.header.type = InputMessage::Type::MOTION;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500752 msg.header.seq = seq;
Garfield Tan1c7bc862020-01-28 13:24:04 -0800753 msg.body.motion.eventId = eventId;
Jeff Brown5912f952013-07-01 19:10:31 -0700754 msg.body.motion.deviceId = deviceId;
755 msg.body.motion.source = source;
Tarandeep Singh58641502017-07-31 10:51:54 -0700756 msg.body.motion.displayId = displayId;
Edgar Arriagac6ae4bb2020-04-16 18:46:48 -0700757 msg.body.motion.hmac = std::move(hmac);
Jeff Brown5912f952013-07-01 19:10:31 -0700758 msg.body.motion.action = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100759 msg.body.motion.actionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700760 msg.body.motion.flags = flags;
761 msg.body.motion.edgeFlags = edgeFlags;
762 msg.body.motion.metaState = metaState;
763 msg.body.motion.buttonState = buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800764 msg.body.motion.classification = classification;
chaviw9eaa22c2020-07-01 16:21:27 -0700765 msg.body.motion.dsdx = transform.dsdx();
766 msg.body.motion.dtdx = transform.dtdx();
767 msg.body.motion.dtdy = transform.dtdy();
768 msg.body.motion.dsdy = transform.dsdy();
769 msg.body.motion.tx = transform.tx();
770 msg.body.motion.ty = transform.ty();
Jeff Brown5912f952013-07-01 19:10:31 -0700771 msg.body.motion.xPrecision = xPrecision;
772 msg.body.motion.yPrecision = yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700773 msg.body.motion.xCursorPosition = xCursorPosition;
774 msg.body.motion.yCursorPosition = yCursorPosition;
Prabir Pradhanb9b18502021-08-26 12:30:32 -0700775 msg.body.motion.dsdxRaw = rawTransform.dsdx();
776 msg.body.motion.dtdxRaw = rawTransform.dtdx();
777 msg.body.motion.dtdyRaw = rawTransform.dtdy();
778 msg.body.motion.dsdyRaw = rawTransform.dsdy();
779 msg.body.motion.txRaw = rawTransform.tx();
780 msg.body.motion.tyRaw = rawTransform.ty();
Jeff Brown5912f952013-07-01 19:10:31 -0700781 msg.body.motion.downTime = downTime;
782 msg.body.motion.eventTime = eventTime;
783 msg.body.motion.pointerCount = pointerCount;
Narayan Kamathbc6001b2014-05-02 17:53:33 +0100784 for (uint32_t i = 0; i < pointerCount; i++) {
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -0700785 msg.body.motion.pointers[i].properties = pointerProperties[i];
786 msg.body.motion.pointers[i].coords = pointerCoords[i];
Jeff Brown5912f952013-07-01 19:10:31 -0700787 }
Atif Niyaz3d3fa522019-07-25 11:12:39 -0700788
Jeff Brown5912f952013-07-01 19:10:31 -0700789 return mChannel->sendMessage(&msg);
790}
791
Antonio Kantek3cfec7b2021-11-05 18:26:17 -0700792status_t InputPublisher::publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +0000793 ATRACE_NAME_IF(ATRACE_ENABLED(),
794 StringPrintf("publishFocusEvent(inputChannel=%s, hasFocus=%s)",
795 mChannel->getName().c_str(), toString(hasFocus)));
Prabir Pradhan96282b02023-02-24 22:36:17 +0000796 ALOGD_IF(debugTransportPublisher(), "channel '%s' publisher ~ %s: seq=%u, id=%d, hasFocus=%s",
797 mChannel->getName().c_str(), __func__, seq, eventId, toString(hasFocus));
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800798
799 InputMessage msg;
800 msg.header.type = InputMessage::Type::FOCUS;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500801 msg.header.seq = seq;
Garfield Tan1c7bc862020-01-28 13:24:04 -0800802 msg.body.focus.eventId = eventId;
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000803 msg.body.focus.hasFocus = hasFocus;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800804 return mChannel->sendMessage(&msg);
805}
806
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800807status_t InputPublisher::publishCaptureEvent(uint32_t seq, int32_t eventId,
808 bool pointerCaptureEnabled) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +0000809 ATRACE_NAME_IF(ATRACE_ENABLED(),
810 StringPrintf("publishCaptureEvent(inputChannel=%s, pointerCaptureEnabled=%s)",
811 mChannel->getName().c_str(), toString(pointerCaptureEnabled)));
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +0000812 ALOGD_IF(debugTransportPublisher(),
Prabir Pradhan96282b02023-02-24 22:36:17 +0000813 "channel '%s' publisher ~ %s: seq=%u, id=%d, pointerCaptureEnabled=%s",
814 mChannel->getName().c_str(), __func__, seq, eventId, toString(pointerCaptureEnabled));
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800815
816 InputMessage msg;
817 msg.header.type = InputMessage::Type::CAPTURE;
818 msg.header.seq = seq;
819 msg.body.capture.eventId = eventId;
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +0000820 msg.body.capture.pointerCaptureEnabled = pointerCaptureEnabled;
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -0800821 return mChannel->sendMessage(&msg);
822}
823
arthurhung7632c332020-12-30 16:58:01 +0800824status_t InputPublisher::publishDragEvent(uint32_t seq, int32_t eventId, float x, float y,
825 bool isExiting) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +0000826 ATRACE_NAME_IF(ATRACE_ENABLED(),
827 StringPrintf("publishDragEvent(inputChannel=%s, x=%f, y=%f, isExiting=%s)",
828 mChannel->getName().c_str(), x, y, toString(isExiting)));
Prabir Pradhanb2bd83c2023-02-23 02:34:40 +0000829 ALOGD_IF(debugTransportPublisher(),
Prabir Pradhan96282b02023-02-24 22:36:17 +0000830 "channel '%s' publisher ~ %s: seq=%u, id=%d, x=%f, y=%f, isExiting=%s",
831 mChannel->getName().c_str(), __func__, seq, eventId, x, y, toString(isExiting));
arthurhung7632c332020-12-30 16:58:01 +0800832
833 InputMessage msg;
834 msg.header.type = InputMessage::Type::DRAG;
835 msg.header.seq = seq;
836 msg.body.drag.eventId = eventId;
837 msg.body.drag.isExiting = isExiting;
838 msg.body.drag.x = x;
839 msg.body.drag.y = y;
840 return mChannel->sendMessage(&msg);
841}
842
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700843status_t InputPublisher::publishTouchModeEvent(uint32_t seq, int32_t eventId, bool isInTouchMode) {
Prabir Pradhan2dac8b82023-09-06 01:11:51 +0000844 ATRACE_NAME_IF(ATRACE_ENABLED(),
845 StringPrintf("publishTouchModeEvent(inputChannel=%s, isInTouchMode=%s)",
846 mChannel->getName().c_str(), toString(isInTouchMode)));
Prabir Pradhan96282b02023-02-24 22:36:17 +0000847 ALOGD_IF(debugTransportPublisher(),
848 "channel '%s' publisher ~ %s: seq=%u, id=%d, isInTouchMode=%s",
849 mChannel->getName().c_str(), __func__, seq, eventId, toString(isInTouchMode));
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -0700850
851 InputMessage msg;
852 msg.header.type = InputMessage::Type::TOUCH_MODE;
853 msg.header.seq = seq;
854 msg.body.touchMode.eventId = eventId;
855 msg.body.touchMode.isInTouchMode = isInTouchMode;
856 return mChannel->sendMessage(&msg);
857}
858
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000859android::base::Result<InputPublisher::ConsumerResponse> InputPublisher::receiveConsumerResponse() {
Jeff Brown5912f952013-07-01 19:10:31 -0700860 InputMessage msg;
861 status_t result = mChannel->receiveMessage(&msg);
862 if (result) {
Siarhei Vishniakou69112652023-08-24 08:34:18 -0700863 if (debugTransportPublisher() && result != WOULD_BLOCK) {
864 LOG(INFO) << "channel '" << mChannel->getName() << "' publisher ~ " << __func__ << ": "
865 << strerror(result);
866 }
Siarhei Vishniakoueedd0fc2021-03-12 09:50:36 +0000867 return android::base::Error(result);
Jeff Brown5912f952013-07-01 19:10:31 -0700868 }
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000869 if (msg.header.type == InputMessage::Type::FINISHED) {
Prabir Pradhan96282b02023-02-24 22:36:17 +0000870 ALOGD_IF(debugTransportPublisher(),
871 "channel '%s' publisher ~ %s: finished: seq=%u, handled=%s",
872 mChannel->getName().c_str(), __func__, msg.header.seq,
873 toString(msg.body.finished.handled));
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000874 return Finished{
875 .seq = msg.header.seq,
876 .handled = msg.body.finished.handled,
877 .consumeTime = msg.body.finished.consumeTime,
878 };
Jeff Brown5912f952013-07-01 19:10:31 -0700879 }
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000880
881 if (msg.header.type == InputMessage::Type::TIMELINE) {
Prabir Pradhan96282b02023-02-24 22:36:17 +0000882 ALOGD_IF(debugTransportPublisher(), "channel '%s' publisher ~ %s: timeline: id=%d",
883 mChannel->getName().c_str(), __func__, msg.body.timeline.eventId);
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000884 return Timeline{
885 .inputEventId = msg.body.timeline.eventId,
886 .graphicsTimeline = msg.body.timeline.graphicsTimeline,
887 };
888 }
889
890 ALOGE("channel '%s' publisher ~ Received unexpected %s message from consumer",
Dominik Laskowski75788452021-02-09 18:51:25 -0800891 mChannel->getName().c_str(), ftl::enum_string(msg.header.type).c_str());
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +0000892 return android::base::Error(UNKNOWN_ERROR);
Jeff Brown5912f952013-07-01 19:10:31 -0700893}
894
895// --- InputConsumer ---
896
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500897InputConsumer::InputConsumer(const std::shared_ptr<InputChannel>& channel)
Siarhei Vishniakou0ced3cc2017-11-21 15:33:17 -0800898 : InputConsumer(channel, isTouchResamplingEnabled()) {}
899
900InputConsumer::InputConsumer(const std::shared_ptr<InputChannel>& channel,
901 bool enableTouchResampling)
902 : mResampleTouch(enableTouchResampling), mChannel(channel), mMsgDeferred(false) {}
Jeff Brown5912f952013-07-01 19:10:31 -0700903
904InputConsumer::~InputConsumer() {
905}
906
907bool InputConsumer::isTouchResamplingEnabled() {
Siarhei Vishniakoub5433e92019-02-21 09:27:39 -0600908 return property_get_bool(PROPERTY_RESAMPLING_ENABLED, true);
Jeff Brown5912f952013-07-01 19:10:31 -0700909}
910
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -0800911status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consumeBatches,
912 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000913 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
914 "channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%" PRId64,
915 mChannel->getName().c_str(), toString(consumeBatches), frameTime);
Jeff Brown5912f952013-07-01 19:10:31 -0700916
917 *outSeq = 0;
Yi Kong5bed83b2018-07-17 12:53:47 -0700918 *outEvent = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700919
920 // Fetch the next input message.
921 // Loop until an event can be returned or no additional events are received.
922 while (!*outEvent) {
923 if (mMsgDeferred) {
924 // mMsg contains a valid input message from the previous call to consume
925 // that has not yet been processed.
926 mMsgDeferred = false;
927 } else {
928 // Receive a fresh message.
929 status_t result = mChannel->receiveMessage(&mMsg);
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000930 if (result == OK) {
Siarhei Vishniakou0ced3cc2017-11-21 15:33:17 -0800931 const auto [_, inserted] =
932 mConsumeTimes.emplace(mMsg.header.seq, systemTime(SYSTEM_TIME_MONOTONIC));
933 LOG_ALWAYS_FATAL_IF(!inserted, "Already have a consume time for seq=%" PRIu32,
934 mMsg.header.seq);
Siarhei Vishniakouca42e0d2024-01-12 12:10:32 -0800935
936 // Trace the event processing timeline - event was just read from the socket
937 ATRACE_ASYNC_BEGIN("InputConsumer processing", /*cookie=*/mMsg.header.seq);
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -1000938 }
Jeff Brown5912f952013-07-01 19:10:31 -0700939 if (result) {
940 // Consume the next batched event unless batches are being held for later.
941 if (consumeBatches || result != WOULD_BLOCK) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800942 result = consumeBatch(factory, frameTime, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700943 if (*outEvent) {
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000944 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
945 "channel '%s' consumer ~ consumed batch event, seq=%u",
946 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700947 break;
948 }
949 }
950 return result;
951 }
952 }
953
954 switch (mMsg.header.type) {
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700955 case InputMessage::Type::KEY: {
956 KeyEvent* keyEvent = factory->createKeyEvent();
957 if (!keyEvent) return NO_MEMORY;
Jeff Brown5912f952013-07-01 19:10:31 -0700958
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -0800959 initializeKeyEvent(*keyEvent, mMsg);
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500960 *outSeq = mMsg.header.seq;
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700961 *outEvent = keyEvent;
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000962 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
963 "channel '%s' consumer ~ consumed key event, seq=%u",
964 mChannel->getName().c_str(), *outSeq);
965 break;
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700966 }
Jeff Brown5912f952013-07-01 19:10:31 -0700967
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700968 case InputMessage::Type::MOTION: {
969 ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
970 if (batchIndex >= 0) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500971 Batch& batch = mBatches[batchIndex];
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700972 if (canAddSample(batch, &mMsg)) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500973 batch.samples.push_back(mMsg);
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000974 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
975 "channel '%s' consumer ~ appended to batch event",
976 mChannel->getName().c_str());
977 break;
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700978 } else if (isPointerEvent(mMsg.body.motion.source) &&
979 mMsg.body.motion.action == AMOTION_EVENT_ACTION_CANCEL) {
980 // No need to process events that we are going to cancel anyways
981 const size_t count = batch.samples.size();
982 for (size_t i = 0; i < count; i++) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500983 const InputMessage& msg = batch.samples[i];
984 sendFinishedSignal(msg.header.seq, false);
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700985 }
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500986 batch.samples.erase(batch.samples.begin(), batch.samples.begin() + count);
987 mBatches.erase(mBatches.begin() + batchIndex);
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700988 } else {
989 // We cannot append to the batch in progress, so we need to consume
990 // the previous batch right now and defer the new message until later.
991 mMsgDeferred = true;
992 status_t result = consumeSamples(factory, batch, batch.samples.size(),
993 outSeq, outEvent);
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -0500994 mBatches.erase(mBatches.begin() + batchIndex);
Siarhei Vishniakou52402772019-10-22 09:32:30 -0700995 if (result) {
996 return result;
997 }
Prabir Pradhan60dd97a2023-02-23 02:23:02 +0000998 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
999 "channel '%s' consumer ~ consumed batch event and "
1000 "deferred current event, seq=%u",
1001 mChannel->getName().c_str(), *outSeq);
1002 break;
Siarhei Vishniakou52402772019-10-22 09:32:30 -07001003 }
Jeff Brown5912f952013-07-01 19:10:31 -07001004 }
Jeff Brown5912f952013-07-01 19:10:31 -07001005
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08001006 // Start a new batch if needed.
1007 if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE ||
1008 mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001009 Batch batch;
1010 batch.samples.push_back(mMsg);
1011 mBatches.push_back(batch);
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001012 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
1013 "channel '%s' consumer ~ started batch event",
1014 mChannel->getName().c_str());
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08001015 break;
1016 }
Jeff Brown5912f952013-07-01 19:10:31 -07001017
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08001018 MotionEvent* motionEvent = factory->createMotionEvent();
1019 if (!motionEvent) return NO_MEMORY;
Jeff Brown5912f952013-07-01 19:10:31 -07001020
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08001021 updateTouchState(mMsg);
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -08001022 initializeMotionEvent(*motionEvent, mMsg);
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001023 *outSeq = mMsg.header.seq;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08001024 *outEvent = motionEvent;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001025
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001026 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
1027 "channel '%s' consumer ~ consumed motion event, seq=%u",
1028 mChannel->getName().c_str(), *outSeq);
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08001029 break;
Siarhei Vishniakou52402772019-10-22 09:32:30 -07001030 }
Jeff Brown5912f952013-07-01 19:10:31 -07001031
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +00001032 case InputMessage::Type::FINISHED:
1033 case InputMessage::Type::TIMELINE: {
Siarhei Vishniakou7766c032021-03-02 20:32:20 +00001034 LOG_ALWAYS_FATAL("Consumed a %s message, which should never be seen by "
1035 "InputConsumer!",
Dominik Laskowski75788452021-02-09 18:51:25 -08001036 ftl::enum_string(mMsg.header.type).c_str());
Siarhei Vishniakou3b37f9a2019-11-23 13:42:41 -08001037 break;
1038 }
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08001039
1040 case InputMessage::Type::FOCUS: {
1041 FocusEvent* focusEvent = factory->createFocusEvent();
1042 if (!focusEvent) return NO_MEMORY;
1043
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -08001044 initializeFocusEvent(*focusEvent, mMsg);
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001045 *outSeq = mMsg.header.seq;
Siarhei Vishniakou7feb2ea2019-11-25 15:11:23 -08001046 *outEvent = focusEvent;
1047 break;
1048 }
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -08001049
1050 case InputMessage::Type::CAPTURE: {
1051 CaptureEvent* captureEvent = factory->createCaptureEvent();
1052 if (!captureEvent) return NO_MEMORY;
1053
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -08001054 initializeCaptureEvent(*captureEvent, mMsg);
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -08001055 *outSeq = mMsg.header.seq;
1056 *outEvent = captureEvent;
1057 break;
1058 }
arthurhung7632c332020-12-30 16:58:01 +08001059
1060 case InputMessage::Type::DRAG: {
1061 DragEvent* dragEvent = factory->createDragEvent();
1062 if (!dragEvent) return NO_MEMORY;
1063
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -08001064 initializeDragEvent(*dragEvent, mMsg);
arthurhung7632c332020-12-30 16:58:01 +08001065 *outSeq = mMsg.header.seq;
1066 *outEvent = dragEvent;
1067 break;
1068 }
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -07001069
1070 case InputMessage::Type::TOUCH_MODE: {
1071 TouchModeEvent* touchModeEvent = factory->createTouchModeEvent();
1072 if (!touchModeEvent) return NO_MEMORY;
1073
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -08001074 initializeTouchModeEvent(*touchModeEvent, mMsg);
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -07001075 *outSeq = mMsg.header.seq;
1076 *outEvent = touchModeEvent;
1077 break;
1078 }
Jeff Brown5912f952013-07-01 19:10:31 -07001079 }
1080 }
1081 return OK;
1082}
1083
1084status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001085 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -07001086 status_t result;
Dan Austin1faef802015-09-22 14:28:07 -07001087 for (size_t i = mBatches.size(); i > 0; ) {
1088 i--;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001089 Batch& batch = mBatches[i];
Michael Wright32232172013-10-21 12:05:22 -07001090 if (frameTime < 0) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001091 result = consumeSamples(factory, batch, batch.samples.size(), outSeq, outEvent);
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001092 mBatches.erase(mBatches.begin() + i);
Jeff Brown5912f952013-07-01 19:10:31 -07001093 return result;
1094 }
1095
Michael Wright32232172013-10-21 12:05:22 -07001096 nsecs_t sampleTime = frameTime;
1097 if (mResampleTouch) {
Siarhei Vishniakou0ced3cc2017-11-21 15:33:17 -08001098 sampleTime -= std::chrono::nanoseconds(RESAMPLE_LATENCY).count();
Michael Wright32232172013-10-21 12:05:22 -07001099 }
Jeff Brown5912f952013-07-01 19:10:31 -07001100 ssize_t split = findSampleNoLaterThan(batch, sampleTime);
1101 if (split < 0) {
1102 continue;
1103 }
1104
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001105 result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -07001106 const InputMessage* next;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001107 if (batch.samples.empty()) {
1108 mBatches.erase(mBatches.begin() + i);
Yi Kong5bed83b2018-07-17 12:53:47 -07001109 next = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -07001110 } else {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001111 next = &batch.samples[0];
Jeff Brown5912f952013-07-01 19:10:31 -07001112 }
Michael Wright32232172013-10-21 12:05:22 -07001113 if (!result && mResampleTouch) {
Jeff Brown5912f952013-07-01 19:10:31 -07001114 resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
1115 }
1116 return result;
1117 }
1118
1119 return WOULD_BLOCK;
1120}
1121
1122status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -08001123 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -07001124 MotionEvent* motionEvent = factory->createMotionEvent();
1125 if (! motionEvent) return NO_MEMORY;
1126
1127 uint32_t chain = 0;
1128 for (size_t i = 0; i < count; i++) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001129 InputMessage& msg = batch.samples[i];
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001130 updateTouchState(msg);
Jeff Brown5912f952013-07-01 19:10:31 -07001131 if (i) {
1132 SeqChain seqChain;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001133 seqChain.seq = msg.header.seq;
Jeff Brown5912f952013-07-01 19:10:31 -07001134 seqChain.chain = chain;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001135 mSeqChains.push_back(seqChain);
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -08001136 addSample(*motionEvent, msg);
Jeff Brown5912f952013-07-01 19:10:31 -07001137 } else {
Siarhei Vishniakou9dbf6372024-03-06 16:08:01 -08001138 initializeMotionEvent(*motionEvent, msg);
Jeff Brown5912f952013-07-01 19:10:31 -07001139 }
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001140 chain = msg.header.seq;
Jeff Brown5912f952013-07-01 19:10:31 -07001141 }
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001142 batch.samples.erase(batch.samples.begin(), batch.samples.begin() + count);
Jeff Brown5912f952013-07-01 19:10:31 -07001143
1144 *outSeq = chain;
1145 *outEvent = motionEvent;
1146 return OK;
1147}
1148
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001149void InputConsumer::updateTouchState(InputMessage& msg) {
Siarhei Vishniakou128eab12019-05-23 10:25:59 +08001150 if (!mResampleTouch || !isPointerEvent(msg.body.motion.source)) {
Jeff Brown5912f952013-07-01 19:10:31 -07001151 return;
1152 }
1153
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001154 int32_t deviceId = msg.body.motion.deviceId;
1155 int32_t source = msg.body.motion.source;
Jeff Brown5912f952013-07-01 19:10:31 -07001156
1157 // Update the touch state history to incorporate the new input message.
1158 // If the message is in the past relative to the most recently produced resampled
1159 // touch, then use the resampled time and coordinates instead.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001160 switch (msg.body.motion.action & AMOTION_EVENT_ACTION_MASK) {
Jeff Brown5912f952013-07-01 19:10:31 -07001161 case AMOTION_EVENT_ACTION_DOWN: {
1162 ssize_t index = findTouchState(deviceId, source);
1163 if (index < 0) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001164 mTouchStates.push_back({});
Jeff Brown5912f952013-07-01 19:10:31 -07001165 index = mTouchStates.size() - 1;
1166 }
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001167 TouchState& touchState = mTouchStates[index];
Jeff Brown5912f952013-07-01 19:10:31 -07001168 touchState.initialize(deviceId, source);
1169 touchState.addHistory(msg);
1170 break;
1171 }
1172
1173 case AMOTION_EVENT_ACTION_MOVE: {
1174 ssize_t index = findTouchState(deviceId, source);
1175 if (index >= 0) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001176 TouchState& touchState = mTouchStates[index];
Jeff Brown5912f952013-07-01 19:10:31 -07001177 touchState.addHistory(msg);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001178 rewriteMessage(touchState, msg);
Jeff Brown5912f952013-07-01 19:10:31 -07001179 }
1180 break;
1181 }
1182
1183 case AMOTION_EVENT_ACTION_POINTER_DOWN: {
1184 ssize_t index = findTouchState(deviceId, source);
1185 if (index >= 0) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001186 TouchState& touchState = mTouchStates[index];
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001187 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -07001188 rewriteMessage(touchState, msg);
1189 }
1190 break;
1191 }
1192
1193 case AMOTION_EVENT_ACTION_POINTER_UP: {
1194 ssize_t index = findTouchState(deviceId, source);
1195 if (index >= 0) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001196 TouchState& touchState = mTouchStates[index];
Jeff Brown5912f952013-07-01 19:10:31 -07001197 rewriteMessage(touchState, msg);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001198 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -07001199 }
1200 break;
1201 }
1202
1203 case AMOTION_EVENT_ACTION_SCROLL: {
1204 ssize_t index = findTouchState(deviceId, source);
1205 if (index >= 0) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001206 TouchState& touchState = mTouchStates[index];
Jeff Brown5912f952013-07-01 19:10:31 -07001207 rewriteMessage(touchState, msg);
1208 }
1209 break;
1210 }
1211
1212 case AMOTION_EVENT_ACTION_UP:
1213 case AMOTION_EVENT_ACTION_CANCEL: {
1214 ssize_t index = findTouchState(deviceId, source);
1215 if (index >= 0) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001216 TouchState& touchState = mTouchStates[index];
Jeff Brown5912f952013-07-01 19:10:31 -07001217 rewriteMessage(touchState, msg);
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001218 mTouchStates.erase(mTouchStates.begin() + index);
Jeff Brown5912f952013-07-01 19:10:31 -07001219 }
1220 break;
1221 }
1222 }
1223}
1224
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001225/**
1226 * Replace the coordinates in msg with the coordinates in lastResample, if necessary.
1227 *
1228 * If lastResample is no longer valid for a specific pointer (i.e. the lastResample time
1229 * is in the past relative to msg and the past two events do not contain identical coordinates),
1230 * then invalidate the lastResample data for that pointer.
1231 * If the two past events have identical coordinates, then lastResample data for that pointer will
1232 * remain valid, and will be used to replace these coordinates. Thus, if a certain coordinate x0 is
1233 * resampled to the new value x1, then x1 will always be used to replace x0 until some new value
1234 * not equal to x0 is received.
1235 */
1236void InputConsumer::rewriteMessage(TouchState& state, InputMessage& msg) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001237 nsecs_t eventTime = msg.body.motion.eventTime;
1238 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
1239 uint32_t id = msg.body.motion.pointers[i].properties.id;
Jeff Brown5912f952013-07-01 19:10:31 -07001240 if (state.lastResample.idBits.hasBit(id)) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001241 if (eventTime < state.lastResample.eventTime ||
1242 state.recentCoordinatesAreIdentical(id)) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001243 PointerCoords& msgCoords = msg.body.motion.pointers[i].coords;
1244 const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
Harry Cutts6c658cc2023-08-02 14:40:40 +00001245 ALOGD_IF(debugResampling(), "[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001246 resampleCoords.getX(), resampleCoords.getY(), msgCoords.getX(),
1247 msgCoords.getY());
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001248 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
1249 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
Philip Quinnafb31282022-12-20 18:17:55 -08001250 msgCoords.isResampled = true;
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001251 } else {
1252 state.lastResample.idBits.clearBit(id);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001253 }
Jeff Brown5912f952013-07-01 19:10:31 -07001254 }
1255 }
1256}
1257
1258void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
1259 const InputMessage* next) {
1260 if (!mResampleTouch
Siarhei Vishniakou128eab12019-05-23 10:25:59 +08001261 || !(isPointerEvent(event->getSource()))
Jeff Brown5912f952013-07-01 19:10:31 -07001262 || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
1263 return;
1264 }
1265
1266 ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
1267 if (index < 0) {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001268 ALOGD_IF(debugResampling(), "Not resampled, no touch state for device.");
Jeff Brown5912f952013-07-01 19:10:31 -07001269 return;
1270 }
1271
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001272 TouchState& touchState = mTouchStates[index];
Jeff Brown5912f952013-07-01 19:10:31 -07001273 if (touchState.historySize < 1) {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001274 ALOGD_IF(debugResampling(), "Not resampled, no history for device.");
Jeff Brown5912f952013-07-01 19:10:31 -07001275 return;
1276 }
1277
1278 // Ensure that the current sample has all of the pointers that need to be reported.
1279 const History* current = touchState.getHistory(0);
1280 size_t pointerCount = event->getPointerCount();
1281 for (size_t i = 0; i < pointerCount; i++) {
1282 uint32_t id = event->getPointerId(i);
1283 if (!current->idBits.hasBit(id)) {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001284 ALOGD_IF(debugResampling(), "Not resampled, missing id %d", id);
Jeff Brown5912f952013-07-01 19:10:31 -07001285 return;
1286 }
1287 }
1288
1289 // Find the data to use for resampling.
1290 const History* other;
1291 History future;
1292 float alpha;
1293 if (next) {
1294 // Interpolate between current sample and future sample.
1295 // So current->eventTime <= sampleTime <= future.eventTime.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +01001296 future.initializeFrom(*next);
Jeff Brown5912f952013-07-01 19:10:31 -07001297 other = &future;
1298 nsecs_t delta = future.eventTime - current->eventTime;
1299 if (delta < RESAMPLE_MIN_DELTA) {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001300 ALOGD_IF(debugResampling(), "Not resampled, delta time is too small: %" PRId64 " ns.",
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001301 delta);
Jeff Brown5912f952013-07-01 19:10:31 -07001302 return;
1303 }
1304 alpha = float(sampleTime - current->eventTime) / delta;
1305 } else if (touchState.historySize >= 2) {
1306 // Extrapolate future sample using current sample and past sample.
1307 // So other->eventTime <= current->eventTime <= sampleTime.
1308 other = touchState.getHistory(1);
1309 nsecs_t delta = current->eventTime - other->eventTime;
1310 if (delta < RESAMPLE_MIN_DELTA) {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001311 ALOGD_IF(debugResampling(), "Not resampled, delta time is too small: %" PRId64 " ns.",
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001312 delta);
Andrew de los Reyesde18f6c2015-10-01 15:57:25 -07001313 return;
1314 } else if (delta > RESAMPLE_MAX_DELTA) {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001315 ALOGD_IF(debugResampling(), "Not resampled, delta time is too large: %" PRId64 " ns.",
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001316 delta);
Jeff Brown5912f952013-07-01 19:10:31 -07001317 return;
1318 }
Siarhei Vishniakou6c1e6222024-03-07 13:39:24 -08001319 nsecs_t maxPredict = current->eventTime + std::min(delta / 2, RESAMPLE_MAX_PREDICTION);
Jeff Brown5912f952013-07-01 19:10:31 -07001320 if (sampleTime > maxPredict) {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001321 ALOGD_IF(debugResampling(),
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001322 "Sample time is too far in the future, adjusting prediction "
1323 "from %" PRId64 " to %" PRId64 " ns.",
1324 sampleTime - current->eventTime, maxPredict - current->eventTime);
Jeff Brown5912f952013-07-01 19:10:31 -07001325 sampleTime = maxPredict;
1326 }
1327 alpha = float(current->eventTime - sampleTime) / delta;
1328 } else {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001329 ALOGD_IF(debugResampling(), "Not resampled, insufficient data.");
Jeff Brown5912f952013-07-01 19:10:31 -07001330 return;
1331 }
1332
Siarhei Vishniakou0ced3cc2017-11-21 15:33:17 -08001333 if (current->eventTime == sampleTime) {
1334 // Prevents having 2 events with identical times and coordinates.
1335 return;
1336 }
1337
Jeff Brown5912f952013-07-01 19:10:31 -07001338 // Resample touch coordinates.
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001339 History oldLastResample;
1340 oldLastResample.initializeFrom(touchState.lastResample);
Jeff Brown5912f952013-07-01 19:10:31 -07001341 touchState.lastResample.eventTime = sampleTime;
1342 touchState.lastResample.idBits.clear();
1343 for (size_t i = 0; i < pointerCount; i++) {
1344 uint32_t id = event->getPointerId(i);
1345 touchState.lastResample.idToIndex[id] = i;
1346 touchState.lastResample.idBits.markBit(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001347 if (oldLastResample.hasPointerId(id) && touchState.recentCoordinatesAreIdentical(id)) {
1348 // We maintain the previously resampled value for this pointer (stored in
1349 // oldLastResample) when the coordinates for this pointer haven't changed since then.
1350 // This way we don't introduce artificial jitter when pointers haven't actually moved.
Philip Quinnafb31282022-12-20 18:17:55 -08001351 // The isResampled flag isn't cleared as the values don't reflect what the device is
1352 // actually reporting.
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001353
1354 // We know here that the coordinates for the pointer haven't changed because we
1355 // would've cleared the resampled bit in rewriteMessage if they had. We can't modify
1356 // lastResample in place becasue the mapping from pointer ID to index may have changed.
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -07001357 touchState.lastResample.pointers[i] = oldLastResample.getPointerById(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001358 continue;
1359 }
1360
Jeff Brown5912f952013-07-01 19:10:31 -07001361 PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
1362 const PointerCoords& currentCoords = current->getPointerById(id);
Siarhei Vishniakou73e6d372023-07-06 18:07:21 -07001363 resampledCoords = currentCoords;
Philip Quinn4e955a22023-09-26 12:09:40 -07001364 resampledCoords.isResampled = true;
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001365 if (other->idBits.hasBit(id) && shouldResampleTool(event->getToolType(i))) {
Jeff Brown5912f952013-07-01 19:10:31 -07001366 const PointerCoords& otherCoords = other->getPointerById(id);
Jeff Brown5912f952013-07-01 19:10:31 -07001367 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001368 lerp(currentCoords.getX(), otherCoords.getX(), alpha));
Jeff Brown5912f952013-07-01 19:10:31 -07001369 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001370 lerp(currentCoords.getY(), otherCoords.getY(), alpha));
Harry Cutts6c658cc2023-08-02 14:40:40 +00001371 ALOGD_IF(debugResampling(),
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001372 "[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
1373 "other (%0.3f, %0.3f), alpha %0.3f",
1374 id, resampledCoords.getX(), resampledCoords.getY(), currentCoords.getX(),
1375 currentCoords.getY(), otherCoords.getX(), otherCoords.getY(), alpha);
Jeff Brown5912f952013-07-01 19:10:31 -07001376 } else {
Harry Cutts6c658cc2023-08-02 14:40:40 +00001377 ALOGD_IF(debugResampling(), "[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)", id,
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001378 resampledCoords.getX(), resampledCoords.getY(), currentCoords.getX(),
1379 currentCoords.getY());
Jeff Brown5912f952013-07-01 19:10:31 -07001380 }
1381 }
1382
1383 event->addSample(sampleTime, touchState.lastResample.pointers);
1384}
1385
Jeff Brown5912f952013-07-01 19:10:31 -07001386status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001387 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
1388 "channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
1389 mChannel->getName().c_str(), seq, toString(handled));
Jeff Brown5912f952013-07-01 19:10:31 -07001390
1391 if (!seq) {
1392 ALOGE("Attempted to send a finished signal with sequence number 0.");
1393 return BAD_VALUE;
1394 }
1395
1396 // Send finished signals for the batch sequence chain first.
1397 size_t seqChainCount = mSeqChains.size();
1398 if (seqChainCount) {
1399 uint32_t currentSeq = seq;
1400 uint32_t chainSeqs[seqChainCount];
1401 size_t chainIndex = 0;
Dan Austin1faef802015-09-22 14:28:07 -07001402 for (size_t i = seqChainCount; i > 0; ) {
1403 i--;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001404 const SeqChain& seqChain = mSeqChains[i];
Jeff Brown5912f952013-07-01 19:10:31 -07001405 if (seqChain.seq == currentSeq) {
1406 currentSeq = seqChain.chain;
1407 chainSeqs[chainIndex++] = currentSeq;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001408 mSeqChains.erase(mSeqChains.begin() + i);
Jeff Brown5912f952013-07-01 19:10:31 -07001409 }
1410 }
1411 status_t status = OK;
Dan Austin1faef802015-09-22 14:28:07 -07001412 while (!status && chainIndex > 0) {
1413 chainIndex--;
Jeff Brown5912f952013-07-01 19:10:31 -07001414 status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
1415 }
1416 if (status) {
1417 // An error occurred so at least one signal was not sent, reconstruct the chain.
gaoshang9090d4f2017-05-17 14:36:46 +08001418 for (;;) {
Jeff Brown5912f952013-07-01 19:10:31 -07001419 SeqChain seqChain;
1420 seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
1421 seqChain.chain = chainSeqs[chainIndex];
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001422 mSeqChains.push_back(seqChain);
gaoshang9090d4f2017-05-17 14:36:46 +08001423 if (!chainIndex) break;
1424 chainIndex--;
1425 }
Jeff Brown5912f952013-07-01 19:10:31 -07001426 return status;
1427 }
1428 }
1429
1430 // Send finished signal for the last message in the batch.
1431 return sendUnchainedFinishedSignal(seq, handled);
1432}
1433
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +00001434status_t InputConsumer::sendTimeline(int32_t inputEventId,
1435 std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline) {
Prabir Pradhan60dd97a2023-02-23 02:23:02 +00001436 ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
1437 "channel '%s' consumer ~ sendTimeline: inputEventId=%" PRId32
1438 ", gpuCompletedTime=%" PRId64 ", presentTime=%" PRId64,
1439 mChannel->getName().c_str(), inputEventId,
1440 graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME],
1441 graphicsTimeline[GraphicsTimeline::PRESENT_TIME]);
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +00001442
1443 InputMessage msg;
1444 msg.header.type = InputMessage::Type::TIMELINE;
1445 msg.header.seq = 0;
1446 msg.body.timeline.eventId = inputEventId;
1447 msg.body.timeline.graphicsTimeline = std::move(graphicsTimeline);
1448 return mChannel->sendMessage(&msg);
1449}
1450
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10001451nsecs_t InputConsumer::getConsumeTime(uint32_t seq) const {
1452 auto it = mConsumeTimes.find(seq);
1453 // Consume time will be missing if either 'finishInputEvent' is called twice, or if it was
1454 // called for the wrong (synthetic?) input event. Either way, it is a bug that should be fixed.
1455 LOG_ALWAYS_FATAL_IF(it == mConsumeTimes.end(), "Could not find consume time for seq=%" PRIu32,
1456 seq);
1457 return it->second;
1458}
1459
1460void InputConsumer::popConsumeTime(uint32_t seq) {
1461 mConsumeTimes.erase(seq);
1462}
1463
Jeff Brown5912f952013-07-01 19:10:31 -07001464status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
1465 InputMessage msg;
Siarhei Vishniakou52402772019-10-22 09:32:30 -07001466 msg.header.type = InputMessage::Type::FINISHED;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001467 msg.header.seq = seq;
Siarhei Vishniakou38b7f7f2021-03-05 01:57:08 +00001468 msg.body.finished.handled = handled;
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10001469 msg.body.finished.consumeTime = getConsumeTime(seq);
1470 status_t result = mChannel->sendMessage(&msg);
1471 if (result == OK) {
1472 // Remove the consume time if the socket write succeeded. We will not need to ack this
1473 // message anymore. If the socket write did not succeed, we will try again and will still
1474 // need consume time.
1475 popConsumeTime(seq);
Siarhei Vishniakouca42e0d2024-01-12 12:10:32 -08001476
1477 // Trace the event processing timeline - event was just finished
1478 ATRACE_ASYNC_END("InputConsumer processing", /*cookie=*/seq);
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10001479 }
1480 return result;
Jeff Brown5912f952013-07-01 19:10:31 -07001481}
1482
Jeff Brown5912f952013-07-01 19:10:31 -07001483bool InputConsumer::hasPendingBatch() const {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001484 return !mBatches.empty();
Jeff Brown5912f952013-07-01 19:10:31 -07001485}
1486
Arthur Hungc7812be2020-02-27 22:40:27 +08001487int32_t InputConsumer::getPendingBatchSource() const {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001488 if (mBatches.empty()) {
Arthur Hungc7812be2020-02-27 22:40:27 +08001489 return AINPUT_SOURCE_CLASS_NONE;
1490 }
1491
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001492 const Batch& batch = mBatches[0];
1493 const InputMessage& head = batch.samples[0];
Arthur Hungc7812be2020-02-27 22:40:27 +08001494 return head.body.motion.source;
1495}
1496
Egor Paskoa0d32af2023-12-14 17:45:41 +01001497bool InputConsumer::probablyHasInput() const {
1498 return hasPendingBatch() || mChannel->probablyHasInput();
1499}
1500
Jeff Brown5912f952013-07-01 19:10:31 -07001501ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
1502 for (size_t i = 0; i < mBatches.size(); i++) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001503 const Batch& batch = mBatches[i];
1504 const InputMessage& head = batch.samples[0];
Jeff Brown5912f952013-07-01 19:10:31 -07001505 if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
1506 return i;
1507 }
1508 }
1509 return -1;
1510}
1511
1512ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
1513 for (size_t i = 0; i < mTouchStates.size(); i++) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001514 const TouchState& touchState = mTouchStates[i];
Jeff Brown5912f952013-07-01 19:10:31 -07001515 if (touchState.deviceId == deviceId && touchState.source == source) {
1516 return i;
1517 }
1518 }
1519 return -1;
1520}
1521
Jeff Brown5912f952013-07-01 19:10:31 -07001522bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001523 const InputMessage& head = batch.samples[0];
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001524 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001525 if (head.body.motion.pointerCount != pointerCount
1526 || head.body.motion.action != msg->body.motion.action) {
1527 return false;
1528 }
1529 for (size_t i = 0; i < pointerCount; i++) {
1530 if (head.body.motion.pointers[i].properties
1531 != msg->body.motion.pointers[i].properties) {
1532 return false;
1533 }
1534 }
1535 return true;
1536}
1537
1538ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
1539 size_t numSamples = batch.samples.size();
1540 size_t index = 0;
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001541 while (index < numSamples && batch.samples[index].body.motion.eventTime <= time) {
Jeff Brown5912f952013-07-01 19:10:31 -07001542 index += 1;
1543 }
1544 return ssize_t(index) - 1;
1545}
1546
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001547std::string InputConsumer::dump() const {
1548 std::string out;
1549 out = out + "mResampleTouch = " + toString(mResampleTouch) + "\n";
1550 out = out + "mChannel = " + mChannel->getName() + "\n";
1551 out = out + "mMsgDeferred: " + toString(mMsgDeferred) + "\n";
1552 if (mMsgDeferred) {
Dominik Laskowski75788452021-02-09 18:51:25 -08001553 out = out + "mMsg : " + ftl::enum_string(mMsg.header.type) + "\n";
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001554 }
1555 out += "Batches:\n";
1556 for (const Batch& batch : mBatches) {
1557 out += " Batch:\n";
1558 for (const InputMessage& msg : batch.samples) {
1559 out += android::base::StringPrintf(" Message %" PRIu32 ": %s ", msg.header.seq,
Dominik Laskowski75788452021-02-09 18:51:25 -08001560 ftl::enum_string(msg.header.type).c_str());
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001561 switch (msg.header.type) {
1562 case InputMessage::Type::KEY: {
1563 out += android::base::StringPrintf("action=%s keycode=%" PRId32,
1564 KeyEvent::actionToString(
1565 msg.body.key.action),
1566 msg.body.key.keyCode);
1567 break;
1568 }
1569 case InputMessage::Type::MOTION: {
1570 out = out + "action=" + MotionEvent::actionToString(msg.body.motion.action);
1571 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
1572 const float x = msg.body.motion.pointers[i].coords.getX();
1573 const float y = msg.body.motion.pointers[i].coords.getY();
1574 out += android::base::StringPrintf("\n Pointer %" PRIu32
1575 " : x=%.1f y=%.1f",
1576 i, x, y);
1577 }
1578 break;
1579 }
1580 case InputMessage::Type::FINISHED: {
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10001581 out += android::base::StringPrintf("handled=%s, consumeTime=%" PRId64,
1582 toString(msg.body.finished.handled),
1583 msg.body.finished.consumeTime);
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001584 break;
1585 }
1586 case InputMessage::Type::FOCUS: {
Antonio Kantek3cfec7b2021-11-05 18:26:17 -07001587 out += android::base::StringPrintf("hasFocus=%s",
1588 toString(msg.body.focus.hasFocus));
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001589 break;
1590 }
Prabir Pradhan3f37b7b2020-11-10 16:50:18 -08001591 case InputMessage::Type::CAPTURE: {
1592 out += android::base::StringPrintf("hasCapture=%s",
1593 toString(msg.body.capture
1594 .pointerCaptureEnabled));
1595 break;
1596 }
arthurhung7632c332020-12-30 16:58:01 +08001597 case InputMessage::Type::DRAG: {
1598 out += android::base::StringPrintf("x=%.1f y=%.1f, isExiting=%s",
1599 msg.body.drag.x, msg.body.drag.y,
1600 toString(msg.body.drag.isExiting));
1601 break;
1602 }
Siarhei Vishniakouf94ae022021-02-04 01:23:17 +00001603 case InputMessage::Type::TIMELINE: {
1604 const nsecs_t gpuCompletedTime =
1605 msg.body.timeline
1606 .graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME];
1607 const nsecs_t presentTime =
1608 msg.body.timeline.graphicsTimeline[GraphicsTimeline::PRESENT_TIME];
1609 out += android::base::StringPrintf("inputEventId=%" PRId32
1610 ", gpuCompletedTime=%" PRId64
1611 ", presentTime=%" PRId64,
1612 msg.body.timeline.eventId, gpuCompletedTime,
1613 presentTime);
1614 break;
1615 }
Antonio Kantek7cdf8ef2021-07-13 18:04:53 -07001616 case InputMessage::Type::TOUCH_MODE: {
1617 out += android::base::StringPrintf("isInTouchMode=%s",
1618 toString(msg.body.touchMode.isInTouchMode));
1619 break;
1620 }
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001621 }
1622 out += "\n";
1623 }
1624 }
1625 if (mBatches.empty()) {
1626 out += " <empty>\n";
1627 }
1628 out += "mSeqChains:\n";
1629 for (const SeqChain& chain : mSeqChains) {
1630 out += android::base::StringPrintf(" chain: seq = %" PRIu32 " chain=%" PRIu32, chain.seq,
1631 chain.chain);
1632 }
1633 if (mSeqChains.empty()) {
1634 out += " <empty>\n";
1635 }
Siarhei Vishniakou3531ae72021-02-02 12:12:27 -10001636 out += "mConsumeTimes:\n";
1637 for (const auto& [seq, consumeTime] : mConsumeTimes) {
1638 out += android::base::StringPrintf(" seq = %" PRIu32 " consumeTime = %" PRId64, seq,
1639 consumeTime);
1640 }
1641 if (mConsumeTimes.empty()) {
1642 out += " <empty>\n";
1643 }
Siarhei Vishniakoua64c1592020-06-22 12:02:29 -05001644 return out;
1645}
1646
Jeff Brown5912f952013-07-01 19:10:31 -07001647} // namespace android