blob: 9a4182c2b10d121bbf9840e93acdd3acf50dd939 [file] [log] [blame]
Jeff Brown46b9ac0a2010-04-22 18:58:52 -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
Jeff Browncbee6d62012-02-03 20:11:27 -080010// Log debug messages about channel messages (send message, receive message)
11#define DEBUG_CHANNEL_MESSAGES 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070012
13// Log debug messages whenever InputChannel objects are created/destroyed
Jeff Brown5c225b12010-06-16 01:53:36 -070014#define DEBUG_CHANNEL_LIFECYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070015
Jeff Browncbee6d62012-02-03 20:11:27 -080016// Log debug messages about transport actions
Jeff Brown072ec962012-02-07 14:46:57 -080017#define DEBUG_TRANSPORT_ACTIONS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070018
Jeff Brown771526c2012-04-27 15:13:25 -070019// Log debug messages about touch event resampling
20#define DEBUG_RESAMPLING 0
21
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070022
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070023#include <cutils/log.h>
24#include <errno.h>
25#include <fcntl.h>
Mathias Agopianb93a03f82012-02-17 15:34:57 -080026#include <androidfw/InputTransport.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070027#include <unistd.h>
Jeff Browncbee6d62012-02-03 20:11:27 -080028#include <sys/types.h>
29#include <sys/socket.h>
Jeff Brown771526c2012-04-27 15:13:25 -070030#include <math.h>
Jeff Browncbee6d62012-02-03 20:11:27 -080031
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070032
33namespace android {
34
Jeff Brownd1c48a02012-02-06 19:12:47 -080035// Socket buffer size. The default is typically about 128KB, which is much larger than
36// we really need. So we make it smaller. It just needs to be big enough to hold
37// a few dozen large multi-finger motion events in the case where an application gets
38// behind processing touches.
39static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
40
Jeff Brown771526c2012-04-27 15:13:25 -070041// Nanoseconds per milliseconds.
42static const nsecs_t NANOS_PER_MS = 1000000;
43
44// Latency added during resampling. A few milliseconds doesn't hurt much but
45// reduces the impact of mispredicted touch positions.
46static const nsecs_t RESAMPLE_LATENCY = 4 * NANOS_PER_MS;
47
48// Minimum time difference between consecutive samples before attempting to resample.
49static const nsecs_t RESAMPLE_MIN_DELTA = 1 * NANOS_PER_MS;
50
51// Maximum linear interpolation scale value. The larger this is, the more error may
52// potentially be introduced.
53static const float RESAMPLE_MAX_ALPHA = 2.0f;
54
Jeff Brownd1c48a02012-02-06 19:12:47 -080055
Jeff Browncbee6d62012-02-03 20:11:27 -080056// --- InputMessage ---
Jeff Brown4e91a182011-04-07 11:38:09 -070057
Jeff Browncbee6d62012-02-03 20:11:27 -080058bool InputMessage::isValid(size_t actualSize) const {
59 if (size() == actualSize) {
60 switch (header.type) {
61 case TYPE_KEY:
62 return true;
63 case TYPE_MOTION:
64 return body.motion.pointerCount > 0
65 && body.motion.pointerCount <= MAX_POINTERS;
66 case TYPE_FINISHED:
67 return true;
68 }
69 }
70 return false;
71}
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070072
Jeff Browncbee6d62012-02-03 20:11:27 -080073size_t InputMessage::size() const {
74 switch (header.type) {
75 case TYPE_KEY:
76 return sizeof(Header) + body.key.size();
77 case TYPE_MOTION:
78 return sizeof(Header) + body.motion.size();
79 case TYPE_FINISHED:
80 return sizeof(Header) + body.finished.size();
81 }
82 return sizeof(Header);
83}
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070084
85
86// --- InputChannel ---
87
Jeff Browncbee6d62012-02-03 20:11:27 -080088InputChannel::InputChannel(const String8& name, int fd) :
89 mName(name), mFd(fd) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070090#if DEBUG_CHANNEL_LIFECYCLE
Jeff Browncbee6d62012-02-03 20:11:27 -080091 ALOGD("Input channel constructed: name='%s', fd=%d",
92 mName.string(), fd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070093#endif
94
Jeff Browncbee6d62012-02-03 20:11:27 -080095 int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
96 LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070097 "non-blocking. errno=%d", mName.string(), errno);
98}
99
100InputChannel::~InputChannel() {
101#if DEBUG_CHANNEL_LIFECYCLE
Jeff Browncbee6d62012-02-03 20:11:27 -0800102 ALOGD("Input channel destroyed: name='%s', fd=%d",
103 mName.string(), mFd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700104#endif
105
Jeff Browncbee6d62012-02-03 20:11:27 -0800106 ::close(mFd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700107}
108
109status_t InputChannel::openInputChannelPair(const String8& name,
Jeff Brown5c225b12010-06-16 01:53:36 -0700110 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
Jeff Browncbee6d62012-02-03 20:11:27 -0800111 int sockets[2];
112 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
113 status_t result = -errno;
114 ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700115 name.string(), errno);
Jeff Browncbee6d62012-02-03 20:11:27 -0800116 outServerChannel.clear();
117 outClientChannel.clear();
118 return result;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700119 }
120
Jeff Brownd1c48a02012-02-06 19:12:47 -0800121 int bufferSize = SOCKET_BUFFER_SIZE;
122 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
123 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
124 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
125 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
126
Jeff Browncbee6d62012-02-03 20:11:27 -0800127 String8 serverChannelName = name;
128 serverChannelName.append(" (server)");
129 outServerChannel = new InputChannel(serverChannelName, sockets[0]);
130
131 String8 clientChannelName = name;
132 clientChannelName.append(" (client)");
133 outClientChannel = new InputChannel(clientChannelName, sockets[1]);
134 return OK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700135}
136
Jeff Browncbee6d62012-02-03 20:11:27 -0800137status_t InputChannel::sendMessage(const InputMessage* msg) {
138 size_t msgLength = msg->size();
Jeff Brown7dae0e42010-09-16 17:04:52 -0700139 ssize_t nWrite;
140 do {
Jeff Browncbee6d62012-02-03 20:11:27 -0800141 nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
Jeff Brown7dae0e42010-09-16 17:04:52 -0700142 } while (nWrite == -1 && errno == EINTR);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700143
Jeff Browncbee6d62012-02-03 20:11:27 -0800144 if (nWrite < 0) {
145 int error = errno;
146#if DEBUG_CHANNEL_MESSAGES
147 ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
148 msg->header.type, error);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700149#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800150 if (error == EAGAIN || error == EWOULDBLOCK) {
151 return WOULD_BLOCK;
152 }
153 if (error == EPIPE || error == ENOTCONN) {
154 return DEAD_OBJECT;
155 }
156 return -error;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700157 }
158
Jeff Browncbee6d62012-02-03 20:11:27 -0800159 if (size_t(nWrite) != msgLength) {
160#if DEBUG_CHANNEL_MESSAGES
161 ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
162 mName.string(), msg->header.type);
Jeff Brown5c225b12010-06-16 01:53:36 -0700163#endif
164 return DEAD_OBJECT;
165 }
166
Jeff Browncbee6d62012-02-03 20:11:27 -0800167#if DEBUG_CHANNEL_MESSAGES
168 ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700169#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800170 return OK;
171}
172
173status_t InputChannel::receiveMessage(InputMessage* msg) {
174 ssize_t nRead;
175 do {
176 nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
177 } while (nRead == -1 && errno == EINTR);
178
179 if (nRead < 0) {
180 int error = errno;
181#if DEBUG_CHANNEL_MESSAGES
182 ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
183#endif
184 if (error == EAGAIN || error == EWOULDBLOCK) {
185 return WOULD_BLOCK;
186 }
187 if (error == EPIPE || error == ENOTCONN) {
188 return DEAD_OBJECT;
189 }
190 return -error;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700191 }
192
Jeff Browncbee6d62012-02-03 20:11:27 -0800193 if (nRead == 0) { // check for EOF
194#if DEBUG_CHANNEL_MESSAGES
195 ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700196#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800197 return DEAD_OBJECT;
198 }
199
200 if (!msg->isValid(nRead)) {
201#if DEBUG_CHANNEL_MESSAGES
202 ALOGD("channel '%s' ~ received invalid message", mName.string());
203#endif
204 return BAD_VALUE;
205 }
206
207#if DEBUG_CHANNEL_MESSAGES
208 ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
209#endif
210 return OK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700211}
212
213
214// --- InputPublisher ---
215
216InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
Jeff Browncbee6d62012-02-03 20:11:27 -0800217 mChannel(channel) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700218}
219
220InputPublisher::~InputPublisher() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700221}
222
223status_t InputPublisher::publishKeyEvent(
Jeff Brown072ec962012-02-07 14:46:57 -0800224 uint32_t seq,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700225 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700226 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700227 int32_t action,
228 int32_t flags,
229 int32_t keyCode,
230 int32_t scanCode,
231 int32_t metaState,
232 int32_t repeatCount,
233 nsecs_t downTime,
234 nsecs_t eventTime) {
235#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800236 ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700237 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700238 "downTime=%lld, eventTime=%lld",
Jeff Brown072ec962012-02-07 14:46:57 -0800239 mChannel->getName().string(), seq,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700240 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700241 downTime, eventTime);
242#endif
243
Jeff Brown072ec962012-02-07 14:46:57 -0800244 if (!seq) {
245 ALOGE("Attempted to publish a key event with sequence number 0.");
246 return BAD_VALUE;
247 }
248
Jeff Browncbee6d62012-02-03 20:11:27 -0800249 InputMessage msg;
250 msg.header.type = InputMessage::TYPE_KEY;
Jeff Brown072ec962012-02-07 14:46:57 -0800251 msg.body.key.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800252 msg.body.key.deviceId = deviceId;
253 msg.body.key.source = source;
254 msg.body.key.action = action;
255 msg.body.key.flags = flags;
256 msg.body.key.keyCode = keyCode;
257 msg.body.key.scanCode = scanCode;
258 msg.body.key.metaState = metaState;
259 msg.body.key.repeatCount = repeatCount;
260 msg.body.key.downTime = downTime;
261 msg.body.key.eventTime = eventTime;
262 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700263}
264
265status_t InputPublisher::publishMotionEvent(
Jeff Brown072ec962012-02-07 14:46:57 -0800266 uint32_t seq,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700267 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700268 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700269 int32_t action,
Jeff Brown85a31762010-09-01 17:01:00 -0700270 int32_t flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700271 int32_t edgeFlags,
272 int32_t metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700273 int32_t buttonState,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700274 float xOffset,
275 float yOffset,
276 float xPrecision,
277 float yPrecision,
278 nsecs_t downTime,
279 nsecs_t eventTime,
280 size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700281 const PointerProperties* pointerProperties,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700282 const PointerCoords* pointerCoords) {
283#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800284 ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700285 "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
286 "xOffset=%f, yOffset=%f, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700287 "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
288 "pointerCount=%d",
Jeff Brown072ec962012-02-07 14:46:57 -0800289 mChannel->getName().string(), seq,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700290 deviceId, source, action, flags, edgeFlags, metaState, buttonState,
291 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700292#endif
293
Jeff Brown072ec962012-02-07 14:46:57 -0800294 if (!seq) {
295 ALOGE("Attempted to publish a motion event with sequence number 0.");
296 return BAD_VALUE;
297 }
298
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700299 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Steve Block3762c312012-01-06 19:20:56 +0000300 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700301 mChannel->getName().string(), pointerCount);
302 return BAD_VALUE;
303 }
304
Jeff Browncbee6d62012-02-03 20:11:27 -0800305 InputMessage msg;
306 msg.header.type = InputMessage::TYPE_MOTION;
Jeff Brown072ec962012-02-07 14:46:57 -0800307 msg.body.motion.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800308 msg.body.motion.deviceId = deviceId;
309 msg.body.motion.source = source;
310 msg.body.motion.action = action;
311 msg.body.motion.flags = flags;
312 msg.body.motion.edgeFlags = edgeFlags;
313 msg.body.motion.metaState = metaState;
314 msg.body.motion.buttonState = buttonState;
315 msg.body.motion.xOffset = xOffset;
316 msg.body.motion.yOffset = yOffset;
317 msg.body.motion.xPrecision = xPrecision;
318 msg.body.motion.yPrecision = yPrecision;
319 msg.body.motion.downTime = downTime;
320 msg.body.motion.eventTime = eventTime;
321 msg.body.motion.pointerCount = pointerCount;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700322 for (size_t i = 0; i < pointerCount; i++) {
Jeff Browncbee6d62012-02-03 20:11:27 -0800323 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
324 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700325 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800326 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700327}
328
Jeff Brown072ec962012-02-07 14:46:57 -0800329status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700330#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000331 ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700332 mChannel->getName().string());
333#endif
334
Jeff Browncbee6d62012-02-03 20:11:27 -0800335 InputMessage msg;
336 status_t result = mChannel->receiveMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700337 if (result) {
Jeff Brown072ec962012-02-07 14:46:57 -0800338 *outSeq = 0;
Jeff Brown49ed71d2010-12-06 17:13:33 -0800339 *outHandled = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700340 return result;
341 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800342 if (msg.header.type != InputMessage::TYPE_FINISHED) {
343 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
344 mChannel->getName().string(), msg.header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700345 return UNKNOWN_ERROR;
346 }
Jeff Brown072ec962012-02-07 14:46:57 -0800347 *outSeq = msg.body.finished.seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800348 *outHandled = msg.body.finished.handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700349 return OK;
350}
351
352// --- InputConsumer ---
353
354InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
Jeff Brown90fde932012-02-13 12:44:01 -0800355 mChannel(channel), mMsgDeferred(false) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700356}
357
358InputConsumer::~InputConsumer() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700359}
360
Jeff Brown072ec962012-02-07 14:46:57 -0800361status_t InputConsumer::consume(InputEventFactoryInterface* factory,
Jeff Brown771526c2012-04-27 15:13:25 -0700362 bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700363#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown771526c2012-04-27 15:13:25 -0700364 ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld",
365 mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700366#endif
367
Jeff Brown072ec962012-02-07 14:46:57 -0800368 *outSeq = 0;
Jeff Brown5c225b12010-06-16 01:53:36 -0700369 *outEvent = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700370
Jeff Brown072ec962012-02-07 14:46:57 -0800371 // Fetch the next input message.
372 // Loop until an event can be returned or no additional events are received.
373 while (!*outEvent) {
Jeff Brown90fde932012-02-13 12:44:01 -0800374 if (mMsgDeferred) {
375 // mMsg contains a valid input message from the previous call to consume
376 // that has not yet been processed.
377 mMsgDeferred = false;
378 } else {
379 // Receive a fresh message.
380 status_t result = mChannel->receiveMessage(&mMsg);
381 if (result) {
382 // Consume the next batched event unless batches are being held for later.
Jeff Brown771526c2012-04-27 15:13:25 -0700383 if (consumeBatches || result != WOULD_BLOCK) {
384 result = consumeBatch(factory, frameTime, outSeq, outEvent);
385 if (*outEvent) {
Jeff Brown072ec962012-02-07 14:46:57 -0800386#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown771526c2012-04-27 15:13:25 -0700387 ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
388 mChannel->getName().string(), *outSeq);
Jeff Brown072ec962012-02-07 14:46:57 -0800389#endif
Jeff Brown771526c2012-04-27 15:13:25 -0700390 break;
391 }
Jeff Brown90fde932012-02-13 12:44:01 -0800392 }
393 return result;
Jeff Brown072ec962012-02-07 14:46:57 -0800394 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800395 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700396
Jeff Brown90fde932012-02-13 12:44:01 -0800397 switch (mMsg.header.type) {
Jeff Brown072ec962012-02-07 14:46:57 -0800398 case InputMessage::TYPE_KEY: {
399 KeyEvent* keyEvent = factory->createKeyEvent();
400 if (!keyEvent) return NO_MEMORY;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700401
Jeff Brown90fde932012-02-13 12:44:01 -0800402 initializeKeyEvent(keyEvent, &mMsg);
403 *outSeq = mMsg.body.key.seq;
Jeff Brown072ec962012-02-07 14:46:57 -0800404 *outEvent = keyEvent;
405#if DEBUG_TRANSPORT_ACTIONS
406 ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
407 mChannel->getName().string(), *outSeq);
408#endif
409 break;
410 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700411
Jeff Brown072ec962012-02-07 14:46:57 -0800412 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown90fde932012-02-13 12:44:01 -0800413 ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
Jeff Brown072ec962012-02-07 14:46:57 -0800414 if (batchIndex >= 0) {
415 Batch& batch = mBatches.editItemAt(batchIndex);
Jeff Brown771526c2012-04-27 15:13:25 -0700416 if (canAddSample(batch, &mMsg)) {
417 batch.samples.push(mMsg);
Jeff Brown072ec962012-02-07 14:46:57 -0800418#if DEBUG_TRANSPORT_ACTIONS
419 ALOGD("channel '%s' consumer ~ appended to batch event",
420 mChannel->getName().string());
421#endif
422 break;
423 } else {
Jeff Brown072ec962012-02-07 14:46:57 -0800424 // We cannot append to the batch in progress, so we need to consume
Jeff Brown90fde932012-02-13 12:44:01 -0800425 // the previous batch right now and defer the new message until later.
426 mMsgDeferred = true;
Jeff Brown771526c2012-04-27 15:13:25 -0700427 status_t result = consumeSamples(factory,
428 batch, batch.samples.size(), outSeq, outEvent);
Jeff Brown072ec962012-02-07 14:46:57 -0800429 mBatches.removeAt(batchIndex);
Jeff Brown771526c2012-04-27 15:13:25 -0700430 if (result) {
431 return result;
432 }
Jeff Brown072ec962012-02-07 14:46:57 -0800433#if DEBUG_TRANSPORT_ACTIONS
434 ALOGD("channel '%s' consumer ~ consumed batch event and "
435 "deferred current event, seq=%u",
436 mChannel->getName().string(), *outSeq);
437#endif
438 break;
439 }
440 }
441
442 // Start a new batch if needed.
Jeff Brown90fde932012-02-13 12:44:01 -0800443 if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
444 || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown072ec962012-02-07 14:46:57 -0800445 mBatches.push();
446 Batch& batch = mBatches.editTop();
Jeff Brown771526c2012-04-27 15:13:25 -0700447 batch.samples.push(mMsg);
Jeff Brown072ec962012-02-07 14:46:57 -0800448#if DEBUG_TRANSPORT_ACTIONS
449 ALOGD("channel '%s' consumer ~ started batch event",
450 mChannel->getName().string());
451#endif
452 break;
453 }
454
455 MotionEvent* motionEvent = factory->createMotionEvent();
456 if (! motionEvent) return NO_MEMORY;
457
Jeff Brown771526c2012-04-27 15:13:25 -0700458 updateTouchState(&mMsg);
Jeff Brown90fde932012-02-13 12:44:01 -0800459 initializeMotionEvent(motionEvent, &mMsg);
460 *outSeq = mMsg.body.motion.seq;
Jeff Brown072ec962012-02-07 14:46:57 -0800461 *outEvent = motionEvent;
462#if DEBUG_TRANSPORT_ACTIONS
463 ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
464 mChannel->getName().string(), *outSeq);
465#endif
466 break;
467 }
468
469 default:
470 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
Jeff Brown90fde932012-02-13 12:44:01 -0800471 mChannel->getName().string(), mMsg.header.type);
Jeff Brown072ec962012-02-07 14:46:57 -0800472 return UNKNOWN_ERROR;
473 }
474 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700475 return OK;
476}
477
Jeff Brown771526c2012-04-27 15:13:25 -0700478status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
479 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
480 status_t result;
481 for (size_t i = mBatches.size(); i-- > 0; ) {
482 Batch& batch = mBatches.editItemAt(i);
483 if (frameTime < 0) {
484 result = consumeSamples(factory, batch, batch.samples.size(),
485 outSeq, outEvent);
486 mBatches.removeAt(i);
487 return result;
488 }
489
490 nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY;
491 ssize_t split = findSampleNoLaterThan(batch, sampleTime);
492 if (split < 0) {
493 continue;
494 }
495
496 result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
497 const InputMessage* next;
498 if (batch.samples.isEmpty()) {
499 mBatches.removeAt(i);
500 next = NULL;
501 } else {
502 next = &batch.samples.itemAt(0);
503 }
504 if (!result) {
505 resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
506 }
507 return result;
508 }
509
510 return WOULD_BLOCK;
511}
512
513status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
514 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
515 MotionEvent* motionEvent = factory->createMotionEvent();
516 if (! motionEvent) return NO_MEMORY;
517
518 uint32_t chain = 0;
519 for (size_t i = 0; i < count; i++) {
520 InputMessage& msg = batch.samples.editItemAt(i);
521 updateTouchState(&msg);
522 if (i) {
523 SeqChain seqChain;
524 seqChain.seq = msg.body.motion.seq;
525 seqChain.chain = chain;
526 mSeqChains.push(seqChain);
527 addSample(motionEvent, &msg);
528 } else {
529 initializeMotionEvent(motionEvent, &msg);
530 }
531 chain = msg.body.motion.seq;
532 }
533 batch.samples.removeItemsAt(0, count);
534
535 *outSeq = chain;
536 *outEvent = motionEvent;
537 return OK;
538}
539
540void InputConsumer::updateTouchState(InputMessage* msg) {
541 if (!(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
542 return;
543 }
544
545 int32_t deviceId = msg->body.motion.deviceId;
546 int32_t source = msg->body.motion.source;
547
548 // TODO: Filter the incoming touch event so that it aligns better
549 // with prior predictions. Turning RESAMPLE_LATENCY offsets the need
550 // for filtering but it would be nice to reduce the latency further.
551
552 switch (msg->body.motion.action) {
553 case AMOTION_EVENT_ACTION_DOWN: {
554 ssize_t index = findTouchState(deviceId, source);
555 if (index < 0) {
556 mTouchStates.push();
557 index = mTouchStates.size() - 1;
558 }
559 TouchState& touchState = mTouchStates.editItemAt(index);
560 touchState.initialize(deviceId, source);
561 touchState.addHistory(msg);
562 break;
563 }
564
565 case AMOTION_EVENT_ACTION_MOVE: {
566 ssize_t index = findTouchState(deviceId, source);
567 if (index >= 0) {
568 TouchState& touchState = mTouchStates.editItemAt(index);
569 touchState.addHistory(msg);
570 }
571 break;
572 }
573
574 case AMOTION_EVENT_ACTION_UP:
575 case AMOTION_EVENT_ACTION_CANCEL: {
576 ssize_t index = findTouchState(deviceId, source);
577 if (index >= 0) {
578 mTouchStates.removeAt(index);
579 }
580 break;
581 }
582 }
583}
584
585void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
586 const InputMessage* next) {
587 if (event->getAction() != AMOTION_EVENT_ACTION_MOVE
588 || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER)) {
589#if DEBUG_RESAMPLING
590 ALOGD("Not resampled, not a move.");
591#endif
592 return;
593 }
594
595 ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
596 if (index < 0) {
597#if DEBUG_RESAMPLING
598 ALOGD("Not resampled, no touch state for device.");
599#endif
600 return;
601 }
602
603 TouchState& touchState = mTouchStates.editItemAt(index);
604 if (touchState.historySize < 1) {
605#if DEBUG_RESAMPLING
606 ALOGD("Not resampled, no history for device.");
607#endif
608 return;
609 }
610
611 const History* current = touchState.getHistory(0);
612 const History* other;
613 History future;
614 if (next) {
615 future.initializeFrom(next);
616 other = &future;
617 } else if (touchState.historySize >= 2) {
618 other = touchState.getHistory(1);
619 } else {
620#if DEBUG_RESAMPLING
621 ALOGD("Not resampled, insufficient data.");
622#endif
623 return;
624 }
625
626 nsecs_t delta = current->eventTime - other->eventTime;
627 if (delta > -RESAMPLE_MIN_DELTA && delta < RESAMPLE_MIN_DELTA) {
628#if DEBUG_RESAMPLING
629 ALOGD("Not resampled, delta time is %lld", delta);
630#endif
631 return;
632 }
633
634 float alpha = float(current->eventTime - sampleTime) / delta;
635 if (fabs(alpha) > RESAMPLE_MAX_ALPHA) {
636#if DEBUG_RESAMPLING
637 ALOGD("Not resampled, alpha is %f", alpha);
638#endif
639 return;
640 }
641
642 size_t pointerCount = event->getPointerCount();
643 PointerCoords resampledCoords[MAX_POINTERS];
644 for (size_t i = 0; i < pointerCount; i++) {
645 uint32_t id = event->getPointerId(i);
646 if (!current->idBits.hasBit(id)) {
647#if DEBUG_RESAMPLING
648 ALOGD("Not resampled, missing id %d", id);
649#endif
650 return;
651 }
652 const PointerCoords& currentCoords =
653 current->pointers[current->idBits.getIndexOfBit(id)];
654 if (other->idBits.hasBit(id)
655 && shouldResampleTool(event->getToolType(i))) {
656 const PointerCoords& otherCoords =
657 other->pointers[other->idBits.getIndexOfBit(id)];
658 resampledCoords[i].lerp(currentCoords, otherCoords, alpha);
659#if DEBUG_RESAMPLING
660 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
661 "other (%0.3f, %0.3f), alpha %0.3f",
662 i, resampledCoords[i].getX(), resampledCoords[i].getY(),
663 currentCoords.getX(), currentCoords.getY(),
664 otherCoords.getX(), otherCoords.getY(),
665 alpha);
666#endif
667 } else {
668 resampledCoords[i].copyFrom(currentCoords);
669#if DEBUG_RESAMPLING
670 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
671 i, resampledCoords[i].getX(), resampledCoords[i].getY(),
672 currentCoords.getX(), currentCoords.getY());
673#endif
674 }
675 }
676
677 event->addSample(sampleTime, resampledCoords);
678}
679
680bool InputConsumer::shouldResampleTool(int32_t toolType) {
681 return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
682 || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
683}
684
Jeff Brown072ec962012-02-07 14:46:57 -0800685status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700686#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800687 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
688 mChannel->getName().string(), seq, handled ? "true" : "false");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700689#endif
690
Jeff Brown072ec962012-02-07 14:46:57 -0800691 if (!seq) {
692 ALOGE("Attempted to send a finished signal with sequence number 0.");
693 return BAD_VALUE;
694 }
695
Jeff Brown2d34e0c2012-02-13 13:18:09 -0800696 // Send finished signals for the batch sequence chain first.
697 size_t seqChainCount = mSeqChains.size();
698 if (seqChainCount) {
699 uint32_t currentSeq = seq;
700 uint32_t chainSeqs[seqChainCount];
701 size_t chainIndex = 0;
702 for (size_t i = seqChainCount; i-- > 0; ) {
703 const SeqChain& seqChain = mSeqChains.itemAt(i);
704 if (seqChain.seq == currentSeq) {
705 currentSeq = seqChain.chain;
706 chainSeqs[chainIndex++] = currentSeq;
707 mSeqChains.removeAt(i);
708 }
709 }
710 status_t status = OK;
711 while (!status && chainIndex-- > 0) {
712 status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
713 }
714 if (status) {
715 // An error occurred so at least one signal was not sent, reconstruct the chain.
716 do {
717 SeqChain seqChain;
718 seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
719 seqChain.chain = chainSeqs[chainIndex];
720 mSeqChains.push(seqChain);
721 } while (chainIndex-- > 0);
722 return status;
723 }
724 }
725
726 // Send finished signal for the last message in the batch.
727 return sendUnchainedFinishedSignal(seq, handled);
728}
729
730status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
Jeff Browncbee6d62012-02-03 20:11:27 -0800731 InputMessage msg;
732 msg.header.type = InputMessage::TYPE_FINISHED;
Jeff Brown072ec962012-02-07 14:46:57 -0800733 msg.body.finished.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800734 msg.body.finished.handled = handled;
735 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700736}
737
Jeff Brown2b6c32c2012-03-13 15:00:09 -0700738bool InputConsumer::hasDeferredEvent() const {
739 return mMsgDeferred;
740}
741
Jeff Brown072ec962012-02-07 14:46:57 -0800742bool InputConsumer::hasPendingBatch() const {
743 return !mBatches.isEmpty();
744}
745
746ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
747 for (size_t i = 0; i < mBatches.size(); i++) {
748 const Batch& batch = mBatches.itemAt(i);
Jeff Brown771526c2012-04-27 15:13:25 -0700749 const InputMessage& head = batch.samples.itemAt(0);
750 if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
751 return i;
752 }
753 }
754 return -1;
755}
756
757ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
758 for (size_t i = 0; i < mTouchStates.size(); i++) {
759 const TouchState& touchState = mTouchStates.itemAt(i);
760 if (touchState.deviceId == deviceId && touchState.source == source) {
Jeff Brown072ec962012-02-07 14:46:57 -0800761 return i;
762 }
763 }
764 return -1;
765}
766
767void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
768 event->initialize(
769 msg->body.key.deviceId,
770 msg->body.key.source,
771 msg->body.key.action,
772 msg->body.key.flags,
773 msg->body.key.keyCode,
774 msg->body.key.scanCode,
775 msg->body.key.metaState,
776 msg->body.key.repeatCount,
777 msg->body.key.downTime,
778 msg->body.key.eventTime);
779}
780
781void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
782 size_t pointerCount = msg->body.motion.pointerCount;
783 PointerProperties pointerProperties[pointerCount];
784 PointerCoords pointerCoords[pointerCount];
785 for (size_t i = 0; i < pointerCount; i++) {
786 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
787 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
788 }
789
790 event->initialize(
791 msg->body.motion.deviceId,
792 msg->body.motion.source,
793 msg->body.motion.action,
794 msg->body.motion.flags,
795 msg->body.motion.edgeFlags,
796 msg->body.motion.metaState,
797 msg->body.motion.buttonState,
798 msg->body.motion.xOffset,
799 msg->body.motion.yOffset,
800 msg->body.motion.xPrecision,
801 msg->body.motion.yPrecision,
802 msg->body.motion.downTime,
803 msg->body.motion.eventTime,
804 pointerCount,
805 pointerProperties,
806 pointerCoords);
807}
808
Jeff Brown771526c2012-04-27 15:13:25 -0700809void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
Jeff Brown072ec962012-02-07 14:46:57 -0800810 size_t pointerCount = msg->body.motion.pointerCount;
811 PointerCoords pointerCoords[pointerCount];
812 for (size_t i = 0; i < pointerCount; i++) {
813 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
814 }
815
816 event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
817 event->addSample(msg->body.motion.eventTime, pointerCoords);
818}
819
Jeff Brown771526c2012-04-27 15:13:25 -0700820bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
821 const InputMessage& head = batch.samples.itemAt(0);
822 size_t pointerCount = msg->body.motion.pointerCount;
823 if (head.body.motion.pointerCount != pointerCount
824 || head.body.motion.action != msg->body.motion.action) {
825 return false;
826 }
827 for (size_t i = 0; i < pointerCount; i++) {
828 if (head.body.motion.pointers[i].properties
829 != msg->body.motion.pointers[i].properties) {
830 return false;
831 }
832 }
833 return true;
834}
835
836ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
837 size_t numSamples = batch.samples.size();
838 size_t index = 0;
839 while (index < numSamples
840 && batch.samples.itemAt(index).body.motion.eventTime <= time) {
841 index += 1;
842 }
843 return ssize_t(index) - 1;
844}
845
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700846} // namespace android