blob: 366c93cf1f79d5074b7eea0c009e8c57cd337675 [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>
37
Michael Wright3dd60e22019-03-27 22:06:44 +000038using android::base::StringPrintf;
39
Jeff Brown5912f952013-07-01 19:10:31 -070040namespace android {
41
42// Socket buffer size. The default is typically about 128KB, which is much larger than
43// we really need. So we make it smaller. It just needs to be big enough to hold
44// a few dozen large multi-finger motion events in the case where an application gets
45// behind processing touches.
46static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
47
48// Nanoseconds per milliseconds.
49static const nsecs_t NANOS_PER_MS = 1000000;
50
51// Latency added during resampling. A few milliseconds doesn't hurt much but
52// reduces the impact of mispredicted touch positions.
53static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
54
55// Minimum time difference between consecutive samples before attempting to resample.
56static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
57
Andrew de los Reyesde18f6c2015-10-01 15:57:25 -070058// Maximum time difference between consecutive samples before attempting to resample
59// by extrapolation.
60static const nsecs_t RESAMPLE_MAX_DELTA = 20 * NANOS_PER_MS;
61
Jeff Brown5912f952013-07-01 19:10:31 -070062// Maximum time to predict forward from the last known state, to avoid predicting too
63// far into the future. This time is further bounded by 50% of the last time delta.
64static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
65
Siarhei Vishniakoub5433e92019-02-21 09:27:39 -060066/**
67 * System property for enabling / disabling touch resampling.
68 * Resampling extrapolates / interpolates the reported touch event coordinates to better
69 * align them to the VSYNC signal, thus resulting in smoother scrolling performance.
70 * Resampling is not needed (and should be disabled) on hardware that already
71 * has touch events triggered by VSYNC.
72 * Set to "1" to enable resampling (default).
73 * Set to "0" to disable resampling.
74 * Resampling is enabled by default.
75 */
76static const char* PROPERTY_RESAMPLING_ENABLED = "ro.input.resampling";
77
Jeff Brown5912f952013-07-01 19:10:31 -070078template<typename T>
79inline static T min(const T& a, const T& b) {
80 return a < b ? a : b;
81}
82
83inline static float lerp(float a, float b, float alpha) {
84 return a + alpha * (b - a);
85}
86
Siarhei Vishniakou128eab12019-05-23 10:25:59 +080087inline static bool isPointerEvent(int32_t source) {
88 return (source & AINPUT_SOURCE_CLASS_POINTER) == AINPUT_SOURCE_CLASS_POINTER;
89}
90
Jeff Brown5912f952013-07-01 19:10:31 -070091// --- InputMessage ---
92
93bool InputMessage::isValid(size_t actualSize) const {
94 if (size() == actualSize) {
95 switch (header.type) {
96 case TYPE_KEY:
97 return true;
98 case TYPE_MOTION:
99 return body.motion.pointerCount > 0
100 && body.motion.pointerCount <= MAX_POINTERS;
101 case TYPE_FINISHED:
102 return true;
103 }
104 }
105 return false;
106}
107
108size_t InputMessage::size() const {
109 switch (header.type) {
110 case TYPE_KEY:
111 return sizeof(Header) + body.key.size();
112 case TYPE_MOTION:
113 return sizeof(Header) + body.motion.size();
114 case TYPE_FINISHED:
115 return sizeof(Header) + body.finished.size();
116 }
117 return sizeof(Header);
118}
119
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800120/**
121 * There could be non-zero bytes in-between InputMessage fields. Force-initialize the entire
122 * memory to zero, then only copy the valid bytes on a per-field basis.
123 */
124void InputMessage::getSanitizedCopy(InputMessage* msg) const {
125 memset(msg, 0, sizeof(*msg));
126
127 // Write the header
128 msg->header.type = header.type;
129
130 // Write the body
131 switch(header.type) {
132 case InputMessage::TYPE_KEY: {
133 // uint32_t seq
134 msg->body.key.seq = body.key.seq;
135 // nsecs_t eventTime
136 msg->body.key.eventTime = body.key.eventTime;
137 // int32_t deviceId
138 msg->body.key.deviceId = body.key.deviceId;
139 // int32_t source
140 msg->body.key.source = body.key.source;
141 // int32_t displayId
142 msg->body.key.displayId = body.key.displayId;
143 // int32_t action
144 msg->body.key.action = body.key.action;
145 // int32_t flags
146 msg->body.key.flags = body.key.flags;
147 // int32_t keyCode
148 msg->body.key.keyCode = body.key.keyCode;
149 // int32_t scanCode
150 msg->body.key.scanCode = body.key.scanCode;
151 // int32_t metaState
152 msg->body.key.metaState = body.key.metaState;
153 // int32_t repeatCount
154 msg->body.key.repeatCount = body.key.repeatCount;
155 // nsecs_t downTime
156 msg->body.key.downTime = body.key.downTime;
157 break;
158 }
159 case InputMessage::TYPE_MOTION: {
160 // uint32_t seq
161 msg->body.motion.seq = body.motion.seq;
162 // nsecs_t eventTime
163 msg->body.motion.eventTime = body.motion.eventTime;
164 // int32_t deviceId
165 msg->body.motion.deviceId = body.motion.deviceId;
166 // int32_t source
167 msg->body.motion.source = body.motion.source;
168 // int32_t displayId
169 msg->body.motion.displayId = body.motion.displayId;
170 // int32_t action
171 msg->body.motion.action = body.motion.action;
172 // int32_t actionButton
173 msg->body.motion.actionButton = body.motion.actionButton;
174 // int32_t flags
175 msg->body.motion.flags = body.motion.flags;
176 // int32_t metaState
177 msg->body.motion.metaState = body.motion.metaState;
178 // int32_t buttonState
179 msg->body.motion.buttonState = body.motion.buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800180 // MotionClassification classification
181 msg->body.motion.classification = body.motion.classification;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800182 // int32_t edgeFlags
183 msg->body.motion.edgeFlags = body.motion.edgeFlags;
184 // nsecs_t downTime
185 msg->body.motion.downTime = body.motion.downTime;
186 // float xOffset
187 msg->body.motion.xOffset = body.motion.xOffset;
188 // float yOffset
189 msg->body.motion.yOffset = body.motion.yOffset;
190 // float xPrecision
191 msg->body.motion.xPrecision = body.motion.xPrecision;
192 // float yPrecision
193 msg->body.motion.yPrecision = body.motion.yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700194 // float xCursorPosition
195 msg->body.motion.xCursorPosition = body.motion.xCursorPosition;
196 // float yCursorPosition
197 msg->body.motion.yCursorPosition = body.motion.yCursorPosition;
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800198 // uint32_t pointerCount
199 msg->body.motion.pointerCount = body.motion.pointerCount;
200 //struct Pointer pointers[MAX_POINTERS]
201 for (size_t i = 0; i < body.motion.pointerCount; i++) {
202 // PointerProperties properties
203 msg->body.motion.pointers[i].properties.id = body.motion.pointers[i].properties.id;
204 msg->body.motion.pointers[i].properties.toolType =
205 body.motion.pointers[i].properties.toolType,
206 // PointerCoords coords
207 msg->body.motion.pointers[i].coords.bits = body.motion.pointers[i].coords.bits;
208 const uint32_t count = BitSet64::count(body.motion.pointers[i].coords.bits);
209 memcpy(&msg->body.motion.pointers[i].coords.values[0],
210 &body.motion.pointers[i].coords.values[0],
211 count * (sizeof(body.motion.pointers[i].coords.values[0])));
212 }
213 break;
214 }
215 case InputMessage::TYPE_FINISHED: {
216 msg->body.finished.seq = body.finished.seq;
217 msg->body.finished.handled = body.finished.handled;
218 break;
219 }
220 default: {
221 LOG_FATAL("Unexpected message type %i", header.type);
222 break;
223 }
224 }
225}
Jeff Brown5912f952013-07-01 19:10:31 -0700226
227// --- InputChannel ---
228
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700229sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd) {
230 const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
231 if (result != 0) {
232 LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
233 strerror(errno));
234 return nullptr;
235 }
236 return new InputChannel(name, std::move(fd));
237}
238
239InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd)
240 : mName(name), mFd(std::move(fd)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700241#if DEBUG_CHANNEL_LIFECYCLE
242 ALOGD("Input channel constructed: name='%s', fd=%d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800243 mName.c_str(), fd);
Jeff Brown5912f952013-07-01 19:10:31 -0700244#endif
Jeff Brown5912f952013-07-01 19:10:31 -0700245}
246
247InputChannel::~InputChannel() {
248#if DEBUG_CHANNEL_LIFECYCLE
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700249 ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get());
Jeff Brown5912f952013-07-01 19:10:31 -0700250#endif
Robert Carr3720ed02018-08-08 16:08:27 -0700251}
252
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800253status_t InputChannel::openInputChannelPair(const std::string& name,
Jeff Brown5912f952013-07-01 19:10:31 -0700254 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
255 int sockets[2];
256 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
257 status_t result = -errno;
258 ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800259 name.c_str(), errno);
Jeff Brown5912f952013-07-01 19:10:31 -0700260 outServerChannel.clear();
261 outClientChannel.clear();
262 return result;
263 }
264
265 int bufferSize = SOCKET_BUFFER_SIZE;
266 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
267 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
268 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
269 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
270
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700271 std::string serverChannelName = name + " (server)";
272 android::base::unique_fd serverFd(sockets[0]);
273 outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd));
Jeff Brown5912f952013-07-01 19:10:31 -0700274
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700275 std::string clientChannelName = name + " (client)";
276 android::base::unique_fd clientFd(sockets[1]);
277 outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd));
Jeff Brown5912f952013-07-01 19:10:31 -0700278 return OK;
279}
280
281status_t InputChannel::sendMessage(const InputMessage* msg) {
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800282 const size_t msgLength = msg->size();
283 InputMessage cleanMsg;
284 msg->getSanitizedCopy(&cleanMsg);
Jeff Brown5912f952013-07-01 19:10:31 -0700285 ssize_t nWrite;
286 do {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700287 nWrite = ::send(mFd.get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
Jeff Brown5912f952013-07-01 19:10:31 -0700288 } while (nWrite == -1 && errno == EINTR);
289
290 if (nWrite < 0) {
291 int error = errno;
292#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800293 ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.c_str(),
Jeff Brown5912f952013-07-01 19:10:31 -0700294 msg->header.type, error);
295#endif
296 if (error == EAGAIN || error == EWOULDBLOCK) {
297 return WOULD_BLOCK;
298 }
299 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) {
300 return DEAD_OBJECT;
301 }
302 return -error;
303 }
304
305 if (size_t(nWrite) != msgLength) {
306#if DEBUG_CHANNEL_MESSAGES
307 ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800308 mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700309#endif
310 return DEAD_OBJECT;
311 }
312
313#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800314 ALOGD("channel '%s' ~ sent message of type %d", mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700315#endif
316 return OK;
317}
318
319status_t InputChannel::receiveMessage(InputMessage* msg) {
320 ssize_t nRead;
321 do {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700322 nRead = ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT);
Jeff Brown5912f952013-07-01 19:10:31 -0700323 } while (nRead == -1 && errno == EINTR);
324
325 if (nRead < 0) {
326 int error = errno;
327#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800328 ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.c_str(), errno);
Jeff Brown5912f952013-07-01 19:10:31 -0700329#endif
330 if (error == EAGAIN || error == EWOULDBLOCK) {
331 return WOULD_BLOCK;
332 }
333 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
334 return DEAD_OBJECT;
335 }
336 return -error;
337 }
338
339 if (nRead == 0) { // check for EOF
340#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800341 ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700342#endif
343 return DEAD_OBJECT;
344 }
345
346 if (!msg->isValid(nRead)) {
347#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800348 ALOGD("channel '%s' ~ received invalid message", mName.c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700349#endif
350 return BAD_VALUE;
351 }
352
353#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800354 ALOGD("channel '%s' ~ received message of type %d", mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700355#endif
356 return OK;
357}
358
359sp<InputChannel> InputChannel::dup() const {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700360 android::base::unique_fd newFd(::dup(getFd()));
361 if (!newFd.ok()) {
362 ALOGE("Could not duplicate fd %i for channel %s: %s", getFd(), mName.c_str(),
363 strerror(errno));
Siarhei Vishniakou3d8df0e2019-09-17 14:53:07 +0100364 const bool hitFdLimit = errno == EMFILE || errno == ENFILE;
365 // If this process is out of file descriptors, then throwing that might end up exploding
366 // on the other side of a binder call, which isn't really helpful.
367 // Better to just crash here and hope that the FD leak is slow.
368 // Other failures could be client errors, so we still propagate those back to the caller.
369 LOG_ALWAYS_FATAL_IF(hitFdLimit, "Too many open files, could not duplicate input channel %s",
370 getName().c_str());
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700371 return nullptr;
372 }
373 return InputChannel::create(mName, std::move(newFd));
Jeff Brown5912f952013-07-01 19:10:31 -0700374}
375
Robert Carr3720ed02018-08-08 16:08:27 -0700376status_t InputChannel::write(Parcel& out) const {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700377 status_t s = out.writeCString(getName().c_str());
Robert Carr3720ed02018-08-08 16:08:27 -0700378 if (s != OK) {
379 return s;
380 }
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700381
Robert Carr803535b2018-08-02 16:38:15 -0700382 s = out.writeStrongBinder(mToken);
383 if (s != OK) {
384 return s;
385 }
Robert Carr3720ed02018-08-08 16:08:27 -0700386
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700387 s = out.writeUniqueFileDescriptor(mFd);
Robert Carr3720ed02018-08-08 16:08:27 -0700388 return s;
389}
390
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700391sp<InputChannel> InputChannel::read(const Parcel& from) {
392 std::string name = from.readCString();
393 sp<IBinder> token = from.readStrongBinder();
394 android::base::unique_fd rawFd;
395 status_t fdResult = from.readUniqueFileDescriptor(&rawFd);
396 if (fdResult != OK) {
397 return nullptr;
Robert Carr3720ed02018-08-08 16:08:27 -0700398 }
399
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700400 sp<InputChannel> channel = InputChannel::create(name, std::move(rawFd));
401 if (channel != nullptr) {
402 channel->setToken(token);
403 }
404 return channel;
Robert Carr3720ed02018-08-08 16:08:27 -0700405}
406
Robert Carr803535b2018-08-02 16:38:15 -0700407sp<IBinder> InputChannel::getToken() const {
408 return mToken;
409}
410
411void InputChannel::setToken(const sp<IBinder>& token) {
412 if (mToken != nullptr) {
413 ALOGE("Assigning InputChannel (%s) a second handle?", mName.c_str());
414 }
415 mToken = token;
416}
417
Jeff Brown5912f952013-07-01 19:10:31 -0700418// --- InputPublisher ---
419
420InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
421 mChannel(channel) {
422}
423
424InputPublisher::~InputPublisher() {
425}
426
427status_t InputPublisher::publishKeyEvent(
428 uint32_t seq,
429 int32_t deviceId,
430 int32_t source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100431 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -0700432 int32_t action,
433 int32_t flags,
434 int32_t keyCode,
435 int32_t scanCode,
436 int32_t metaState,
437 int32_t repeatCount,
438 nsecs_t downTime,
439 nsecs_t eventTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000440 if (ATRACE_ENABLED()) {
441 std::string message = StringPrintf("publishKeyEvent(inputChannel=%s, keyCode=%" PRId32 ")",
442 mChannel->getName().c_str(), keyCode);
443 ATRACE_NAME(message.c_str());
444 }
Jeff Brown5912f952013-07-01 19:10:31 -0700445#if DEBUG_TRANSPORT_ACTIONS
446 ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
447 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700448 "downTime=%" PRId64 ", eventTime=%" PRId64,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800449 mChannel->getName().c_str(), seq,
Jeff Brown5912f952013-07-01 19:10:31 -0700450 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
451 downTime, eventTime);
452#endif
453
454 if (!seq) {
455 ALOGE("Attempted to publish a key event with sequence number 0.");
456 return BAD_VALUE;
457 }
458
459 InputMessage msg;
460 msg.header.type = InputMessage::TYPE_KEY;
461 msg.body.key.seq = seq;
462 msg.body.key.deviceId = deviceId;
463 msg.body.key.source = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100464 msg.body.key.displayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700465 msg.body.key.action = action;
466 msg.body.key.flags = flags;
467 msg.body.key.keyCode = keyCode;
468 msg.body.key.scanCode = scanCode;
469 msg.body.key.metaState = metaState;
470 msg.body.key.repeatCount = repeatCount;
471 msg.body.key.downTime = downTime;
472 msg.body.key.eventTime = eventTime;
473 return mChannel->sendMessage(&msg);
474}
475
476status_t InputPublisher::publishMotionEvent(
Garfield Tan00f511d2019-06-12 16:55:40 -0700477 uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
478 int32_t actionButton, int32_t flags, int32_t edgeFlags, int32_t metaState,
479 int32_t buttonState, MotionClassification classification, float xOffset, float yOffset,
480 float xPrecision, float yPrecision, float xCursorPosition, float yCursorPosition,
481 nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
482 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000483 if (ATRACE_ENABLED()) {
484 std::string message = StringPrintf(
485 "publishMotionEvent(inputChannel=%s, action=%" PRId32 ")",
486 mChannel->getName().c_str(), action);
487 ATRACE_NAME(message.c_str());
488 }
Jeff Brown5912f952013-07-01 19:10:31 -0700489#if DEBUG_TRANSPORT_ACTIONS
490 ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800491 "displayId=%" PRId32 ", "
Michael Wright7b159c92015-05-14 14:48:03 +0100492 "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800493 "metaState=0x%x, buttonState=0x%x, classification=%s, xOffset=%f, yOffset=%f, "
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700494 "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
Michael Wright63ff3a82014-06-10 13:03:17 -0700495 "pointerCount=%" PRIu32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800496 mChannel->getName().c_str(), seq,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800497 deviceId, source, displayId, action, actionButton, flags, edgeFlags, metaState,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800498 buttonState, motionClassificationToString(classification),
499 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
Jeff Brown5912f952013-07-01 19:10:31 -0700500#endif
501
502 if (!seq) {
503 ALOGE("Attempted to publish a motion event with sequence number 0.");
504 return BAD_VALUE;
505 }
506
507 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Michael Wright63ff3a82014-06-10 13:03:17 -0700508 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %" PRIu32 ".",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800509 mChannel->getName().c_str(), pointerCount);
Jeff Brown5912f952013-07-01 19:10:31 -0700510 return BAD_VALUE;
511 }
512
513 InputMessage msg;
514 msg.header.type = InputMessage::TYPE_MOTION;
515 msg.body.motion.seq = seq;
516 msg.body.motion.deviceId = deviceId;
517 msg.body.motion.source = source;
Tarandeep Singh58641502017-07-31 10:51:54 -0700518 msg.body.motion.displayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700519 msg.body.motion.action = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100520 msg.body.motion.actionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700521 msg.body.motion.flags = flags;
522 msg.body.motion.edgeFlags = edgeFlags;
523 msg.body.motion.metaState = metaState;
524 msg.body.motion.buttonState = buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800525 msg.body.motion.classification = classification;
Jeff Brown5912f952013-07-01 19:10:31 -0700526 msg.body.motion.xOffset = xOffset;
527 msg.body.motion.yOffset = yOffset;
528 msg.body.motion.xPrecision = xPrecision;
529 msg.body.motion.yPrecision = yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700530 msg.body.motion.xCursorPosition = xCursorPosition;
531 msg.body.motion.yCursorPosition = yCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700532 msg.body.motion.downTime = downTime;
533 msg.body.motion.eventTime = eventTime;
534 msg.body.motion.pointerCount = pointerCount;
Narayan Kamathbc6001b2014-05-02 17:53:33 +0100535 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -0700536 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
537 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
538 }
Atif Niyaz3d3fa522019-07-25 11:12:39 -0700539
Jeff Brown5912f952013-07-01 19:10:31 -0700540 return mChannel->sendMessage(&msg);
541}
542
543status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
544#if DEBUG_TRANSPORT_ACTIONS
545 ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800546 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700547#endif
548
549 InputMessage msg;
550 status_t result = mChannel->receiveMessage(&msg);
551 if (result) {
552 *outSeq = 0;
553 *outHandled = false;
554 return result;
555 }
556 if (msg.header.type != InputMessage::TYPE_FINISHED) {
557 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800558 mChannel->getName().c_str(), msg.header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700559 return UNKNOWN_ERROR;
560 }
561 *outSeq = msg.body.finished.seq;
562 *outHandled = msg.body.finished.handled;
563 return OK;
564}
565
566// --- InputConsumer ---
567
568InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
569 mResampleTouch(isTouchResamplingEnabled()),
570 mChannel(channel), mMsgDeferred(false) {
571}
572
573InputConsumer::~InputConsumer() {
574}
575
576bool InputConsumer::isTouchResamplingEnabled() {
Siarhei Vishniakoub5433e92019-02-21 09:27:39 -0600577 return property_get_bool(PROPERTY_RESAMPLING_ENABLED, true);
Jeff Brown5912f952013-07-01 19:10:31 -0700578}
579
580status_t InputConsumer::consume(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800581 bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700582#if DEBUG_TRANSPORT_ACTIONS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700583 ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%" PRId64,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800584 mChannel->getName().c_str(), consumeBatches ? "true" : "false", frameTime);
Jeff Brown5912f952013-07-01 19:10:31 -0700585#endif
586
587 *outSeq = 0;
Yi Kong5bed83b2018-07-17 12:53:47 -0700588 *outEvent = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700589
590 // Fetch the next input message.
591 // Loop until an event can be returned or no additional events are received.
592 while (!*outEvent) {
593 if (mMsgDeferred) {
594 // mMsg contains a valid input message from the previous call to consume
595 // that has not yet been processed.
596 mMsgDeferred = false;
597 } else {
598 // Receive a fresh message.
599 status_t result = mChannel->receiveMessage(&mMsg);
600 if (result) {
601 // Consume the next batched event unless batches are being held for later.
602 if (consumeBatches || result != WOULD_BLOCK) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800603 result = consumeBatch(factory, frameTime, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700604 if (*outEvent) {
605#if DEBUG_TRANSPORT_ACTIONS
606 ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800607 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700608#endif
609 break;
610 }
611 }
612 return result;
613 }
614 }
615
616 switch (mMsg.header.type) {
617 case InputMessage::TYPE_KEY: {
618 KeyEvent* keyEvent = factory->createKeyEvent();
619 if (!keyEvent) return NO_MEMORY;
620
621 initializeKeyEvent(keyEvent, &mMsg);
622 *outSeq = mMsg.body.key.seq;
623 *outEvent = keyEvent;
624#if DEBUG_TRANSPORT_ACTIONS
625 ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800626 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700627#endif
628 break;
629 }
630
gaoshange3e11a72017-08-08 16:11:31 +0800631 case InputMessage::TYPE_MOTION: {
Jeff Brown5912f952013-07-01 19:10:31 -0700632 ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
633 if (batchIndex >= 0) {
634 Batch& batch = mBatches.editItemAt(batchIndex);
635 if (canAddSample(batch, &mMsg)) {
636 batch.samples.push(mMsg);
637#if DEBUG_TRANSPORT_ACTIONS
638 ALOGD("channel '%s' consumer ~ appended to batch event",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800639 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700640#endif
641 break;
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800642 } else if (isPointerEvent(mMsg.body.motion.source) &&
643 mMsg.body.motion.action == AMOTION_EVENT_ACTION_CANCEL) {
644 // No need to process events that we are going to cancel anyways
645 const size_t count = batch.samples.size();
646 for (size_t i = 0; i < count; i++) {
647 const InputMessage& msg = batch.samples.itemAt(i);
648 sendFinishedSignal(msg.body.motion.seq, false);
649 }
650 batch.samples.removeItemsAt(0, count);
651 mBatches.removeAt(batchIndex);
Jeff Brown5912f952013-07-01 19:10:31 -0700652 } else {
653 // We cannot append to the batch in progress, so we need to consume
654 // the previous batch right now and defer the new message until later.
655 mMsgDeferred = true;
656 status_t result = consumeSamples(factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800657 batch, batch.samples.size(), outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700658 mBatches.removeAt(batchIndex);
659 if (result) {
660 return result;
661 }
662#if DEBUG_TRANSPORT_ACTIONS
663 ALOGD("channel '%s' consumer ~ consumed batch event and "
664 "deferred current event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800665 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700666#endif
667 break;
668 }
669 }
670
671 // Start a new batch if needed.
672 if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
673 || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
674 mBatches.push();
675 Batch& batch = mBatches.editTop();
676 batch.samples.push(mMsg);
677#if DEBUG_TRANSPORT_ACTIONS
678 ALOGD("channel '%s' consumer ~ started batch event",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800679 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700680#endif
681 break;
682 }
683
684 MotionEvent* motionEvent = factory->createMotionEvent();
685 if (! motionEvent) return NO_MEMORY;
686
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100687 updateTouchState(mMsg);
Jeff Brown5912f952013-07-01 19:10:31 -0700688 initializeMotionEvent(motionEvent, &mMsg);
689 *outSeq = mMsg.body.motion.seq;
690 *outEvent = motionEvent;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800691
Jeff Brown5912f952013-07-01 19:10:31 -0700692#if DEBUG_TRANSPORT_ACTIONS
693 ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800694 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700695#endif
696 break;
697 }
698
699 default:
700 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800701 mChannel->getName().c_str(), mMsg.header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700702 return UNKNOWN_ERROR;
703 }
704 }
705 return OK;
706}
707
708status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800709 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700710 status_t result;
Dan Austin1faef802015-09-22 14:28:07 -0700711 for (size_t i = mBatches.size(); i > 0; ) {
712 i--;
Jeff Brown5912f952013-07-01 19:10:31 -0700713 Batch& batch = mBatches.editItemAt(i);
Michael Wright32232172013-10-21 12:05:22 -0700714 if (frameTime < 0) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800715 result = consumeSamples(factory, batch, batch.samples.size(), outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700716 mBatches.removeAt(i);
717 return result;
718 }
719
Michael Wright32232172013-10-21 12:05:22 -0700720 nsecs_t sampleTime = frameTime;
721 if (mResampleTouch) {
722 sampleTime -= RESAMPLE_LATENCY;
723 }
Jeff Brown5912f952013-07-01 19:10:31 -0700724 ssize_t split = findSampleNoLaterThan(batch, sampleTime);
725 if (split < 0) {
726 continue;
727 }
728
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800729 result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700730 const InputMessage* next;
731 if (batch.samples.isEmpty()) {
732 mBatches.removeAt(i);
Yi Kong5bed83b2018-07-17 12:53:47 -0700733 next = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700734 } else {
735 next = &batch.samples.itemAt(0);
736 }
Michael Wright32232172013-10-21 12:05:22 -0700737 if (!result && mResampleTouch) {
Jeff Brown5912f952013-07-01 19:10:31 -0700738 resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
739 }
740 return result;
741 }
742
743 return WOULD_BLOCK;
744}
745
746status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800747 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700748 MotionEvent* motionEvent = factory->createMotionEvent();
749 if (! motionEvent) return NO_MEMORY;
750
751 uint32_t chain = 0;
752 for (size_t i = 0; i < count; i++) {
753 InputMessage& msg = batch.samples.editItemAt(i);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100754 updateTouchState(msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700755 if (i) {
756 SeqChain seqChain;
757 seqChain.seq = msg.body.motion.seq;
758 seqChain.chain = chain;
759 mSeqChains.push(seqChain);
760 addSample(motionEvent, &msg);
761 } else {
762 initializeMotionEvent(motionEvent, &msg);
763 }
764 chain = msg.body.motion.seq;
765 }
766 batch.samples.removeItemsAt(0, count);
767
768 *outSeq = chain;
769 *outEvent = motionEvent;
770 return OK;
771}
772
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100773void InputConsumer::updateTouchState(InputMessage& msg) {
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800774 if (!mResampleTouch || !isPointerEvent(msg.body.motion.source)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700775 return;
776 }
777
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100778 int32_t deviceId = msg.body.motion.deviceId;
779 int32_t source = msg.body.motion.source;
Jeff Brown5912f952013-07-01 19:10:31 -0700780
781 // Update the touch state history to incorporate the new input message.
782 // If the message is in the past relative to the most recently produced resampled
783 // touch, then use the resampled time and coordinates instead.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100784 switch (msg.body.motion.action & AMOTION_EVENT_ACTION_MASK) {
Jeff Brown5912f952013-07-01 19:10:31 -0700785 case AMOTION_EVENT_ACTION_DOWN: {
786 ssize_t index = findTouchState(deviceId, source);
787 if (index < 0) {
788 mTouchStates.push();
789 index = mTouchStates.size() - 1;
790 }
791 TouchState& touchState = mTouchStates.editItemAt(index);
792 touchState.initialize(deviceId, source);
793 touchState.addHistory(msg);
794 break;
795 }
796
797 case AMOTION_EVENT_ACTION_MOVE: {
798 ssize_t index = findTouchState(deviceId, source);
799 if (index >= 0) {
800 TouchState& touchState = mTouchStates.editItemAt(index);
801 touchState.addHistory(msg);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800802 rewriteMessage(touchState, msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700803 }
804 break;
805 }
806
807 case AMOTION_EVENT_ACTION_POINTER_DOWN: {
808 ssize_t index = findTouchState(deviceId, source);
809 if (index >= 0) {
810 TouchState& touchState = mTouchStates.editItemAt(index);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100811 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -0700812 rewriteMessage(touchState, msg);
813 }
814 break;
815 }
816
817 case AMOTION_EVENT_ACTION_POINTER_UP: {
818 ssize_t index = findTouchState(deviceId, source);
819 if (index >= 0) {
820 TouchState& touchState = mTouchStates.editItemAt(index);
821 rewriteMessage(touchState, msg);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100822 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -0700823 }
824 break;
825 }
826
827 case AMOTION_EVENT_ACTION_SCROLL: {
828 ssize_t index = findTouchState(deviceId, source);
829 if (index >= 0) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800830 TouchState& touchState = mTouchStates.editItemAt(index);
Jeff Brown5912f952013-07-01 19:10:31 -0700831 rewriteMessage(touchState, msg);
832 }
833 break;
834 }
835
836 case AMOTION_EVENT_ACTION_UP:
837 case AMOTION_EVENT_ACTION_CANCEL: {
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 mTouchStates.removeAt(index);
843 }
844 break;
845 }
846 }
847}
848
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800849/**
850 * Replace the coordinates in msg with the coordinates in lastResample, if necessary.
851 *
852 * If lastResample is no longer valid for a specific pointer (i.e. the lastResample time
853 * is in the past relative to msg and the past two events do not contain identical coordinates),
854 * then invalidate the lastResample data for that pointer.
855 * If the two past events have identical coordinates, then lastResample data for that pointer will
856 * remain valid, and will be used to replace these coordinates. Thus, if a certain coordinate x0 is
857 * resampled to the new value x1, then x1 will always be used to replace x0 until some new value
858 * not equal to x0 is received.
859 */
860void InputConsumer::rewriteMessage(TouchState& state, InputMessage& msg) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100861 nsecs_t eventTime = msg.body.motion.eventTime;
862 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
863 uint32_t id = msg.body.motion.pointers[i].properties.id;
Jeff Brown5912f952013-07-01 19:10:31 -0700864 if (state.lastResample.idBits.hasBit(id)) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100865 if (eventTime < state.lastResample.eventTime ||
866 state.recentCoordinatesAreIdentical(id)) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800867 PointerCoords& msgCoords = msg.body.motion.pointers[i].coords;
868 const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
Jeff Brown5912f952013-07-01 19:10:31 -0700869#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100870 ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
871 resampleCoords.getX(), resampleCoords.getY(),
872 msgCoords.getX(), msgCoords.getY());
Jeff Brown5912f952013-07-01 19:10:31 -0700873#endif
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800874 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
875 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
876 } else {
877 state.lastResample.idBits.clearBit(id);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100878 }
Jeff Brown5912f952013-07-01 19:10:31 -0700879 }
880 }
881}
882
883void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
884 const InputMessage* next) {
885 if (!mResampleTouch
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800886 || !(isPointerEvent(event->getSource()))
Jeff Brown5912f952013-07-01 19:10:31 -0700887 || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
888 return;
889 }
890
891 ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
892 if (index < 0) {
893#if DEBUG_RESAMPLING
894 ALOGD("Not resampled, no touch state for device.");
895#endif
896 return;
897 }
898
899 TouchState& touchState = mTouchStates.editItemAt(index);
900 if (touchState.historySize < 1) {
901#if DEBUG_RESAMPLING
902 ALOGD("Not resampled, no history for device.");
903#endif
904 return;
905 }
906
907 // Ensure that the current sample has all of the pointers that need to be reported.
908 const History* current = touchState.getHistory(0);
909 size_t pointerCount = event->getPointerCount();
910 for (size_t i = 0; i < pointerCount; i++) {
911 uint32_t id = event->getPointerId(i);
912 if (!current->idBits.hasBit(id)) {
913#if DEBUG_RESAMPLING
914 ALOGD("Not resampled, missing id %d", id);
915#endif
916 return;
917 }
918 }
919
920 // Find the data to use for resampling.
921 const History* other;
922 History future;
923 float alpha;
924 if (next) {
925 // Interpolate between current sample and future sample.
926 // So current->eventTime <= sampleTime <= future.eventTime.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100927 future.initializeFrom(*next);
Jeff Brown5912f952013-07-01 19:10:31 -0700928 other = &future;
929 nsecs_t delta = future.eventTime - current->eventTime;
930 if (delta < RESAMPLE_MIN_DELTA) {
931#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100932 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
Jeff Brown5912f952013-07-01 19:10:31 -0700933#endif
934 return;
935 }
936 alpha = float(sampleTime - current->eventTime) / delta;
937 } else if (touchState.historySize >= 2) {
938 // Extrapolate future sample using current sample and past sample.
939 // So other->eventTime <= current->eventTime <= sampleTime.
940 other = touchState.getHistory(1);
941 nsecs_t delta = current->eventTime - other->eventTime;
942 if (delta < RESAMPLE_MIN_DELTA) {
943#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100944 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
Andrew de los Reyesde18f6c2015-10-01 15:57:25 -0700945#endif
946 return;
947 } else if (delta > RESAMPLE_MAX_DELTA) {
948#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100949 ALOGD("Not resampled, delta time is too large: %" PRId64 " ns.", delta);
Jeff Brown5912f952013-07-01 19:10:31 -0700950#endif
951 return;
952 }
953 nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
954 if (sampleTime > maxPredict) {
955#if DEBUG_RESAMPLING
956 ALOGD("Sample time is too far in the future, adjusting prediction "
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100957 "from %" PRId64 " to %" PRId64 " ns.",
Jeff Brown5912f952013-07-01 19:10:31 -0700958 sampleTime - current->eventTime, maxPredict - current->eventTime);
959#endif
960 sampleTime = maxPredict;
961 }
962 alpha = float(current->eventTime - sampleTime) / delta;
963 } else {
964#if DEBUG_RESAMPLING
965 ALOGD("Not resampled, insufficient data.");
966#endif
967 return;
968 }
969
970 // Resample touch coordinates.
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800971 History oldLastResample;
972 oldLastResample.initializeFrom(touchState.lastResample);
Jeff Brown5912f952013-07-01 19:10:31 -0700973 touchState.lastResample.eventTime = sampleTime;
974 touchState.lastResample.idBits.clear();
975 for (size_t i = 0; i < pointerCount; i++) {
976 uint32_t id = event->getPointerId(i);
977 touchState.lastResample.idToIndex[id] = i;
978 touchState.lastResample.idBits.markBit(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800979 if (oldLastResample.hasPointerId(id) && touchState.recentCoordinatesAreIdentical(id)) {
980 // We maintain the previously resampled value for this pointer (stored in
981 // oldLastResample) when the coordinates for this pointer haven't changed since then.
982 // This way we don't introduce artificial jitter when pointers haven't actually moved.
983
984 // We know here that the coordinates for the pointer haven't changed because we
985 // would've cleared the resampled bit in rewriteMessage if they had. We can't modify
986 // lastResample in place becasue the mapping from pointer ID to index may have changed.
987 touchState.lastResample.pointers[i].copyFrom(oldLastResample.getPointerById(id));
988 continue;
989 }
990
Jeff Brown5912f952013-07-01 19:10:31 -0700991 PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
992 const PointerCoords& currentCoords = current->getPointerById(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800993 resampledCoords.copyFrom(currentCoords);
Jeff Brown5912f952013-07-01 19:10:31 -0700994 if (other->idBits.hasBit(id)
995 && shouldResampleTool(event->getToolType(i))) {
996 const PointerCoords& otherCoords = other->getPointerById(id);
Jeff Brown5912f952013-07-01 19:10:31 -0700997 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
998 lerp(currentCoords.getX(), otherCoords.getX(), alpha));
999 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
1000 lerp(currentCoords.getY(), otherCoords.getY(), alpha));
1001#if DEBUG_RESAMPLING
1002 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
1003 "other (%0.3f, %0.3f), alpha %0.3f",
1004 id, resampledCoords.getX(), resampledCoords.getY(),
1005 currentCoords.getX(), currentCoords.getY(),
1006 otherCoords.getX(), otherCoords.getY(),
1007 alpha);
1008#endif
1009 } else {
Jeff Brown5912f952013-07-01 19:10:31 -07001010#if DEBUG_RESAMPLING
1011 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
1012 id, resampledCoords.getX(), resampledCoords.getY(),
1013 currentCoords.getX(), currentCoords.getY());
1014#endif
1015 }
1016 }
1017
1018 event->addSample(sampleTime, touchState.lastResample.pointers);
1019}
1020
1021bool InputConsumer::shouldResampleTool(int32_t toolType) {
1022 return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
1023 || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
1024}
1025
1026status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
1027#if DEBUG_TRANSPORT_ACTIONS
1028 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001029 mChannel->getName().c_str(), seq, handled ? "true" : "false");
Jeff Brown5912f952013-07-01 19:10:31 -07001030#endif
1031
1032 if (!seq) {
1033 ALOGE("Attempted to send a finished signal with sequence number 0.");
1034 return BAD_VALUE;
1035 }
1036
1037 // Send finished signals for the batch sequence chain first.
1038 size_t seqChainCount = mSeqChains.size();
1039 if (seqChainCount) {
1040 uint32_t currentSeq = seq;
1041 uint32_t chainSeqs[seqChainCount];
1042 size_t chainIndex = 0;
Dan Austin1faef802015-09-22 14:28:07 -07001043 for (size_t i = seqChainCount; i > 0; ) {
1044 i--;
Jeff Brown5912f952013-07-01 19:10:31 -07001045 const SeqChain& seqChain = mSeqChains.itemAt(i);
1046 if (seqChain.seq == currentSeq) {
1047 currentSeq = seqChain.chain;
1048 chainSeqs[chainIndex++] = currentSeq;
1049 mSeqChains.removeAt(i);
1050 }
1051 }
1052 status_t status = OK;
Dan Austin1faef802015-09-22 14:28:07 -07001053 while (!status && chainIndex > 0) {
1054 chainIndex--;
Jeff Brown5912f952013-07-01 19:10:31 -07001055 status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
1056 }
1057 if (status) {
1058 // An error occurred so at least one signal was not sent, reconstruct the chain.
gaoshang9090d4f2017-05-17 14:36:46 +08001059 for (;;) {
Jeff Brown5912f952013-07-01 19:10:31 -07001060 SeqChain seqChain;
1061 seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
1062 seqChain.chain = chainSeqs[chainIndex];
1063 mSeqChains.push(seqChain);
gaoshang9090d4f2017-05-17 14:36:46 +08001064 if (!chainIndex) break;
1065 chainIndex--;
1066 }
Jeff Brown5912f952013-07-01 19:10:31 -07001067 return status;
1068 }
1069 }
1070
1071 // Send finished signal for the last message in the batch.
1072 return sendUnchainedFinishedSignal(seq, handled);
1073}
1074
1075status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
1076 InputMessage msg;
1077 msg.header.type = InputMessage::TYPE_FINISHED;
1078 msg.body.finished.seq = seq;
1079 msg.body.finished.handled = handled;
1080 return mChannel->sendMessage(&msg);
1081}
1082
1083bool InputConsumer::hasDeferredEvent() const {
1084 return mMsgDeferred;
1085}
1086
1087bool InputConsumer::hasPendingBatch() const {
1088 return !mBatches.isEmpty();
1089}
1090
1091ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
1092 for (size_t i = 0; i < mBatches.size(); i++) {
1093 const Batch& batch = mBatches.itemAt(i);
1094 const InputMessage& head = batch.samples.itemAt(0);
1095 if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
1096 return i;
1097 }
1098 }
1099 return -1;
1100}
1101
1102ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
1103 for (size_t i = 0; i < mTouchStates.size(); i++) {
1104 const TouchState& touchState = mTouchStates.itemAt(i);
1105 if (touchState.deviceId == deviceId && touchState.source == source) {
1106 return i;
1107 }
1108 }
1109 return -1;
1110}
1111
1112void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
1113 event->initialize(
1114 msg->body.key.deviceId,
1115 msg->body.key.source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001116 msg->body.key.displayId,
Jeff Brown5912f952013-07-01 19:10:31 -07001117 msg->body.key.action,
1118 msg->body.key.flags,
1119 msg->body.key.keyCode,
1120 msg->body.key.scanCode,
1121 msg->body.key.metaState,
1122 msg->body.key.repeatCount,
1123 msg->body.key.downTime,
1124 msg->body.key.eventTime);
1125}
1126
1127void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001128 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001129 PointerProperties pointerProperties[pointerCount];
1130 PointerCoords pointerCoords[pointerCount];
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001131 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -07001132 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
1133 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
1134 }
1135
Garfield Tan00f511d2019-06-12 16:55:40 -07001136 event->initialize(msg->body.motion.deviceId, msg->body.motion.source,
1137 msg->body.motion.displayId, msg->body.motion.action,
1138 msg->body.motion.actionButton, msg->body.motion.flags,
1139 msg->body.motion.edgeFlags, msg->body.motion.metaState,
1140 msg->body.motion.buttonState, msg->body.motion.classification,
1141 msg->body.motion.xOffset, msg->body.motion.yOffset,
1142 msg->body.motion.xPrecision, msg->body.motion.yPrecision,
1143 msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
1144 msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
1145 pointerProperties, pointerCoords);
Jeff Brown5912f952013-07-01 19:10:31 -07001146}
1147
1148void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001149 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001150 PointerCoords pointerCoords[pointerCount];
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001151 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -07001152 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
1153 }
1154
1155 event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
1156 event->addSample(msg->body.motion.eventTime, pointerCoords);
1157}
1158
1159bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
1160 const InputMessage& head = batch.samples.itemAt(0);
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001161 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001162 if (head.body.motion.pointerCount != pointerCount
1163 || head.body.motion.action != msg->body.motion.action) {
1164 return false;
1165 }
1166 for (size_t i = 0; i < pointerCount; i++) {
1167 if (head.body.motion.pointers[i].properties
1168 != msg->body.motion.pointers[i].properties) {
1169 return false;
1170 }
1171 }
1172 return true;
1173}
1174
1175ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
1176 size_t numSamples = batch.samples.size();
1177 size_t index = 0;
1178 while (index < numSamples
1179 && batch.samples.itemAt(index).body.motion.eventTime <= time) {
1180 index += 1;
1181 }
1182 return ssize_t(index) - 1;
1183}
1184
1185} // namespace android