blob: 7835651f119b412dbb5bab9f33a8b252e5a7d55f [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
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700230sp<InputChannel> InputChannel::create(const std::string& name, android::base::unique_fd fd) {
231 const int result = fcntl(fd, F_SETFL, O_NONBLOCK);
232 if (result != 0) {
233 LOG_ALWAYS_FATAL("channel '%s' ~ Could not make socket non-blocking: %s", name.c_str(),
234 strerror(errno));
235 return nullptr;
236 }
237 return new InputChannel(name, std::move(fd));
238}
239
240InputChannel::InputChannel(const std::string& name, android::base::unique_fd fd)
241 : mName(name), mFd(std::move(fd)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700242#if DEBUG_CHANNEL_LIFECYCLE
243 ALOGD("Input channel constructed: name='%s', fd=%d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800244 mName.c_str(), fd);
Jeff Brown5912f952013-07-01 19:10:31 -0700245#endif
Jeff Brown5912f952013-07-01 19:10:31 -0700246}
247
248InputChannel::~InputChannel() {
249#if DEBUG_CHANNEL_LIFECYCLE
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700250 ALOGD("Input channel destroyed: name='%s', fd=%d", mName.c_str(), mFd.get());
Jeff Brown5912f952013-07-01 19:10:31 -0700251#endif
Robert Carr3720ed02018-08-08 16:08:27 -0700252}
253
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800254status_t InputChannel::openInputChannelPair(const std::string& name,
Jeff Brown5912f952013-07-01 19:10:31 -0700255 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
256 int sockets[2];
257 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
258 status_t result = -errno;
259 ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800260 name.c_str(), errno);
Jeff Brown5912f952013-07-01 19:10:31 -0700261 outServerChannel.clear();
262 outClientChannel.clear();
263 return result;
264 }
265
266 int bufferSize = SOCKET_BUFFER_SIZE;
267 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
268 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
269 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
270 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
271
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700272 std::string serverChannelName = name + " (server)";
273 android::base::unique_fd serverFd(sockets[0]);
274 outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd));
Jeff Brown5912f952013-07-01 19:10:31 -0700275
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700276 std::string clientChannelName = name + " (client)";
277 android::base::unique_fd clientFd(sockets[1]);
278 outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd));
Jeff Brown5912f952013-07-01 19:10:31 -0700279 return OK;
280}
281
282status_t InputChannel::sendMessage(const InputMessage* msg) {
Siarhei Vishniakou1f7c0e42018-11-16 22:18:53 -0800283 const size_t msgLength = msg->size();
284 InputMessage cleanMsg;
285 msg->getSanitizedCopy(&cleanMsg);
Jeff Brown5912f952013-07-01 19:10:31 -0700286 ssize_t nWrite;
287 do {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700288 nWrite = ::send(mFd.get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
Jeff Brown5912f952013-07-01 19:10:31 -0700289 } while (nWrite == -1 && errno == EINTR);
290
291 if (nWrite < 0) {
292 int error = errno;
293#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800294 ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.c_str(),
Jeff Brown5912f952013-07-01 19:10:31 -0700295 msg->header.type, error);
296#endif
297 if (error == EAGAIN || error == EWOULDBLOCK) {
298 return WOULD_BLOCK;
299 }
300 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) {
301 return DEAD_OBJECT;
302 }
303 return -error;
304 }
305
306 if (size_t(nWrite) != msgLength) {
307#if DEBUG_CHANNEL_MESSAGES
308 ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800309 mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700310#endif
311 return DEAD_OBJECT;
312 }
313
314#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800315 ALOGD("channel '%s' ~ sent message of type %d", mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700316#endif
317 return OK;
318}
319
320status_t InputChannel::receiveMessage(InputMessage* msg) {
321 ssize_t nRead;
322 do {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700323 nRead = ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT);
Jeff Brown5912f952013-07-01 19:10:31 -0700324 } while (nRead == -1 && errno == EINTR);
325
326 if (nRead < 0) {
327 int error = errno;
328#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800329 ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.c_str(), errno);
Jeff Brown5912f952013-07-01 19:10:31 -0700330#endif
331 if (error == EAGAIN || error == EWOULDBLOCK) {
332 return WOULD_BLOCK;
333 }
334 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
335 return DEAD_OBJECT;
336 }
337 return -error;
338 }
339
340 if (nRead == 0) { // check for EOF
341#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800342 ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700343#endif
344 return DEAD_OBJECT;
345 }
346
347 if (!msg->isValid(nRead)) {
348#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800349 ALOGD("channel '%s' ~ received invalid message", mName.c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700350#endif
351 return BAD_VALUE;
352 }
353
354#if DEBUG_CHANNEL_MESSAGES
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800355 ALOGD("channel '%s' ~ received message of type %d", mName.c_str(), msg->header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700356#endif
357 return OK;
358}
359
360sp<InputChannel> InputChannel::dup() const {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700361 android::base::unique_fd newFd(::dup(getFd()));
362 if (!newFd.ok()) {
363 ALOGE("Could not duplicate fd %i for channel %s: %s", getFd(), mName.c_str(),
364 strerror(errno));
365 return nullptr;
366 }
367 return InputChannel::create(mName, std::move(newFd));
Jeff Brown5912f952013-07-01 19:10:31 -0700368}
369
Robert Carr3720ed02018-08-08 16:08:27 -0700370status_t InputChannel::write(Parcel& out) const {
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700371 status_t s = out.writeCString(getName().c_str());
Robert Carr3720ed02018-08-08 16:08:27 -0700372 if (s != OK) {
373 return s;
374 }
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700375
Robert Carr803535b2018-08-02 16:38:15 -0700376 s = out.writeStrongBinder(mToken);
377 if (s != OK) {
378 return s;
379 }
Robert Carr3720ed02018-08-08 16:08:27 -0700380
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700381 s = out.writeUniqueFileDescriptor(mFd);
Robert Carr3720ed02018-08-08 16:08:27 -0700382 return s;
383}
384
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700385sp<InputChannel> InputChannel::read(const Parcel& from) {
386 std::string name = from.readCString();
387 sp<IBinder> token = from.readStrongBinder();
388 android::base::unique_fd rawFd;
389 status_t fdResult = from.readUniqueFileDescriptor(&rawFd);
390 if (fdResult != OK) {
391 return nullptr;
Robert Carr3720ed02018-08-08 16:08:27 -0700392 }
393
Josh Gao2ccbe3a2019-08-09 14:35:36 -0700394 sp<InputChannel> channel = InputChannel::create(name, std::move(rawFd));
395 if (channel != nullptr) {
396 channel->setToken(token);
397 }
398 return channel;
Robert Carr3720ed02018-08-08 16:08:27 -0700399}
400
Robert Carr803535b2018-08-02 16:38:15 -0700401sp<IBinder> InputChannel::getToken() const {
402 return mToken;
403}
404
405void InputChannel::setToken(const sp<IBinder>& token) {
406 if (mToken != nullptr) {
407 ALOGE("Assigning InputChannel (%s) a second handle?", mName.c_str());
408 }
409 mToken = token;
410}
411
Jeff Brown5912f952013-07-01 19:10:31 -0700412// --- InputPublisher ---
413
414InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
415 mChannel(channel) {
416}
417
418InputPublisher::~InputPublisher() {
419}
420
421status_t InputPublisher::publishKeyEvent(
422 uint32_t seq,
423 int32_t deviceId,
424 int32_t source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100425 int32_t displayId,
Jeff Brown5912f952013-07-01 19:10:31 -0700426 int32_t action,
427 int32_t flags,
428 int32_t keyCode,
429 int32_t scanCode,
430 int32_t metaState,
431 int32_t repeatCount,
432 nsecs_t downTime,
433 nsecs_t eventTime) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000434 if (ATRACE_ENABLED()) {
435 std::string message = StringPrintf("publishKeyEvent(inputChannel=%s, keyCode=%" PRId32 ")",
436 mChannel->getName().c_str(), keyCode);
437 ATRACE_NAME(message.c_str());
438 }
Jeff Brown5912f952013-07-01 19:10:31 -0700439#if DEBUG_TRANSPORT_ACTIONS
440 ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
441 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700442 "downTime=%" PRId64 ", eventTime=%" PRId64,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800443 mChannel->getName().c_str(), seq,
Jeff Brown5912f952013-07-01 19:10:31 -0700444 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
445 downTime, eventTime);
446#endif
447
448 if (!seq) {
449 ALOGE("Attempted to publish a key event with sequence number 0.");
450 return BAD_VALUE;
451 }
452
453 InputMessage msg;
454 msg.header.type = InputMessage::TYPE_KEY;
455 msg.body.key.seq = seq;
456 msg.body.key.deviceId = deviceId;
457 msg.body.key.source = source;
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +0100458 msg.body.key.displayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700459 msg.body.key.action = action;
460 msg.body.key.flags = flags;
461 msg.body.key.keyCode = keyCode;
462 msg.body.key.scanCode = scanCode;
463 msg.body.key.metaState = metaState;
464 msg.body.key.repeatCount = repeatCount;
465 msg.body.key.downTime = downTime;
466 msg.body.key.eventTime = eventTime;
467 return mChannel->sendMessage(&msg);
468}
469
470status_t InputPublisher::publishMotionEvent(
Garfield Tan00f511d2019-06-12 16:55:40 -0700471 uint32_t seq, int32_t deviceId, int32_t source, int32_t displayId, int32_t action,
472 int32_t actionButton, int32_t flags, int32_t edgeFlags, int32_t metaState,
473 int32_t buttonState, MotionClassification classification, float xOffset, float yOffset,
474 float xPrecision, float yPrecision, float xCursorPosition, float yCursorPosition,
475 nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount,
476 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
Michael Wright3dd60e22019-03-27 22:06:44 +0000477 if (ATRACE_ENABLED()) {
478 std::string message = StringPrintf(
479 "publishMotionEvent(inputChannel=%s, action=%" PRId32 ")",
480 mChannel->getName().c_str(), action);
481 ATRACE_NAME(message.c_str());
482 }
Jeff Brown5912f952013-07-01 19:10:31 -0700483#if DEBUG_TRANSPORT_ACTIONS
484 ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800485 "displayId=%" PRId32 ", "
Michael Wright7b159c92015-05-14 14:48:03 +0100486 "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800487 "metaState=0x%x, buttonState=0x%x, classification=%s, xOffset=%f, yOffset=%f, "
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700488 "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", "
Michael Wright63ff3a82014-06-10 13:03:17 -0700489 "pointerCount=%" PRIu32,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800490 mChannel->getName().c_str(), seq,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800491 deviceId, source, displayId, action, actionButton, flags, edgeFlags, metaState,
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800492 buttonState, motionClassificationToString(classification),
493 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
Jeff Brown5912f952013-07-01 19:10:31 -0700494#endif
495
496 if (!seq) {
497 ALOGE("Attempted to publish a motion event with sequence number 0.");
498 return BAD_VALUE;
499 }
500
501 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Michael Wright63ff3a82014-06-10 13:03:17 -0700502 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %" PRIu32 ".",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800503 mChannel->getName().c_str(), pointerCount);
Jeff Brown5912f952013-07-01 19:10:31 -0700504 return BAD_VALUE;
505 }
506
507 InputMessage msg;
508 msg.header.type = InputMessage::TYPE_MOTION;
509 msg.body.motion.seq = seq;
510 msg.body.motion.deviceId = deviceId;
511 msg.body.motion.source = source;
Tarandeep Singh58641502017-07-31 10:51:54 -0700512 msg.body.motion.displayId = displayId;
Jeff Brown5912f952013-07-01 19:10:31 -0700513 msg.body.motion.action = action;
Michael Wright7b159c92015-05-14 14:48:03 +0100514 msg.body.motion.actionButton = actionButton;
Jeff Brown5912f952013-07-01 19:10:31 -0700515 msg.body.motion.flags = flags;
516 msg.body.motion.edgeFlags = edgeFlags;
517 msg.body.motion.metaState = metaState;
518 msg.body.motion.buttonState = buttonState;
Siarhei Vishniakou16a2e302019-01-14 19:21:45 -0800519 msg.body.motion.classification = classification;
Jeff Brown5912f952013-07-01 19:10:31 -0700520 msg.body.motion.xOffset = xOffset;
521 msg.body.motion.yOffset = yOffset;
522 msg.body.motion.xPrecision = xPrecision;
523 msg.body.motion.yPrecision = yPrecision;
Garfield Tan00f511d2019-06-12 16:55:40 -0700524 msg.body.motion.xCursorPosition = xCursorPosition;
525 msg.body.motion.yCursorPosition = yCursorPosition;
Jeff Brown5912f952013-07-01 19:10:31 -0700526 msg.body.motion.downTime = downTime;
527 msg.body.motion.eventTime = eventTime;
528 msg.body.motion.pointerCount = pointerCount;
Narayan Kamathbc6001b2014-05-02 17:53:33 +0100529 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -0700530 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
531 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
532 }
Atif Niyaz3d3fa522019-07-25 11:12:39 -0700533
534 if (source == AINPUT_SOURCE_TOUCHSCREEN) {
535 reportTouchEventForStatistics(eventTime);
536 }
Jeff Brown5912f952013-07-01 19:10:31 -0700537 return mChannel->sendMessage(&msg);
538}
539
540status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
541#if DEBUG_TRANSPORT_ACTIONS
542 ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800543 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700544#endif
545
546 InputMessage msg;
547 status_t result = mChannel->receiveMessage(&msg);
548 if (result) {
549 *outSeq = 0;
550 *outHandled = false;
551 return result;
552 }
553 if (msg.header.type != InputMessage::TYPE_FINISHED) {
554 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800555 mChannel->getName().c_str(), msg.header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700556 return UNKNOWN_ERROR;
557 }
558 *outSeq = msg.body.finished.seq;
559 *outHandled = msg.body.finished.handled;
560 return OK;
561}
562
Atif Niyaz3d3fa522019-07-25 11:12:39 -0700563void InputPublisher::reportTouchEventForStatistics(nsecs_t evdevTime) {
564 if (mTouchStatistics.shouldReport()) {
565 android::util::stats_write(android::util::TOUCH_EVENT_REPORTED, mTouchStatistics.getMin(),
566 mTouchStatistics.getMax(), mTouchStatistics.getMean(),
567 mTouchStatistics.getStDev(), mTouchStatistics.getCount());
568 mTouchStatistics.reset();
569 }
570 nsecs_t latency = nanoseconds_to_microseconds(systemTime(CLOCK_MONOTONIC) - evdevTime);
571 mTouchStatistics.addValue(latency);
572}
573
Jeff Brown5912f952013-07-01 19:10:31 -0700574// --- InputConsumer ---
575
576InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
577 mResampleTouch(isTouchResamplingEnabled()),
578 mChannel(channel), mMsgDeferred(false) {
579}
580
581InputConsumer::~InputConsumer() {
582}
583
584bool InputConsumer::isTouchResamplingEnabled() {
Siarhei Vishniakoub5433e92019-02-21 09:27:39 -0600585 return property_get_bool(PROPERTY_RESAMPLING_ENABLED, true);
Jeff Brown5912f952013-07-01 19:10:31 -0700586}
587
588status_t InputConsumer::consume(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800589 bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700590#if DEBUG_TRANSPORT_ACTIONS
Siarhei Vishniakou5d83f602017-09-12 12:40:29 -0700591 ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%" PRId64,
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800592 mChannel->getName().c_str(), consumeBatches ? "true" : "false", frameTime);
Jeff Brown5912f952013-07-01 19:10:31 -0700593#endif
594
595 *outSeq = 0;
Yi Kong5bed83b2018-07-17 12:53:47 -0700596 *outEvent = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700597
598 // Fetch the next input message.
599 // Loop until an event can be returned or no additional events are received.
600 while (!*outEvent) {
601 if (mMsgDeferred) {
602 // mMsg contains a valid input message from the previous call to consume
603 // that has not yet been processed.
604 mMsgDeferred = false;
605 } else {
606 // Receive a fresh message.
607 status_t result = mChannel->receiveMessage(&mMsg);
608 if (result) {
609 // Consume the next batched event unless batches are being held for later.
610 if (consumeBatches || result != WOULD_BLOCK) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800611 result = consumeBatch(factory, frameTime, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700612 if (*outEvent) {
613#if DEBUG_TRANSPORT_ACTIONS
614 ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800615 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700616#endif
617 break;
618 }
619 }
620 return result;
621 }
622 }
623
624 switch (mMsg.header.type) {
625 case InputMessage::TYPE_KEY: {
626 KeyEvent* keyEvent = factory->createKeyEvent();
627 if (!keyEvent) return NO_MEMORY;
628
629 initializeKeyEvent(keyEvent, &mMsg);
630 *outSeq = mMsg.body.key.seq;
631 *outEvent = keyEvent;
632#if DEBUG_TRANSPORT_ACTIONS
633 ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800634 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700635#endif
636 break;
637 }
638
gaoshange3e11a72017-08-08 16:11:31 +0800639 case InputMessage::TYPE_MOTION: {
Jeff Brown5912f952013-07-01 19:10:31 -0700640 ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
641 if (batchIndex >= 0) {
642 Batch& batch = mBatches.editItemAt(batchIndex);
643 if (canAddSample(batch, &mMsg)) {
644 batch.samples.push(mMsg);
645#if DEBUG_TRANSPORT_ACTIONS
646 ALOGD("channel '%s' consumer ~ appended to batch event",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800647 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700648#endif
649 break;
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800650 } else if (isPointerEvent(mMsg.body.motion.source) &&
651 mMsg.body.motion.action == AMOTION_EVENT_ACTION_CANCEL) {
652 // No need to process events that we are going to cancel anyways
653 const size_t count = batch.samples.size();
654 for (size_t i = 0; i < count; i++) {
655 const InputMessage& msg = batch.samples.itemAt(i);
656 sendFinishedSignal(msg.body.motion.seq, false);
657 }
658 batch.samples.removeItemsAt(0, count);
659 mBatches.removeAt(batchIndex);
Jeff Brown5912f952013-07-01 19:10:31 -0700660 } else {
661 // We cannot append to the batch in progress, so we need to consume
662 // the previous batch right now and defer the new message until later.
663 mMsgDeferred = true;
664 status_t result = consumeSamples(factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800665 batch, batch.samples.size(), outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700666 mBatches.removeAt(batchIndex);
667 if (result) {
668 return result;
669 }
670#if DEBUG_TRANSPORT_ACTIONS
671 ALOGD("channel '%s' consumer ~ consumed batch event and "
672 "deferred current event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800673 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700674#endif
675 break;
676 }
677 }
678
679 // Start a new batch if needed.
680 if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
681 || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
682 mBatches.push();
683 Batch& batch = mBatches.editTop();
684 batch.samples.push(mMsg);
685#if DEBUG_TRANSPORT_ACTIONS
686 ALOGD("channel '%s' consumer ~ started batch event",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800687 mChannel->getName().c_str());
Jeff Brown5912f952013-07-01 19:10:31 -0700688#endif
689 break;
690 }
691
692 MotionEvent* motionEvent = factory->createMotionEvent();
693 if (! motionEvent) return NO_MEMORY;
694
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100695 updateTouchState(mMsg);
Jeff Brown5912f952013-07-01 19:10:31 -0700696 initializeMotionEvent(motionEvent, &mMsg);
697 *outSeq = mMsg.body.motion.seq;
698 *outEvent = motionEvent;
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800699
Jeff Brown5912f952013-07-01 19:10:31 -0700700#if DEBUG_TRANSPORT_ACTIONS
701 ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800702 mChannel->getName().c_str(), *outSeq);
Jeff Brown5912f952013-07-01 19:10:31 -0700703#endif
704 break;
705 }
706
707 default:
708 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -0800709 mChannel->getName().c_str(), mMsg.header.type);
Jeff Brown5912f952013-07-01 19:10:31 -0700710 return UNKNOWN_ERROR;
711 }
712 }
713 return OK;
714}
715
716status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800717 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700718 status_t result;
Dan Austin1faef802015-09-22 14:28:07 -0700719 for (size_t i = mBatches.size(); i > 0; ) {
720 i--;
Jeff Brown5912f952013-07-01 19:10:31 -0700721 Batch& batch = mBatches.editItemAt(i);
Michael Wright32232172013-10-21 12:05:22 -0700722 if (frameTime < 0) {
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800723 result = consumeSamples(factory, batch, batch.samples.size(), outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700724 mBatches.removeAt(i);
725 return result;
726 }
727
Michael Wright32232172013-10-21 12:05:22 -0700728 nsecs_t sampleTime = frameTime;
729 if (mResampleTouch) {
730 sampleTime -= RESAMPLE_LATENCY;
731 }
Jeff Brown5912f952013-07-01 19:10:31 -0700732 ssize_t split = findSampleNoLaterThan(batch, sampleTime);
733 if (split < 0) {
734 continue;
735 }
736
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800737 result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
Jeff Brown5912f952013-07-01 19:10:31 -0700738 const InputMessage* next;
739 if (batch.samples.isEmpty()) {
740 mBatches.removeAt(i);
Yi Kong5bed83b2018-07-17 12:53:47 -0700741 next = nullptr;
Jeff Brown5912f952013-07-01 19:10:31 -0700742 } else {
743 next = &batch.samples.itemAt(0);
744 }
Michael Wright32232172013-10-21 12:05:22 -0700745 if (!result && mResampleTouch) {
Jeff Brown5912f952013-07-01 19:10:31 -0700746 resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
747 }
748 return result;
749 }
750
751 return WOULD_BLOCK;
752}
753
754status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
Siarhei Vishniakou777a10b2018-01-31 16:45:06 -0800755 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown5912f952013-07-01 19:10:31 -0700756 MotionEvent* motionEvent = factory->createMotionEvent();
757 if (! motionEvent) return NO_MEMORY;
758
759 uint32_t chain = 0;
760 for (size_t i = 0; i < count; i++) {
761 InputMessage& msg = batch.samples.editItemAt(i);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100762 updateTouchState(msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700763 if (i) {
764 SeqChain seqChain;
765 seqChain.seq = msg.body.motion.seq;
766 seqChain.chain = chain;
767 mSeqChains.push(seqChain);
768 addSample(motionEvent, &msg);
769 } else {
770 initializeMotionEvent(motionEvent, &msg);
771 }
772 chain = msg.body.motion.seq;
773 }
774 batch.samples.removeItemsAt(0, count);
775
776 *outSeq = chain;
777 *outEvent = motionEvent;
778 return OK;
779}
780
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100781void InputConsumer::updateTouchState(InputMessage& msg) {
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800782 if (!mResampleTouch || !isPointerEvent(msg.body.motion.source)) {
Jeff Brown5912f952013-07-01 19:10:31 -0700783 return;
784 }
785
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100786 int32_t deviceId = msg.body.motion.deviceId;
787 int32_t source = msg.body.motion.source;
Jeff Brown5912f952013-07-01 19:10:31 -0700788
789 // Update the touch state history to incorporate the new input message.
790 // If the message is in the past relative to the most recently produced resampled
791 // touch, then use the resampled time and coordinates instead.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100792 switch (msg.body.motion.action & AMOTION_EVENT_ACTION_MASK) {
Jeff Brown5912f952013-07-01 19:10:31 -0700793 case AMOTION_EVENT_ACTION_DOWN: {
794 ssize_t index = findTouchState(deviceId, source);
795 if (index < 0) {
796 mTouchStates.push();
797 index = mTouchStates.size() - 1;
798 }
799 TouchState& touchState = mTouchStates.editItemAt(index);
800 touchState.initialize(deviceId, source);
801 touchState.addHistory(msg);
802 break;
803 }
804
805 case AMOTION_EVENT_ACTION_MOVE: {
806 ssize_t index = findTouchState(deviceId, source);
807 if (index >= 0) {
808 TouchState& touchState = mTouchStates.editItemAt(index);
809 touchState.addHistory(msg);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800810 rewriteMessage(touchState, msg);
Jeff Brown5912f952013-07-01 19:10:31 -0700811 }
812 break;
813 }
814
815 case AMOTION_EVENT_ACTION_POINTER_DOWN: {
816 ssize_t index = findTouchState(deviceId, source);
817 if (index >= 0) {
818 TouchState& touchState = mTouchStates.editItemAt(index);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100819 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -0700820 rewriteMessage(touchState, msg);
821 }
822 break;
823 }
824
825 case AMOTION_EVENT_ACTION_POINTER_UP: {
826 ssize_t index = findTouchState(deviceId, source);
827 if (index >= 0) {
828 TouchState& touchState = mTouchStates.editItemAt(index);
829 rewriteMessage(touchState, msg);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100830 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
Jeff Brown5912f952013-07-01 19:10:31 -0700831 }
832 break;
833 }
834
835 case AMOTION_EVENT_ACTION_SCROLL: {
836 ssize_t index = findTouchState(deviceId, source);
837 if (index >= 0) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800838 TouchState& touchState = mTouchStates.editItemAt(index);
Jeff Brown5912f952013-07-01 19:10:31 -0700839 rewriteMessage(touchState, msg);
840 }
841 break;
842 }
843
844 case AMOTION_EVENT_ACTION_UP:
845 case AMOTION_EVENT_ACTION_CANCEL: {
846 ssize_t index = findTouchState(deviceId, source);
847 if (index >= 0) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800848 TouchState& touchState = mTouchStates.editItemAt(index);
Jeff Brown5912f952013-07-01 19:10:31 -0700849 rewriteMessage(touchState, msg);
850 mTouchStates.removeAt(index);
851 }
852 break;
853 }
854 }
855}
856
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800857/**
858 * Replace the coordinates in msg with the coordinates in lastResample, if necessary.
859 *
860 * If lastResample is no longer valid for a specific pointer (i.e. the lastResample time
861 * is in the past relative to msg and the past two events do not contain identical coordinates),
862 * then invalidate the lastResample data for that pointer.
863 * If the two past events have identical coordinates, then lastResample data for that pointer will
864 * remain valid, and will be used to replace these coordinates. Thus, if a certain coordinate x0 is
865 * resampled to the new value x1, then x1 will always be used to replace x0 until some new value
866 * not equal to x0 is received.
867 */
868void InputConsumer::rewriteMessage(TouchState& state, InputMessage& msg) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100869 nsecs_t eventTime = msg.body.motion.eventTime;
870 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
871 uint32_t id = msg.body.motion.pointers[i].properties.id;
Jeff Brown5912f952013-07-01 19:10:31 -0700872 if (state.lastResample.idBits.hasBit(id)) {
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100873 if (eventTime < state.lastResample.eventTime ||
874 state.recentCoordinatesAreIdentical(id)) {
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800875 PointerCoords& msgCoords = msg.body.motion.pointers[i].coords;
876 const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
Jeff Brown5912f952013-07-01 19:10:31 -0700877#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100878 ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
879 resampleCoords.getX(), resampleCoords.getY(),
880 msgCoords.getX(), msgCoords.getY());
Jeff Brown5912f952013-07-01 19:10:31 -0700881#endif
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800882 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
883 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
884 } else {
885 state.lastResample.idBits.clearBit(id);
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100886 }
Jeff Brown5912f952013-07-01 19:10:31 -0700887 }
888 }
889}
890
891void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
892 const InputMessage* next) {
893 if (!mResampleTouch
Siarhei Vishniakou128eab12019-05-23 10:25:59 +0800894 || !(isPointerEvent(event->getSource()))
Jeff Brown5912f952013-07-01 19:10:31 -0700895 || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
896 return;
897 }
898
899 ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
900 if (index < 0) {
901#if DEBUG_RESAMPLING
902 ALOGD("Not resampled, no touch state for device.");
903#endif
904 return;
905 }
906
907 TouchState& touchState = mTouchStates.editItemAt(index);
908 if (touchState.historySize < 1) {
909#if DEBUG_RESAMPLING
910 ALOGD("Not resampled, no history for device.");
911#endif
912 return;
913 }
914
915 // Ensure that the current sample has all of the pointers that need to be reported.
916 const History* current = touchState.getHistory(0);
917 size_t pointerCount = event->getPointerCount();
918 for (size_t i = 0; i < pointerCount; i++) {
919 uint32_t id = event->getPointerId(i);
920 if (!current->idBits.hasBit(id)) {
921#if DEBUG_RESAMPLING
922 ALOGD("Not resampled, missing id %d", id);
923#endif
924 return;
925 }
926 }
927
928 // Find the data to use for resampling.
929 const History* other;
930 History future;
931 float alpha;
932 if (next) {
933 // Interpolate between current sample and future sample.
934 // So current->eventTime <= sampleTime <= future.eventTime.
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100935 future.initializeFrom(*next);
Jeff Brown5912f952013-07-01 19:10:31 -0700936 other = &future;
937 nsecs_t delta = future.eventTime - current->eventTime;
938 if (delta < RESAMPLE_MIN_DELTA) {
939#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100940 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
Jeff Brown5912f952013-07-01 19:10:31 -0700941#endif
942 return;
943 }
944 alpha = float(sampleTime - current->eventTime) / delta;
945 } else if (touchState.historySize >= 2) {
946 // Extrapolate future sample using current sample and past sample.
947 // So other->eventTime <= current->eventTime <= sampleTime.
948 other = touchState.getHistory(1);
949 nsecs_t delta = current->eventTime - other->eventTime;
950 if (delta < RESAMPLE_MIN_DELTA) {
951#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100952 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
Andrew de los Reyesde18f6c2015-10-01 15:57:25 -0700953#endif
954 return;
955 } else if (delta > RESAMPLE_MAX_DELTA) {
956#if DEBUG_RESAMPLING
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100957 ALOGD("Not resampled, delta time is too large: %" PRId64 " ns.", delta);
Jeff Brown5912f952013-07-01 19:10:31 -0700958#endif
959 return;
960 }
961 nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
962 if (sampleTime > maxPredict) {
963#if DEBUG_RESAMPLING
964 ALOGD("Sample time is too far in the future, adjusting prediction "
Siarhei Vishniakou0aeec072017-06-12 15:01:41 +0100965 "from %" PRId64 " to %" PRId64 " ns.",
Jeff Brown5912f952013-07-01 19:10:31 -0700966 sampleTime - current->eventTime, maxPredict - current->eventTime);
967#endif
968 sampleTime = maxPredict;
969 }
970 alpha = float(current->eventTime - sampleTime) / delta;
971 } else {
972#if DEBUG_RESAMPLING
973 ALOGD("Not resampled, insufficient data.");
974#endif
975 return;
976 }
977
978 // Resample touch coordinates.
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800979 History oldLastResample;
980 oldLastResample.initializeFrom(touchState.lastResample);
Jeff Brown5912f952013-07-01 19:10:31 -0700981 touchState.lastResample.eventTime = sampleTime;
982 touchState.lastResample.idBits.clear();
983 for (size_t i = 0; i < pointerCount; i++) {
984 uint32_t id = event->getPointerId(i);
985 touchState.lastResample.idToIndex[id] = i;
986 touchState.lastResample.idBits.markBit(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -0800987 if (oldLastResample.hasPointerId(id) && touchState.recentCoordinatesAreIdentical(id)) {
988 // We maintain the previously resampled value for this pointer (stored in
989 // oldLastResample) when the coordinates for this pointer haven't changed since then.
990 // This way we don't introduce artificial jitter when pointers haven't actually moved.
991
992 // We know here that the coordinates for the pointer haven't changed because we
993 // would've cleared the resampled bit in rewriteMessage if they had. We can't modify
994 // lastResample in place becasue the mapping from pointer ID to index may have changed.
995 touchState.lastResample.pointers[i].copyFrom(oldLastResample.getPointerById(id));
996 continue;
997 }
998
Jeff Brown5912f952013-07-01 19:10:31 -0700999 PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
1000 const PointerCoords& currentCoords = current->getPointerById(id);
Siarhei Vishniakou56c9ae12017-11-06 21:16:47 -08001001 resampledCoords.copyFrom(currentCoords);
Jeff Brown5912f952013-07-01 19:10:31 -07001002 if (other->idBits.hasBit(id)
1003 && shouldResampleTool(event->getToolType(i))) {
1004 const PointerCoords& otherCoords = other->getPointerById(id);
Jeff Brown5912f952013-07-01 19:10:31 -07001005 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
1006 lerp(currentCoords.getX(), otherCoords.getX(), alpha));
1007 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
1008 lerp(currentCoords.getY(), otherCoords.getY(), alpha));
1009#if DEBUG_RESAMPLING
1010 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
1011 "other (%0.3f, %0.3f), alpha %0.3f",
1012 id, resampledCoords.getX(), resampledCoords.getY(),
1013 currentCoords.getX(), currentCoords.getY(),
1014 otherCoords.getX(), otherCoords.getY(),
1015 alpha);
1016#endif
1017 } else {
Jeff Brown5912f952013-07-01 19:10:31 -07001018#if DEBUG_RESAMPLING
1019 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
1020 id, resampledCoords.getX(), resampledCoords.getY(),
1021 currentCoords.getX(), currentCoords.getY());
1022#endif
1023 }
1024 }
1025
1026 event->addSample(sampleTime, touchState.lastResample.pointers);
1027}
1028
1029bool InputConsumer::shouldResampleTool(int32_t toolType) {
1030 return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
1031 || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
1032}
1033
1034status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
1035#if DEBUG_TRANSPORT_ACTIONS
1036 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
Siarhei Vishniakouf93fcf42017-11-22 16:00:14 -08001037 mChannel->getName().c_str(), seq, handled ? "true" : "false");
Jeff Brown5912f952013-07-01 19:10:31 -07001038#endif
1039
1040 if (!seq) {
1041 ALOGE("Attempted to send a finished signal with sequence number 0.");
1042 return BAD_VALUE;
1043 }
1044
1045 // Send finished signals for the batch sequence chain first.
1046 size_t seqChainCount = mSeqChains.size();
1047 if (seqChainCount) {
1048 uint32_t currentSeq = seq;
1049 uint32_t chainSeqs[seqChainCount];
1050 size_t chainIndex = 0;
Dan Austin1faef802015-09-22 14:28:07 -07001051 for (size_t i = seqChainCount; i > 0; ) {
1052 i--;
Jeff Brown5912f952013-07-01 19:10:31 -07001053 const SeqChain& seqChain = mSeqChains.itemAt(i);
1054 if (seqChain.seq == currentSeq) {
1055 currentSeq = seqChain.chain;
1056 chainSeqs[chainIndex++] = currentSeq;
1057 mSeqChains.removeAt(i);
1058 }
1059 }
1060 status_t status = OK;
Dan Austin1faef802015-09-22 14:28:07 -07001061 while (!status && chainIndex > 0) {
1062 chainIndex--;
Jeff Brown5912f952013-07-01 19:10:31 -07001063 status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
1064 }
1065 if (status) {
1066 // An error occurred so at least one signal was not sent, reconstruct the chain.
gaoshang9090d4f2017-05-17 14:36:46 +08001067 for (;;) {
Jeff Brown5912f952013-07-01 19:10:31 -07001068 SeqChain seqChain;
1069 seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
1070 seqChain.chain = chainSeqs[chainIndex];
1071 mSeqChains.push(seqChain);
gaoshang9090d4f2017-05-17 14:36:46 +08001072 if (!chainIndex) break;
1073 chainIndex--;
1074 }
Jeff Brown5912f952013-07-01 19:10:31 -07001075 return status;
1076 }
1077 }
1078
1079 // Send finished signal for the last message in the batch.
1080 return sendUnchainedFinishedSignal(seq, handled);
1081}
1082
1083status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
1084 InputMessage msg;
1085 msg.header.type = InputMessage::TYPE_FINISHED;
1086 msg.body.finished.seq = seq;
1087 msg.body.finished.handled = handled;
1088 return mChannel->sendMessage(&msg);
1089}
1090
1091bool InputConsumer::hasDeferredEvent() const {
1092 return mMsgDeferred;
1093}
1094
1095bool InputConsumer::hasPendingBatch() const {
1096 return !mBatches.isEmpty();
1097}
1098
1099ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
1100 for (size_t i = 0; i < mBatches.size(); i++) {
1101 const Batch& batch = mBatches.itemAt(i);
1102 const InputMessage& head = batch.samples.itemAt(0);
1103 if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
1104 return i;
1105 }
1106 }
1107 return -1;
1108}
1109
1110ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
1111 for (size_t i = 0; i < mTouchStates.size(); i++) {
1112 const TouchState& touchState = mTouchStates.itemAt(i);
1113 if (touchState.deviceId == deviceId && touchState.source == source) {
1114 return i;
1115 }
1116 }
1117 return -1;
1118}
1119
1120void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
1121 event->initialize(
1122 msg->body.key.deviceId,
1123 msg->body.key.source,
Siarhei Vishniakoua62a8dd2018-06-08 21:17:33 +01001124 msg->body.key.displayId,
Jeff Brown5912f952013-07-01 19:10:31 -07001125 msg->body.key.action,
1126 msg->body.key.flags,
1127 msg->body.key.keyCode,
1128 msg->body.key.scanCode,
1129 msg->body.key.metaState,
1130 msg->body.key.repeatCount,
1131 msg->body.key.downTime,
1132 msg->body.key.eventTime);
1133}
1134
1135void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001136 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001137 PointerProperties pointerProperties[pointerCount];
1138 PointerCoords pointerCoords[pointerCount];
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001139 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -07001140 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
1141 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
1142 }
1143
Garfield Tan00f511d2019-06-12 16:55:40 -07001144 event->initialize(msg->body.motion.deviceId, msg->body.motion.source,
1145 msg->body.motion.displayId, msg->body.motion.action,
1146 msg->body.motion.actionButton, msg->body.motion.flags,
1147 msg->body.motion.edgeFlags, msg->body.motion.metaState,
1148 msg->body.motion.buttonState, msg->body.motion.classification,
1149 msg->body.motion.xOffset, msg->body.motion.yOffset,
1150 msg->body.motion.xPrecision, msg->body.motion.yPrecision,
1151 msg->body.motion.xCursorPosition, msg->body.motion.yCursorPosition,
1152 msg->body.motion.downTime, msg->body.motion.eventTime, pointerCount,
1153 pointerProperties, pointerCoords);
Jeff Brown5912f952013-07-01 19:10:31 -07001154}
1155
1156void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001157 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001158 PointerCoords pointerCoords[pointerCount];
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001159 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown5912f952013-07-01 19:10:31 -07001160 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
1161 }
1162
1163 event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
1164 event->addSample(msg->body.motion.eventTime, pointerCoords);
1165}
1166
1167bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
1168 const InputMessage& head = batch.samples.itemAt(0);
Narayan Kamathbc6001b2014-05-02 17:53:33 +01001169 uint32_t pointerCount = msg->body.motion.pointerCount;
Jeff Brown5912f952013-07-01 19:10:31 -07001170 if (head.body.motion.pointerCount != pointerCount
1171 || head.body.motion.action != msg->body.motion.action) {
1172 return false;
1173 }
1174 for (size_t i = 0; i < pointerCount; i++) {
1175 if (head.body.motion.pointers[i].properties
1176 != msg->body.motion.pointers[i].properties) {
1177 return false;
1178 }
1179 }
1180 return true;
1181}
1182
1183ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
1184 size_t numSamples = batch.samples.size();
1185 size_t index = 0;
1186 while (index < numSamples
1187 && batch.samples.itemAt(index).body.motion.eventTime <= time) {
1188 index += 1;
1189 }
1190 return ssize_t(index) - 1;
1191}
1192
1193} // namespace android