blob: 2ff301e2705285a8155dd63e131280c3a0b9ba90 [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"
7
8//#define LOG_NDEBUG 0
9
10// Log debug messages about channel messages (send message, receive message)
11#define DEBUG_CHANNEL_MESSAGES 0
12
13// Log debug messages whenever InputChannel objects are created/destroyed
14#define DEBUG_CHANNEL_LIFECYCLE 0
15
16// Log debug messages about transport actions
17#define DEBUG_TRANSPORT_ACTIONS 0
18
19// Log debug messages about touch event resampling
20#define DEBUG_RESAMPLING 0
21
Jeff Brown5912f952013-07-01 19:10:31 -070022#include <errno.h>
23#include <fcntl.h>
Michael Wrightd0a4a622014-06-09 19:03:32 -070024#include <inttypes.h>
Jeff Brown5912f952013-07-01 19:10:31 -070025#include <math.h>
Jeff Brown5912f952013-07-01 19:10:31 -070026#include <sys/socket.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070027#include <sys/types.h>
Jeff Brown5912f952013-07-01 19:10:31 -070028#include <unistd.h>
29
Michael Wright3dd60e22019-03-27 22:06:44 +000030#include <android-base/stringprintf.h>
31#include <binder/Parcel.h>
Jeff Brown5912f952013-07-01 19:10:31 -070032#include <cutils/properties.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070033#include <log/log.h>
Michael Wright3dd60e22019-03-27 22:06:44 +000034#include <utils/Trace.h>
Mark Salyzyn7823e122016-09-29 08:08:05 -070035
Jeff Brown5912f952013-07-01 19:10:31 -070036#include <input/InputTransport.h>
Atif Niyaz3d3fa522019-07-25 11:12:39 -070037#include <statslog.h>
Jeff Brown5912f952013-07-01 19:10:31 -070038
Michael Wright3dd60e22019-03-27 22:06:44 +000039using android::base::StringPrintf;
40
Jeff Brown5912f952013-07-01 19:10:31 -070041namespace android {
42
43// Socket buffer size. The default is typically about 128KB, which is much larger than
44// we really need. So we make it smaller. It just needs to be big enough to hold
45// a few dozen large multi-finger motion events in the case where an application gets
46// behind processing touches.
47static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
48
49// Nanoseconds per milliseconds.
50static const nsecs_t NANOS_PER_MS = 1000000;
51
52// Latency added during resampling. A few milliseconds doesn't hurt much but
53// reduces the impact of mispredicted touch positions.
54static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
55
56// Minimum time difference between consecutive samples before attempting to resample.
57static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
58
Andrew de los Reyesde18f6c2015-10-01 15:57:25 -070059// Maximum time difference between consecutive samples before attempting to resample
60// by extrapolation.
61static const nsecs_t RESAMPLE_MAX_DELTA = 20 * NANOS_PER_MS;
62
Jeff Brown5912f952013-07-01 19:10:31 -070063// Maximum time to predict forward from the last known state, to avoid predicting too
64// far into the future. This time is further bounded by 50% of the last time delta.
65static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
66
Siarhei Vishniakoub5433e92019-02-21 09:27:39 -060067/**
68 * System property for enabling / disabling touch resampling.
69 * Resampling extrapolates / interpolates the reported touch event coordinates to better
70 * align them to the VSYNC signal, thus resulting in smoother scrolling performance.
71 * Resampling is not needed (and should be disabled) on hardware that already
72 * has touch events triggered by VSYNC.
73 * Set to "1" to enable resampling (default).
74 * Set to "0" to disable resampling.
75 * Resampling is enabled by default.
76 */
77static const char* PROPERTY_RESAMPLING_ENABLED = "ro.input.resampling";
78
Jeff Brown5912f952013-07-01 19:10:31 -070079template<typename T>
80inline static T min(const T& a, const T& b) {
81 return a < b ? a : b;
82}
83
84inline static float lerp(float a, float b, float alpha) {
85 return a + alpha * (b - a);
86}
87
Siarhei Vishniakou128eab12019-05-23 10:25:59 +080088inline static bool isPointerEvent(int32_t source) {
89 return (source & AINPUT_SOURCE_CLASS_POINTER) == AINPUT_SOURCE_CLASS_POINTER;
90}
91
Jeff Brown5912f952013-07-01 19:10:31 -070092// --- InputMessage ---
93
94bool InputMessage::isValid(size_t actualSize) const {
95 if (size() == actualSize) {
96 switch (header.type) {
97 case TYPE_KEY:
98 return true;
99 case TYPE_MOTION:
100 return body.motion.pointerCount > 0
101 && body.motion.pointerCount <= MAX_POINTERS;
102 case TYPE_FINISHED:
103 return true;
104 }
105 }
106 return false;
107}
108
109size_t InputMessage::size() const {
110 switch (header.type) {
111 case TYPE_KEY:
112 return sizeof(Header) + body.key.size();
113 case TYPE_MOTION:
114 return sizeof(Header) + body.motion.size();
115 case TYPE_FINISHED:
116 return sizeof(Header) + body.finished.size();
117 }
118 return sizeof(Header);
119}
120
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800121/**
122 * There could be non-zero bytes in-between InputMessage fields. Force-initialize the entire
123 * memory to zero, then only copy the valid bytes on a per-field basis.
124 */
125void InputMessage::getSanitizedCopy(InputMessage* msg) const {
126 memset(msg, 0, sizeof(*msg));
127
128 // Write the header
129 msg->header.type = header.type;
130
131 // Write the body
132 switch(header.type) {
133 case InputMessage::TYPE_KEY: {
134 // uint32_t seq
135 msg->body.key.seq = body.key.seq;
136 // nsecs_t eventTime
137 msg->body.key.eventTime = body.key.eventTime;
138 // int32_t deviceId
139 msg->body.key.deviceId = body.key.deviceId;
140 // int32_t source
141 msg->body.key.source = body.key.source;
142 // int32_t displayId
143 msg->body.key.displayId = body.key.displayId;
144 // int32_t action
145 msg->body.key.action = body.key.action;
146 // int32_t flags
147 msg->body.key.flags = body.key.flags;
148 // int32_t keyCode
149 msg->body.key.keyCode = body.key.keyCode;
150 // int32_t scanCode
151 msg->body.key.scanCode = body.key.scanCode;
152 // int32_t metaState
153 msg->body.key.metaState = body.key.metaState;
154 // int32_t repeatCount
155 msg->body.key.repeatCount = body.key.repeatCount;
156 // nsecs_t downTime
157 msg->body.key.downTime = body.key.downTime;
158 break;
159 }
160 case InputMessage::TYPE_MOTION: {
161 // uint32_t seq
162 msg->body.motion.seq = body.motion.seq;
163 // nsecs_t eventTime
164 msg->body.motion.eventTime = body.motion.eventTime;
165 // int32_t deviceId
166 msg->body.motion.deviceId = body.motion.deviceId;
167 // int32_t source
168 msg->body.motion.source = body.motion.source;
169 // int32_t displayId
170 msg->body.motion.displayId = body.motion.displayId;
171 // int32_t action
172 msg->body.motion.action = body.motion.action;
173 // int32_t actionButton
174 msg->body.motion.actionButton = body.motion.actionButton;
175 // int32_t flags
176 msg->body.motion.flags = body.motion.flags;
177 // int32_t metaState
178 msg->body.motion.metaState = body.motion.metaState;
179 // int32_t buttonState
180 msg->body.motion.buttonState = body.motion.buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800181 // MotionClassification classification
182 msg->body.motion.classification = body.motion.classification;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800183 // int32_t edgeFlags
184 msg->body.motion.edgeFlags = body.motion.edgeFlags;
185 // nsecs_t downTime
186 msg->body.motion.downTime = body.motion.downTime;
187 // float xOffset
188 msg->body.motion.xOffset = body.motion.xOffset;
189 // float yOffset
190 msg->body.motion.yOffset = body.motion.yOffset;
191 // float xPrecision
192 msg->body.motion.xPrecision = body.motion.xPrecision;
193 // float yPrecision
194 msg->body.motion.yPrecision = body.motion.yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700195 // float xCursorPosition
196 msg->body.motion.xCursorPosition = body.motion.xCursorPosition;
197 // float yCursorPosition
198 msg->body.motion.yCursorPosition = body.motion.yCursorPosition;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800199 // uint32_t pointerCount
200 msg->body.motion.pointerCount = body.motion.pointerCount;
201 //struct Pointer pointers[MAX_POINTERS]
202 for (size_t i = 0; i < body.motion.pointerCount; i++) {
203 // PointerProperties properties
204 msg->body.motion.pointers[i].properties.id = body.motion.pointers[i].properties.id;
205 msg->body.motion.pointers[i].properties.toolType =
206 body.motion.pointers[i].properties.toolType,
207 // PointerCoords coords
208 msg->body.motion.pointers[i].coords.bits = body.motion.pointers[i].coords.bits;
209 const uint32_t count = BitSet64::count(body.motion.pointers[i].coords.bits);
210 memcpy(&msg->body.motion.pointers[i].coords.values[0],
211 &body.motion.pointers[i].coords.values[0],
212 count * (sizeof(body.motion.pointers[i].coords.values[0])));
213 }
214 break;
215 }
216 case InputMessage::TYPE_FINISHED: {
217 msg->body.finished.seq = body.finished.seq;
218 msg->body.finished.handled = body.finished.handled;
219 break;
220 }
221 default: {
222 LOG_FATAL("Unexpected message type %i", header.type);
223 break;
224 }
225 }
226}
Jeff Brown5912f952013-07-01 19:10:31 -0700227
228// --- InputChannel ---
229
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800230InputChannel::InputChannel(const std::string& name, int fd) :
Robert Carr3720ed02018-08-08 16:08:27 -0700231 mName(name) {
Jeff Brown5912f952013-07-01 19:10:31 -0700232#if DEBUG_CHANNEL_LIFECYCLE
233 ALOGD("Input channel constructed: name='%s', fd=%d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800234 mName.c_str(), fd);
Jeff Brown5912f952013-07-01 19:10:31 -0700235#endif
236
Robert Carr3720ed02018-08-08 16:08:27 -0700237 setFd(fd);
Jeff Brown5912f952013-07-01 19:10:31 -0700238}
239
240InputChannel::~InputChannel() {
241#if DEBUG_CHANNEL_LIFECYCLE
242 ALOGD("Input channel destroyed: name='%s', fd=%d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800243 mName.c_str(), mFd);
Jeff Brown5912f952013-07-01 19:10:31 -0700244#endif
245
246 ::close(mFd);
247}
248
Robert Carr3720ed02018-08-08 16:08:27 -0700249void InputChannel::setFd(int fd) {
250 if (mFd > 0) {
251 ::close(mFd);
252 }
253 mFd = fd;
254 if (mFd > 0) {
255 int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
256 LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
257 "non-blocking. errno=%d", mName.c_str(), errno);
258 }
259}
260
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800261status_t InputChannel::openInputChannelPair(const std::string& name,
Jeff Brown5912f952013-07-01 19:10:31 -0700262 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
263 int sockets[2];
264 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
265 status_t result = -errno;
266 ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800267 name.c_str(), errno);
Jeff Brown5912f952013-07-01 19:10:31 -0700268 outServerChannel.clear();
269 outClientChannel.clear();
270 return result;
271 }
272
273 int bufferSize = SOCKET_BUFFER_SIZE;
274 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
275 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
276 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
277 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
278
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800279 std::string serverChannelName = name;
280 serverChannelName += " (server)";
Jeff Brown5912f952013-07-01 19:10:31 -0700281 outServerChannel = new InputChannel(serverChannelName, sockets[0]);
282
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800283 std::string clientChannelName = name;
284 clientChannelName += " (client)";
Jeff Brown5912f952013-07-01 19:10:31 -0700285 outClientChannel = new InputChannel(clientChannelName, sockets[1]);
286 return OK;
287}
288
289status_t InputChannel::sendMessage(const InputMessage* msg) {
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800290 const size_t msgLength = msg->size();
291 InputMessage cleanMsg;
292 msg->getSanitizedCopy(&cleanMsg);
Jeff Brown5912f952013-07-01 19:10:31 -0700293 ssize_t nWrite;
294 do {
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800295 nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
Jeff Brown5912f952013-07-01 19:10:31 -0700296 } while (nWrite == -1 && errno == EINTR);
297
298 if (nWrite < 0) {
299 int error = errno;
300#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800301 ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.c_str(),
Jeff Brown5912f952013-07-01 19:10:31 -0700302 msg->header.type, error);
303#endif
304 if (error == EAGAIN || error == EWOULDBLOCK) {
305 return WOULD_BLOCK;
306 }
307 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) {
308 return DEAD_OBJECT;
309 }
310 return -error;
311 }
312
313 if (size_t(nWrite) != msgLength) {
314#if DEBUG_CHANNEL_MESSAGES
315 ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800316 mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700317#endif
318 return DEAD_OBJECT;
319 }
320
321#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800322 ALOGD("channel '%s' ~ sent message of type %d", mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700323#endif
324 return OK;
325}
326
327status_t InputChannel::receiveMessage(InputMessage* msg) {
328 ssize_t nRead;
329 do {
330 nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
331 } while (nRead == -1 && errno == EINTR);
332
333 if (nRead < 0) {
334 int error = errno;
335#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800336 ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.c_str(), errno);
Jeff Brown5912f952013-07-01 19:10:31 -0700337#endif
338 if (error == EAGAIN || error == EWOULDBLOCK) {
339 return WOULD_BLOCK;
340 }
341 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
342 return DEAD_OBJECT;
343 }
344 return -error;
345 }
346
347 if (nRead == 0) { // check for EOF
348#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800349 ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700350#endif
351 return DEAD_OBJECT;
352 }
353
354 if (!msg->isValid(nRead)) {
355#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800356 ALOGD("channel '%s' ~ received invalid message", mName.c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700357#endif
358 return BAD_VALUE;
359 }
360
361#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800362 ALOGD("channel '%s' ~ received message of type %d", mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700363#endif
364 return OK;
365}
366
367sp<InputChannel> InputChannel::dup() const {
368 int fd = ::dup(getFd());
Yi Kong5bed83b2018-07-17 12:53:47 -0700369 return fd >= 0 ? new InputChannel(getName(), fd) : nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700370}
371
372
Robert Carr3720ed02018-08-08 16:08:27 -0700373status_t InputChannel::write(Parcel& out) const {
374 status_t s = out.writeString8(String8(getName().c_str()));
375
376 if (s != OK) {
377 return s;
378 }
Robert Carr803535b2018-08-02 16:38:15 -0700379 s = out.writeStrongBinder(mToken);
380 if (s != OK) {
381 return s;
382 }
Robert Carr3720ed02018-08-08 16:08:27 -0700383
384 s = out.writeDupFileDescriptor(getFd());
385
386 return s;
387}
388
389status_t InputChannel::read(const Parcel& from) {
390 mName = from.readString8();
Robert Carr803535b2018-08-02 16:38:15 -0700391 mToken = from.readStrongBinder();
Robert Carr3720ed02018-08-08 16:08:27 -0700392
393 int rawFd = from.readFileDescriptor();
394 setFd(::dup(rawFd));
395
396 if (mFd < 0) {
397 return BAD_VALUE;
398 }
399
400 return OK;
401}
402
Robert Carr803535b2018-08-02 16:38:15 -0700403sp<IBinder> InputChannel::getToken() const {
404 return mToken;
405}
406
407void InputChannel::setToken(const sp<IBinder>& token) {
408 if (mToken != nullptr) {
409 ALOGE("Assigning InputChannel (%s) a second handle?", mName.c_str());
410 }
411 mToken = token;
412}
413
Jeff Brown5912f952013-07-01 19:10:31 -0700414// --- InputPublisher ---
415
416InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
417 mChannel(channel) {
418}
419
420InputPublisher::~InputPublisher() {
421}
422
423status_t InputPublisher::publishKeyEvent(
424 uint32_t seq,
425 int32_t deviceId,
426 int32_t source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100427 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -0700428 int32_t action,
429 int32_t flags,
430 int32_t keyCode,
431 int32_t scanCode,
432 int32_t metaState,
433 int32_t repeatCount,
434 nsecs_t downTime,
435 nsecs_t eventTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000436 if (ATRACE_ENABLED()) {
437 std::string message = StringPrintf("publishKeyEvent(inputChannel=%s, keyCode=%" PRId32 ")",
438 mChannel->getName().c_str(), keyCode);
439 ATRACE_NAME(message.c_str());
440 }
Jeff Brown5912f952013-07-01 19:10:31 -0700441#if DEBUG_TRANSPORT_ACTIONS
442 ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
443 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700444 "downTime=%" PRId64 ", eventTime=%" PRId64,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800445 mChannel->getName().c_str(), seq,
Jeff Brown5912f952013-07-01 19:10:31 -0700446 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
447 downTime, eventTime);
448#endif
449
450 if (!seq) {
451 ALOGE("Attempted to publish a key event with sequence number 0.");
452 return BAD_VALUE;
453 }
454
455 InputMessage msg;
456 msg.header.type = InputMessage::TYPE_KEY;
457 msg.body.key.seq = seq;
458 msg.body.key.deviceId = deviceId;
459 msg.body.key.source = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100460 msg.body.key.displayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700461 msg.body.key.action = action;
462 msg.body.key.flags = flags;
463 msg.body.key.keyCode = keyCode;
464 msg.body.key.scanCode = scanCode;
465 msg.body.key.metaState = metaState;
466 msg.body.key.repeatCount = repeatCount;
467 msg.body.key.downTime = downTime;
468 msg.body.key.eventTime = eventTime;
469 return mChannel->sendMessage(&msg);
470}
471
472status_t InputPublisher::publishMotionEvent(
Garfield Tan00f511d2019-06-12 16:55:40 -0700473 uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
474 int32_t actionButton, int32_t flags, int32_t edgeFlags, int32_t metaState,
475 int32_t buttonState, MotionClassification classification, float xOffset, float yOffset,
476 float xPrecision, float yPrecision, float xCursorPosition, float yCursorPosition,
477 nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
478 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000479 if (ATRACE_ENABLED()) {
480 std::string message = StringPrintf(
481 "publishMotionEvent(inputChannel=%s, action=%" PRId32 ")",
482 mChannel->getName().c_str(), action);
483 ATRACE_NAME(message.c_str());
484 }
Jeff Brown5912f952013-07-01 19:10:31 -0700485#if DEBUG_TRANSPORT_ACTIONS
486 ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800487 "displayId=%" PRId32 ", "
Michael Wright7b159c92015-05-14 14:48:03 +0100488 "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800489 "metaState=0x%x, buttonState=0x%x, classification=%s, xOffset=%f, yOffset=%f, "
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700490 "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
Michael Wright63ff3a82014-06-10 13:03:17 -0700491 "pointerCount=%" PRIu32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800492 mChannel->getName().c_str(), seq,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800493 deviceId, source, displayId, action, actionButton, flags, edgeFlags, metaState,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800494 buttonState, motionClassificationToString(classification),
495 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
Jeff Brown5912f952013-07-01 19:10:31 -0700496#endif
497
498 if (!seq) {
499 ALOGE("Attempted to publish a motion event with sequence number 0.");
500 return BAD_VALUE;
501 }
502
503 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Michael Wright63ff3a82014-06-10 13:03:17 -0700504 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %" PRIu32 ".",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800505 mChannel->getName().c_str(), pointerCount);
Jeff Brown5912f952013-07-01 19:10:31 -0700506 return BAD_VALUE;
507 }
508
509 InputMessage msg;
510 msg.header.type = InputMessage::TYPE_MOTION;
511 msg.body.motion.seq = seq;
512 msg.body.motion.deviceId = deviceId;
513 msg.body.motion.source = source;
Tarandeep Singh58641502017-07-31 10:51:54 -0700514 msg.body.motion.displayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700515 msg.body.motion.action = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100516 msg.body.motion.actionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700517 msg.body.motion.flags = flags;
518 msg.body.motion.edgeFlags = edgeFlags;
519 msg.body.motion.metaState = metaState;
520 msg.body.motion.buttonState = buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800521 msg.body.motion.classification = classification;
Jeff Brown5912f952013-07-01 19:10:31 -0700522 msg.body.motion.xOffset = xOffset;
523 msg.body.motion.yOffset = yOffset;
524 msg.body.motion.xPrecision = xPrecision;
525 msg.body.motion.yPrecision = yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700526 msg.body.motion.xCursorPosition = xCursorPosition;
527 msg.body.motion.yCursorPosition = yCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700528 msg.body.motion.downTime = downTime;
529 msg.body.motion.eventTime = eventTime;
530 msg.body.motion.pointerCount = pointerCount;
Narayan Kamathbc6001b2014-05-02 17:53:33 +0100531 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -0700532 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
533 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
534 }
Atif Niyaz3d3fa522019-07-25 11:12:39 -0700535
536 if (source == AINPUT_SOURCE_TOUCHSCREEN) {
537 reportTouchEventForStatistics(eventTime);
538 }
Jeff Brown5912f952013-07-01 19:10:31 -0700539 return mChannel->sendMessage(&msg);
540}
541
542status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
543#if DEBUG_TRANSPORT_ACTIONS
544 ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800545 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700546#endif
547
548 InputMessage msg;
549 status_t result = mChannel->receiveMessage(&msg);
550 if (result) {
551 *outSeq = 0;
552 *outHandled = false;
553 return result;
554 }
555 if (msg.header.type != InputMessage::TYPE_FINISHED) {
556 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800557 mChannel->getName().c_str(), msg.header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700558 return UNKNOWN_ERROR;
559 }
560 *outSeq = msg.body.finished.seq;
561 *outHandled = msg.body.finished.handled;
562 return OK;
563}
564
Atif Niyaz3d3fa522019-07-25 11:12:39 -0700565void InputPublisher::reportTouchEventForStatistics(nsecs_t evdevTime) {
566 if (mTouchStatistics.shouldReport()) {
567 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
568 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
569 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
570 mTouchStatistics.reset();
571 }
572 nsecs_t latency = nanoseconds_to_microseconds(systemTime(CLOCK_MONOTONIC) - evdevTime);
573 mTouchStatistics.addValue(latency);
574}
575
Jeff Brown5912f952013-07-01 19:10:31 -0700576// --- InputConsumer ---
577
578InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
579 mResampleTouch(isTouchResamplingEnabled()),
580 mChannel(channel), mMsgDeferred(false) {
581}
582
583InputConsumer::~InputConsumer() {
584}
585
586bool InputConsumer::isTouchResamplingEnabled() {
Siarhei Vishniakoub5433e92019-02-21 09:27:39 -0600587 return property_get_bool(PROPERTY_RESAMPLING_ENABLED, true);
Jeff Brown5912f952013-07-01 19:10:31 -0700588}
589
590status_t InputConsumer::consume(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800591 bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700592#if DEBUG_TRANSPORT_ACTIONS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700593 ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%" PRId64,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800594 mChannel->getName().c_str(), consumeBatches ? "true" : "false", frameTime);
Jeff Brown5912f952013-07-01 19:10:31 -0700595#endif
596
597 *outSeq = 0;
Yi Kong5bed83b2018-07-17 12:53:47 -0700598 *outEvent = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700599
600 // Fetch the next input message.
601 // Loop until an event can be returned or no additional events are received.
602 while (!*outEvent) {
603 if (mMsgDeferred) {
604 // mMsg contains a valid input message from the previous call to consume
605 // that has not yet been processed.
606 mMsgDeferred = false;
607 } else {
608 // Receive a fresh message.
609 status_t result = mChannel->receiveMessage(&mMsg);
610 if (result) {
611 // Consume the next batched event unless batches are being held for later.
612 if (consumeBatches || result != WOULD_BLOCK) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800613 result = consumeBatch(factory, frameTime, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700614 if (*outEvent) {
615#if DEBUG_TRANSPORT_ACTIONS
616 ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800617 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700618#endif
619 break;
620 }
621 }
622 return result;
623 }
624 }
625
626 switch (mMsg.header.type) {
627 case InputMessage::TYPE_KEY: {
628 KeyEvent* keyEvent = factory->createKeyEvent();
629 if (!keyEvent) return NO_MEMORY;
630
631 initializeKeyEvent(keyEvent, &mMsg);
632 *outSeq = mMsg.body.key.seq;
633 *outEvent = keyEvent;
634#if DEBUG_TRANSPORT_ACTIONS
635 ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800636 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700637#endif
638 break;
639 }
640
gaoshange3e11a72017-08-08 16:11:31 +0800641 case InputMessage::TYPE_MOTION: {
Jeff Brown5912f952013-07-01 19:10:31 -0700642 ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
643 if (batchIndex >= 0) {
644 Batch& batch = mBatches.editItemAt(batchIndex);
645 if (canAddSample(batch, &mMsg)) {
646 batch.samples.push(mMsg);
647#if DEBUG_TRANSPORT_ACTIONS
648 ALOGD("channel '%s' consumer ~ appended to batch event",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800649 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700650#endif
651 break;
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800652 } else if (isPointerEvent(mMsg.body.motion.source) &&
653 mMsg.body.motion.action == AMOTION_EVENT_ACTION_CANCEL) {
654 // No need to process events that we are going to cancel anyways
655 const size_t count = batch.samples.size();
656 for (size_t i = 0; i < count; i++) {
657 const InputMessage& msg = batch.samples.itemAt(i);
658 sendFinishedSignal(msg.body.motion.seq, false);
659 }
660 batch.samples.removeItemsAt(0, count);
661 mBatches.removeAt(batchIndex);
Jeff Brown5912f952013-07-01 19:10:31 -0700662 } else {
663 // We cannot append to the batch in progress, so we need to consume
664 // the previous batch right now and defer the new message until later.
665 mMsgDeferred = true;
666 status_t result = consumeSamples(factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800667 batch, batch.samples.size(), outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700668 mBatches.removeAt(batchIndex);
669 if (result) {
670 return result;
671 }
672#if DEBUG_TRANSPORT_ACTIONS
673 ALOGD("channel '%s' consumer ~ consumed batch event and "
674 "deferred current event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800675 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700676#endif
677 break;
678 }
679 }
680
681 // Start a new batch if needed.
682 if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
683 || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
684 mBatches.push();
685 Batch& batch = mBatches.editTop();
686 batch.samples.push(mMsg);
687#if DEBUG_TRANSPORT_ACTIONS
688 ALOGD("channel '%s' consumer ~ started batch event",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800689 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700690#endif
691 break;
692 }
693
694 MotionEvent* motionEvent = factory->createMotionEvent();
695 if (! motionEvent) return NO_MEMORY;
696
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100697 updateTouchState(mMsg);
Jeff Brown5912f952013-07-01 19:10:31 -0700698 initializeMotionEvent(motionEvent, &mMsg);
699 *outSeq = mMsg.body.motion.seq;
700 *outEvent = motionEvent;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800701
Jeff Brown5912f952013-07-01 19:10:31 -0700702#if DEBUG_TRANSPORT_ACTIONS
703 ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800704 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700705#endif
706 break;
707 }
708
709 default:
710 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800711 mChannel->getName().c_str(), mMsg.header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700712 return UNKNOWN_ERROR;
713 }
714 }
715 return OK;
716}
717
718status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800719 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700720 status_t result;
Dan Austin1faef802015-09-22 14:28:07 -0700721 for (size_t i = mBatches.size(); i > 0; ) {
722 i--;
Jeff Brown5912f952013-07-01 19:10:31 -0700723 Batch& batch = mBatches.editItemAt(i);
Michael Wright32232172013-10-21 12:05:22 -0700724 if (frameTime < 0) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800725 result = consumeSamples(factory, batch, batch.samples.size(), outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700726 mBatches.removeAt(i);
727 return result;
728 }
729
Michael Wright32232172013-10-21 12:05:22 -0700730 nsecs_t sampleTime = frameTime;
731 if (mResampleTouch) {
732 sampleTime -= RESAMPLE_LATENCY;
733 }
Jeff Brown5912f952013-07-01 19:10:31 -0700734 ssize_t split = findSampleNoLaterThan(batch, sampleTime);
735 if (split < 0) {
736 continue;
737 }
738
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800739 result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700740 const InputMessage* next;
741 if (batch.samples.isEmpty()) {
742 mBatches.removeAt(i);
Yi Kong5bed83b2018-07-17 12:53:47 -0700743 next = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700744 } else {
745 next = &batch.samples.itemAt(0);
746 }
Michael Wright32232172013-10-21 12:05:22 -0700747 if (!result && mResampleTouch) {
Jeff Brown5912f952013-07-01 19:10:31 -0700748 resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
749 }
750 return result;
751 }
752
753 return WOULD_BLOCK;
754}
755
756status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800757 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700758 MotionEvent* motionEvent = factory->createMotionEvent();
759 if (! motionEvent) return NO_MEMORY;
760
761 uint32_t chain = 0;
762 for (size_t i = 0; i < count; i++) {
763 InputMessage& msg = batch.samples.editItemAt(i);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100764 updateTouchState(msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700765 if (i) {
766 SeqChain seqChain;
767 seqChain.seq = msg.body.motion.seq;
768 seqChain.chain = chain;
769 mSeqChains.push(seqChain);
770 addSample(motionEvent, &msg);
771 } else {
772 initializeMotionEvent(motionEvent, &msg);
773 }
774 chain = msg.body.motion.seq;
775 }
776 batch.samples.removeItemsAt(0, count);
777
778 *outSeq = chain;
779 *outEvent = motionEvent;
780 return OK;
781}
782
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100783void InputConsumer::updateTouchState(InputMessage& msg) {
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800784 if (!mResampleTouch || !isPointerEvent(msg.body.motion.source)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700785 return;
786 }
787
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100788 int32_t deviceId = msg.body.motion.deviceId;
789 int32_t source = msg.body.motion.source;
Jeff Brown5912f952013-07-01 19:10:31 -0700790
791 // Update the touch state history to incorporate the new input message.
792 // If the message is in the past relative to the most recently produced resampled
793 // touch, then use the resampled time and coordinates instead.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100794 switch (msg.body.motion.action & AMOTION_EVENT_ACTION_MASK) {
Jeff Brown5912f952013-07-01 19:10:31 -0700795 case AMOTION_EVENT_ACTION_DOWN: {
796 ssize_t index = findTouchState(deviceId, source);
797 if (index < 0) {
798 mTouchStates.push();
799 index = mTouchStates.size() - 1;
800 }
801 TouchState& touchState = mTouchStates.editItemAt(index);
802 touchState.initialize(deviceId, source);
803 touchState.addHistory(msg);
804 break;
805 }
806
807 case AMOTION_EVENT_ACTION_MOVE: {
808 ssize_t index = findTouchState(deviceId, source);
809 if (index >= 0) {
810 TouchState& touchState = mTouchStates.editItemAt(index);
811 touchState.addHistory(msg);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800812 rewriteMessage(touchState, msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700813 }
814 break;
815 }
816
817 case AMOTION_EVENT_ACTION_POINTER_DOWN: {
818 ssize_t index = findTouchState(deviceId, source);
819 if (index >= 0) {
820 TouchState& touchState = mTouchStates.editItemAt(index);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100821 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -0700822 rewriteMessage(touchState, msg);
823 }
824 break;
825 }
826
827 case AMOTION_EVENT_ACTION_POINTER_UP: {
828 ssize_t index = findTouchState(deviceId, source);
829 if (index >= 0) {
830 TouchState& touchState = mTouchStates.editItemAt(index);
831 rewriteMessage(touchState, msg);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100832 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -0700833 }
834 break;
835 }
836
837 case AMOTION_EVENT_ACTION_SCROLL: {
838 ssize_t index = findTouchState(deviceId, source);
839 if (index >= 0) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800840 TouchState& touchState = mTouchStates.editItemAt(index);
Jeff Brown5912f952013-07-01 19:10:31 -0700841 rewriteMessage(touchState, msg);
842 }
843 break;
844 }
845
846 case AMOTION_EVENT_ACTION_UP:
847 case AMOTION_EVENT_ACTION_CANCEL: {
848 ssize_t index = findTouchState(deviceId, source);
849 if (index >= 0) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800850 TouchState& touchState = mTouchStates.editItemAt(index);
Jeff Brown5912f952013-07-01 19:10:31 -0700851 rewriteMessage(touchState, msg);
852 mTouchStates.removeAt(index);
853 }
854 break;
855 }
856 }
857}
858
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800859/**
860 * Replace the coordinates in msg with the coordinates in lastResample, if necessary.
861 *
862 * If lastResample is no longer valid for a specific pointer (i.e. the lastResample time
863 * is in the past relative to msg and the past two events do not contain identical coordinates),
864 * then invalidate the lastResample data for that pointer.
865 * If the two past events have identical coordinates, then lastResample data for that pointer will
866 * remain valid, and will be used to replace these coordinates. Thus, if a certain coordinate x0 is
867 * resampled to the new value x1, then x1 will always be used to replace x0 until some new value
868 * not equal to x0 is received.
869 */
870void InputConsumer::rewriteMessage(TouchState& state, InputMessage& msg) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100871 nsecs_t eventTime = msg.body.motion.eventTime;
872 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
873 uint32_t id = msg.body.motion.pointers[i].properties.id;
Jeff Brown5912f952013-07-01 19:10:31 -0700874 if (state.lastResample.idBits.hasBit(id)) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100875 if (eventTime < state.lastResample.eventTime ||
876 state.recentCoordinatesAreIdentical(id)) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800877 PointerCoords& msgCoords = msg.body.motion.pointers[i].coords;
878 const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
Jeff Brown5912f952013-07-01 19:10:31 -0700879#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100880 ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
881 resampleCoords.getX(), resampleCoords.getY(),
882 msgCoords.getX(), msgCoords.getY());
Jeff Brown5912f952013-07-01 19:10:31 -0700883#endif
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800884 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
885 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
886 } else {
887 state.lastResample.idBits.clearBit(id);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100888 }
Jeff Brown5912f952013-07-01 19:10:31 -0700889 }
890 }
891}
892
893void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
894 const InputMessage* next) {
895 if (!mResampleTouch
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800896 || !(isPointerEvent(event->getSource()))
Jeff Brown5912f952013-07-01 19:10:31 -0700897 || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
898 return;
899 }
900
901 ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
902 if (index < 0) {
903#if DEBUG_RESAMPLING
904 ALOGD("Not resampled, no touch state for device.");
905#endif
906 return;
907 }
908
909 TouchState& touchState = mTouchStates.editItemAt(index);
910 if (touchState.historySize < 1) {
911#if DEBUG_RESAMPLING
912 ALOGD("Not resampled, no history for device.");
913#endif
914 return;
915 }
916
917 // Ensure that the current sample has all of the pointers that need to be reported.
918 const History* current = touchState.getHistory(0);
919 size_t pointerCount = event->getPointerCount();
920 for (size_t i = 0; i < pointerCount; i++) {
921 uint32_t id = event->getPointerId(i);
922 if (!current->idBits.hasBit(id)) {
923#if DEBUG_RESAMPLING
924 ALOGD("Not resampled, missing id %d", id);
925#endif
926 return;
927 }
928 }
929
930 // Find the data to use for resampling.
931 const History* other;
932 History future;
933 float alpha;
934 if (next) {
935 // Interpolate between current sample and future sample.
936 // So current->eventTime <= sampleTime <= future.eventTime.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100937 future.initializeFrom(*next);
Jeff Brown5912f952013-07-01 19:10:31 -0700938 other = &future;
939 nsecs_t delta = future.eventTime - current->eventTime;
940 if (delta < RESAMPLE_MIN_DELTA) {
941#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100942 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
Jeff Brown5912f952013-07-01 19:10:31 -0700943#endif
944 return;
945 }
946 alpha = float(sampleTime - current->eventTime) / delta;
947 } else if (touchState.historySize >= 2) {
948 // Extrapolate future sample using current sample and past sample.
949 // So other->eventTime <= current->eventTime <= sampleTime.
950 other = touchState.getHistory(1);
951 nsecs_t delta = current->eventTime - other->eventTime;
952 if (delta < RESAMPLE_MIN_DELTA) {
953#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100954 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
Andrew de los Reyesde18f6c2015-10-01 15:57:25 -0700955#endif
956 return;
957 } else if (delta > RESAMPLE_MAX_DELTA) {
958#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100959 ALOGD("Not resampled, delta time is too large: %" PRId64 " ns.", delta);
Jeff Brown5912f952013-07-01 19:10:31 -0700960#endif
961 return;
962 }
963 nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
964 if (sampleTime > maxPredict) {
965#if DEBUG_RESAMPLING
966 ALOGD("Sample time is too far in the future, adjusting prediction "
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100967 "from %" PRId64 " to %" PRId64 " ns.",
Jeff Brown5912f952013-07-01 19:10:31 -0700968 sampleTime - current->eventTime, maxPredict - current->eventTime);
969#endif
970 sampleTime = maxPredict;
971 }
972 alpha = float(current->eventTime - sampleTime) / delta;
973 } else {
974#if DEBUG_RESAMPLING
975 ALOGD("Not resampled, insufficient data.");
976#endif
977 return;
978 }
979
980 // Resample touch coordinates.
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800981 History oldLastResample;
982 oldLastResample.initializeFrom(touchState.lastResample);
Jeff Brown5912f952013-07-01 19:10:31 -0700983 touchState.lastResample.eventTime = sampleTime;
984 touchState.lastResample.idBits.clear();
985 for (size_t i = 0; i < pointerCount; i++) {
986 uint32_t id = event->getPointerId(i);
987 touchState.lastResample.idToIndex[id] = i;
988 touchState.lastResample.idBits.markBit(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800989 if (oldLastResample.hasPointerId(id) && touchState.recentCoordinatesAreIdentical(id)) {
990 // We maintain the previously resampled value for this pointer (stored in
991 // oldLastResample) when the coordinates for this pointer haven't changed since then.
992 // This way we don't introduce artificial jitter when pointers haven't actually moved.
993
994 // We know here that the coordinates for the pointer haven't changed because we
995 // would've cleared the resampled bit in rewriteMessage if they had. We can't modify
996 // lastResample in place becasue the mapping from pointer ID to index may have changed.
997 touchState.lastResample.pointers[i].copyFrom(oldLastResample.getPointerById(id));
998 continue;
999 }
1000
Jeff Brown5912f952013-07-01 19:10:31 -07001001 PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
1002 const PointerCoords& currentCoords = current->getPointerById(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001003 resampledCoords.copyFrom(currentCoords);
Jeff Brown5912f952013-07-01 19:10:31 -07001004 if (other->idBits.hasBit(id)
1005 && shouldResampleTool(event->getToolType(i))) {
1006 const PointerCoords& otherCoords = other->getPointerById(id);
Jeff Brown5912f952013-07-01 19:10:31 -07001007 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
1008 lerp(currentCoords.getX(), otherCoords.getX(), alpha));
1009 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
1010 lerp(currentCoords.getY(), otherCoords.getY(), alpha));
1011#if DEBUG_RESAMPLING
1012 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
1013 "other (%0.3f, %0.3f), alpha %0.3f",
1014 id, resampledCoords.getX(), resampledCoords.getY(),
1015 currentCoords.getX(), currentCoords.getY(),
1016 otherCoords.getX(), otherCoords.getY(),
1017 alpha);
1018#endif
1019 } else {
Jeff Brown5912f952013-07-01 19:10:31 -07001020#if DEBUG_RESAMPLING
1021 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
1022 id, resampledCoords.getX(), resampledCoords.getY(),
1023 currentCoords.getX(), currentCoords.getY());
1024#endif
1025 }
1026 }
1027
1028 event->addSample(sampleTime, touchState.lastResample.pointers);
1029}
1030
1031bool InputConsumer::shouldResampleTool(int32_t toolType) {
1032 return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
1033 || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
1034}
1035
1036status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
1037#if DEBUG_TRANSPORT_ACTIONS
1038 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001039 mChannel->getName().c_str(), seq, handled ? "true" : "false");
Jeff Brown5912f952013-07-01 19:10:31 -07001040#endif
1041
1042 if (!seq) {
1043 ALOGE("Attempted to send a finished signal with sequence number 0.");
1044 return BAD_VALUE;
1045 }
1046
1047 // Send finished signals for the batch sequence chain first.
1048 size_t seqChainCount = mSeqChains.size();
1049 if (seqChainCount) {
1050 uint32_t currentSeq = seq;
1051 uint32_t chainSeqs[seqChainCount];
1052 size_t chainIndex = 0;
Dan Austin1faef802015-09-22 14:28:07 -07001053 for (size_t i = seqChainCount; i > 0; ) {
1054 i--;
Jeff Brown5912f952013-07-01 19:10:31 -07001055 const SeqChain& seqChain = mSeqChains.itemAt(i);
1056 if (seqChain.seq == currentSeq) {
1057 currentSeq = seqChain.chain;
1058 chainSeqs[chainIndex++] = currentSeq;
1059 mSeqChains.removeAt(i);
1060 }
1061 }
1062 status_t status = OK;
Dan Austin1faef802015-09-22 14:28:07 -07001063 while (!status && chainIndex > 0) {
1064 chainIndex--;
Jeff Brown5912f952013-07-01 19:10:31 -07001065 status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
1066 }
1067 if (status) {
1068 // An error occurred so at least one signal was not sent, reconstruct the chain.
gaoshang9090d4f2017-05-17 14:36:46 +08001069 for (;;) {
Jeff Brown5912f952013-07-01 19:10:31 -07001070 SeqChain seqChain;
1071 seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
1072 seqChain.chain = chainSeqs[chainIndex];
1073 mSeqChains.push(seqChain);
gaoshang9090d4f2017-05-17 14:36:46 +08001074 if (!chainIndex) break;
1075 chainIndex--;
1076 }
Jeff Brown5912f952013-07-01 19:10:31 -07001077 return status;
1078 }
1079 }
1080
1081 // Send finished signal for the last message in the batch.
1082 return sendUnchainedFinishedSignal(seq, handled);
1083}
1084
1085status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
1086 InputMessage msg;
1087 msg.header.type = InputMessage::TYPE_FINISHED;
1088 msg.body.finished.seq = seq;
1089 msg.body.finished.handled = handled;
1090 return mChannel->sendMessage(&msg);
1091}
1092
1093bool InputConsumer::hasDeferredEvent() const {
1094 return mMsgDeferred;
1095}
1096
1097bool InputConsumer::hasPendingBatch() const {
1098 return !mBatches.isEmpty();
1099}
1100
1101ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
1102 for (size_t i = 0; i < mBatches.size(); i++) {
1103 const Batch& batch = mBatches.itemAt(i);
1104 const InputMessage& head = batch.samples.itemAt(0);
1105 if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
1106 return i;
1107 }
1108 }
1109 return -1;
1110}
1111
1112ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
1113 for (size_t i = 0; i < mTouchStates.size(); i++) {
1114 const TouchState& touchState = mTouchStates.itemAt(i);
1115 if (touchState.deviceId == deviceId && touchState.source == source) {
1116 return i;
1117 }
1118 }
1119 return -1;
1120}
1121
1122void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
1123 event->initialize(
1124 msg->body.key.deviceId,
1125 msg->body.key.source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001126 msg->body.key.displayId,
Jeff Brown5912f952013-07-01 19:10:31 -07001127 msg->body.key.action,
1128 msg->body.key.flags,
1129 msg->body.key.keyCode,
1130 msg->body.key.scanCode,
1131 msg->body.key.metaState,
1132 msg->body.key.repeatCount,
1133 msg->body.key.downTime,
1134 msg->body.key.eventTime);
1135}
1136
1137void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001138 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001139 PointerProperties pointerProperties[pointerCount];
1140 PointerCoords pointerCoords[pointerCount];
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001141 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -07001142 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
1143 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
1144 }
1145
Garfield Tan00f511d2019-06-12 16:55:40 -07001146 event->initialize(msg->body.motion.deviceId, msg->body.motion.source,
1147 msg->body.motion.displayId, msg->body.motion.action,
1148 msg->body.motion.actionButton, msg->body.motion.flags,
1149 msg->body.motion.edgeFlags, msg->body.motion.metaState,
1150 msg->body.motion.buttonState, msg->body.motion.classification,
1151 msg->body.motion.xOffset, msg->body.motion.yOffset,
1152 msg->body.motion.xPrecision, msg->body.motion.yPrecision,
1153 msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
1154 msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
1155 pointerProperties, pointerCoords);
Jeff Brown5912f952013-07-01 19:10:31 -07001156}
1157
1158void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001159 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001160 PointerCoords pointerCoords[pointerCount];
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001161 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -07001162 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
1163 }
1164
1165 event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
1166 event->addSample(msg->body.motion.eventTime, pointerCoords);
1167}
1168
1169bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
1170 const InputMessage& head = batch.samples.itemAt(0);
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001171 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001172 if (head.body.motion.pointerCount != pointerCount
1173 || head.body.motion.action != msg->body.motion.action) {
1174 return false;
1175 }
1176 for (size_t i = 0; i < pointerCount; i++) {
1177 if (head.body.motion.pointers[i].properties
1178 != msg->body.motion.pointers[i].properties) {
1179 return false;
1180 }
1181 }
1182 return true;
1183}
1184
1185ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
1186 size_t numSamples = batch.samples.size();
1187 size_t index = 0;
1188 while (index < numSamples
1189 && batch.samples.itemAt(index).body.motion.eventTime <= time) {
1190 index += 1;
1191 }
1192 return ssize_t(index) - 1;
1193}
1194
1195} // namespace android