blob: ecb3fb5c9870ce09daa9dfdc85f9bcc9f7c86d9e [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
19
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070020#include <cutils/log.h>
21#include <errno.h>
22#include <fcntl.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070023#include <ui/InputTransport.h>
24#include <unistd.h>
Jeff Browncbee6d62012-02-03 20:11:27 -080025#include <sys/types.h>
26#include <sys/socket.h>
27
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070028
29namespace android {
30
Jeff Brownd1c48a02012-02-06 19:12:47 -080031// Socket buffer size. The default is typically about 128KB, which is much larger than
32// we really need. So we make it smaller. It just needs to be big enough to hold
33// a few dozen large multi-finger motion events in the case where an application gets
34// behind processing touches.
35static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
36
37
Jeff Browncbee6d62012-02-03 20:11:27 -080038// --- InputMessage ---
Jeff Brown4e91a182011-04-07 11:38:09 -070039
Jeff Browncbee6d62012-02-03 20:11:27 -080040bool InputMessage::isValid(size_t actualSize) const {
41 if (size() == actualSize) {
42 switch (header.type) {
43 case TYPE_KEY:
44 return true;
45 case TYPE_MOTION:
46 return body.motion.pointerCount > 0
47 && body.motion.pointerCount <= MAX_POINTERS;
48 case TYPE_FINISHED:
49 return true;
50 }
51 }
52 return false;
53}
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070054
Jeff Browncbee6d62012-02-03 20:11:27 -080055size_t InputMessage::size() const {
56 switch (header.type) {
57 case TYPE_KEY:
58 return sizeof(Header) + body.key.size();
59 case TYPE_MOTION:
60 return sizeof(Header) + body.motion.size();
61 case TYPE_FINISHED:
62 return sizeof(Header) + body.finished.size();
63 }
64 return sizeof(Header);
65}
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070066
67
68// --- InputChannel ---
69
Jeff Browncbee6d62012-02-03 20:11:27 -080070InputChannel::InputChannel(const String8& name, int fd) :
71 mName(name), mFd(fd) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070072#if DEBUG_CHANNEL_LIFECYCLE
Jeff Browncbee6d62012-02-03 20:11:27 -080073 ALOGD("Input channel constructed: name='%s', fd=%d",
74 mName.string(), fd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070075#endif
76
Jeff Browncbee6d62012-02-03 20:11:27 -080077 int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
78 LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070079 "non-blocking. errno=%d", mName.string(), errno);
80}
81
82InputChannel::~InputChannel() {
83#if DEBUG_CHANNEL_LIFECYCLE
Jeff Browncbee6d62012-02-03 20:11:27 -080084 ALOGD("Input channel destroyed: name='%s', fd=%d",
85 mName.string(), mFd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070086#endif
87
Jeff Browncbee6d62012-02-03 20:11:27 -080088 ::close(mFd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070089}
90
91status_t InputChannel::openInputChannelPair(const String8& name,
Jeff Brown5c225b12010-06-16 01:53:36 -070092 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
Jeff Browncbee6d62012-02-03 20:11:27 -080093 int sockets[2];
94 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
95 status_t result = -errno;
96 ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070097 name.string(), errno);
Jeff Browncbee6d62012-02-03 20:11:27 -080098 outServerChannel.clear();
99 outClientChannel.clear();
100 return result;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700101 }
102
Jeff Brownd1c48a02012-02-06 19:12:47 -0800103 int bufferSize = SOCKET_BUFFER_SIZE;
104 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
105 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
106 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
107 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
108
Jeff Browncbee6d62012-02-03 20:11:27 -0800109 String8 serverChannelName = name;
110 serverChannelName.append(" (server)");
111 outServerChannel = new InputChannel(serverChannelName, sockets[0]);
112
113 String8 clientChannelName = name;
114 clientChannelName.append(" (client)");
115 outClientChannel = new InputChannel(clientChannelName, sockets[1]);
116 return OK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700117}
118
Jeff Browncbee6d62012-02-03 20:11:27 -0800119status_t InputChannel::sendMessage(const InputMessage* msg) {
120 size_t msgLength = msg->size();
Jeff Brown7dae0e42010-09-16 17:04:52 -0700121 ssize_t nWrite;
122 do {
Jeff Browncbee6d62012-02-03 20:11:27 -0800123 nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
Jeff Brown7dae0e42010-09-16 17:04:52 -0700124 } while (nWrite == -1 && errno == EINTR);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700125
Jeff Browncbee6d62012-02-03 20:11:27 -0800126 if (nWrite < 0) {
127 int error = errno;
128#if DEBUG_CHANNEL_MESSAGES
129 ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
130 msg->header.type, error);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700131#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800132 if (error == EAGAIN || error == EWOULDBLOCK) {
133 return WOULD_BLOCK;
134 }
135 if (error == EPIPE || error == ENOTCONN) {
136 return DEAD_OBJECT;
137 }
138 return -error;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700139 }
140
Jeff Browncbee6d62012-02-03 20:11:27 -0800141 if (size_t(nWrite) != msgLength) {
142#if DEBUG_CHANNEL_MESSAGES
143 ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
144 mName.string(), msg->header.type);
Jeff Brown5c225b12010-06-16 01:53:36 -0700145#endif
146 return DEAD_OBJECT;
147 }
148
Jeff Browncbee6d62012-02-03 20:11:27 -0800149#if DEBUG_CHANNEL_MESSAGES
150 ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700151#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800152 return OK;
153}
154
155status_t InputChannel::receiveMessage(InputMessage* msg) {
156 ssize_t nRead;
157 do {
158 nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
159 } while (nRead == -1 && errno == EINTR);
160
161 if (nRead < 0) {
162 int error = errno;
163#if DEBUG_CHANNEL_MESSAGES
164 ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
165#endif
166 if (error == EAGAIN || error == EWOULDBLOCK) {
167 return WOULD_BLOCK;
168 }
169 if (error == EPIPE || error == ENOTCONN) {
170 return DEAD_OBJECT;
171 }
172 return -error;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700173 }
174
Jeff Browncbee6d62012-02-03 20:11:27 -0800175 if (nRead == 0) { // check for EOF
176#if DEBUG_CHANNEL_MESSAGES
177 ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700178#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800179 return DEAD_OBJECT;
180 }
181
182 if (!msg->isValid(nRead)) {
183#if DEBUG_CHANNEL_MESSAGES
184 ALOGD("channel '%s' ~ received invalid message", mName.string());
185#endif
186 return BAD_VALUE;
187 }
188
189#if DEBUG_CHANNEL_MESSAGES
190 ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
191#endif
192 return OK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700193}
194
195
196// --- InputPublisher ---
197
198InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
Jeff Browncbee6d62012-02-03 20:11:27 -0800199 mChannel(channel) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700200}
201
202InputPublisher::~InputPublisher() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700203}
204
205status_t InputPublisher::publishKeyEvent(
Jeff Brown072ec962012-02-07 14:46:57 -0800206 uint32_t seq,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700207 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700208 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700209 int32_t action,
210 int32_t flags,
211 int32_t keyCode,
212 int32_t scanCode,
213 int32_t metaState,
214 int32_t repeatCount,
215 nsecs_t downTime,
216 nsecs_t eventTime) {
217#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800218 ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700219 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700220 "downTime=%lld, eventTime=%lld",
Jeff Brown072ec962012-02-07 14:46:57 -0800221 mChannel->getName().string(), seq,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700222 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700223 downTime, eventTime);
224#endif
225
Jeff Brown072ec962012-02-07 14:46:57 -0800226 if (!seq) {
227 ALOGE("Attempted to publish a key event with sequence number 0.");
228 return BAD_VALUE;
229 }
230
Jeff Browncbee6d62012-02-03 20:11:27 -0800231 InputMessage msg;
232 msg.header.type = InputMessage::TYPE_KEY;
Jeff Brown072ec962012-02-07 14:46:57 -0800233 msg.body.key.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800234 msg.body.key.deviceId = deviceId;
235 msg.body.key.source = source;
236 msg.body.key.action = action;
237 msg.body.key.flags = flags;
238 msg.body.key.keyCode = keyCode;
239 msg.body.key.scanCode = scanCode;
240 msg.body.key.metaState = metaState;
241 msg.body.key.repeatCount = repeatCount;
242 msg.body.key.downTime = downTime;
243 msg.body.key.eventTime = eventTime;
244 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700245}
246
247status_t InputPublisher::publishMotionEvent(
Jeff Brown072ec962012-02-07 14:46:57 -0800248 uint32_t seq,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700249 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700250 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700251 int32_t action,
Jeff Brown85a31762010-09-01 17:01:00 -0700252 int32_t flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700253 int32_t edgeFlags,
254 int32_t metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700255 int32_t buttonState,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700256 float xOffset,
257 float yOffset,
258 float xPrecision,
259 float yPrecision,
260 nsecs_t downTime,
261 nsecs_t eventTime,
262 size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700263 const PointerProperties* pointerProperties,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700264 const PointerCoords* pointerCoords) {
265#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800266 ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700267 "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
268 "xOffset=%f, yOffset=%f, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700269 "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
270 "pointerCount=%d",
Jeff Brown072ec962012-02-07 14:46:57 -0800271 mChannel->getName().string(), seq,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700272 deviceId, source, action, flags, edgeFlags, metaState, buttonState,
273 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700274#endif
275
Jeff Brown072ec962012-02-07 14:46:57 -0800276 if (!seq) {
277 ALOGE("Attempted to publish a motion event with sequence number 0.");
278 return BAD_VALUE;
279 }
280
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700281 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Steve Block3762c312012-01-06 19:20:56 +0000282 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700283 mChannel->getName().string(), pointerCount);
284 return BAD_VALUE;
285 }
286
Jeff Browncbee6d62012-02-03 20:11:27 -0800287 InputMessage msg;
288 msg.header.type = InputMessage::TYPE_MOTION;
Jeff Brown072ec962012-02-07 14:46:57 -0800289 msg.body.motion.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800290 msg.body.motion.deviceId = deviceId;
291 msg.body.motion.source = source;
292 msg.body.motion.action = action;
293 msg.body.motion.flags = flags;
294 msg.body.motion.edgeFlags = edgeFlags;
295 msg.body.motion.metaState = metaState;
296 msg.body.motion.buttonState = buttonState;
297 msg.body.motion.xOffset = xOffset;
298 msg.body.motion.yOffset = yOffset;
299 msg.body.motion.xPrecision = xPrecision;
300 msg.body.motion.yPrecision = yPrecision;
301 msg.body.motion.downTime = downTime;
302 msg.body.motion.eventTime = eventTime;
303 msg.body.motion.pointerCount = pointerCount;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700304 for (size_t i = 0; i < pointerCount; i++) {
Jeff Browncbee6d62012-02-03 20:11:27 -0800305 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
306 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700307 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800308 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700309}
310
Jeff Brown072ec962012-02-07 14:46:57 -0800311status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700312#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000313 ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700314 mChannel->getName().string());
315#endif
316
Jeff Browncbee6d62012-02-03 20:11:27 -0800317 InputMessage msg;
318 status_t result = mChannel->receiveMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700319 if (result) {
Jeff Brown072ec962012-02-07 14:46:57 -0800320 *outSeq = 0;
Jeff Brown49ed71d2010-12-06 17:13:33 -0800321 *outHandled = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700322 return result;
323 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800324 if (msg.header.type != InputMessage::TYPE_FINISHED) {
325 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
326 mChannel->getName().string(), msg.header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700327 return UNKNOWN_ERROR;
328 }
Jeff Brown072ec962012-02-07 14:46:57 -0800329 *outSeq = msg.body.finished.seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800330 *outHandled = msg.body.finished.handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700331 return OK;
332}
333
334// --- InputConsumer ---
335
336InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
Jeff Brown90fde932012-02-13 12:44:01 -0800337 mChannel(channel), mMsgDeferred(false) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700338}
339
340InputConsumer::~InputConsumer() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700341}
342
Jeff Brown072ec962012-02-07 14:46:57 -0800343status_t InputConsumer::consume(InputEventFactoryInterface* factory,
344 bool consumeBatches, uint32_t* outSeq, InputEvent** outEvent) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700345#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800346 ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s",
347 mChannel->getName().string(), consumeBatches ? "true" : "false");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700348#endif
349
Jeff Brown072ec962012-02-07 14:46:57 -0800350 *outSeq = 0;
Jeff Brown5c225b12010-06-16 01:53:36 -0700351 *outEvent = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700352
Jeff Brown072ec962012-02-07 14:46:57 -0800353 // Fetch the next input message.
354 // Loop until an event can be returned or no additional events are received.
355 while (!*outEvent) {
Jeff Brown90fde932012-02-13 12:44:01 -0800356 if (mMsgDeferred) {
357 // mMsg contains a valid input message from the previous call to consume
358 // that has not yet been processed.
359 mMsgDeferred = false;
360 } else {
361 // Receive a fresh message.
362 status_t result = mChannel->receiveMessage(&mMsg);
363 if (result) {
364 // Consume the next batched event unless batches are being held for later.
365 if (!mBatches.isEmpty() && (consumeBatches || result != WOULD_BLOCK)) {
366 MotionEvent* motionEvent = factory->createMotionEvent();
367 if (! motionEvent) return NO_MEMORY;
Jeff Brown072ec962012-02-07 14:46:57 -0800368
Jeff Brown90fde932012-02-13 12:44:01 -0800369 const Batch& batch = mBatches.top();
370 motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
371 *outSeq = batch.seq;
372 *outEvent = motionEvent;
373 mBatches.pop();
Jeff Brown072ec962012-02-07 14:46:57 -0800374#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown90fde932012-02-13 12:44:01 -0800375 ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
376 mChannel->getName().string(), *outSeq);
Jeff Brown072ec962012-02-07 14:46:57 -0800377#endif
Jeff Brown90fde932012-02-13 12:44:01 -0800378 break;
379 }
380 return result;
Jeff Brown072ec962012-02-07 14:46:57 -0800381 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800382 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700383
Jeff Brown90fde932012-02-13 12:44:01 -0800384 switch (mMsg.header.type) {
Jeff Brown072ec962012-02-07 14:46:57 -0800385 case InputMessage::TYPE_KEY: {
386 KeyEvent* keyEvent = factory->createKeyEvent();
387 if (!keyEvent) return NO_MEMORY;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700388
Jeff Brown90fde932012-02-13 12:44:01 -0800389 initializeKeyEvent(keyEvent, &mMsg);
390 *outSeq = mMsg.body.key.seq;
Jeff Brown072ec962012-02-07 14:46:57 -0800391 *outEvent = keyEvent;
392#if DEBUG_TRANSPORT_ACTIONS
393 ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
394 mChannel->getName().string(), *outSeq);
395#endif
396 break;
397 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700398
Jeff Brown072ec962012-02-07 14:46:57 -0800399 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown90fde932012-02-13 12:44:01 -0800400 ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
Jeff Brown072ec962012-02-07 14:46:57 -0800401 if (batchIndex >= 0) {
402 Batch& batch = mBatches.editItemAt(batchIndex);
Jeff Brown90fde932012-02-13 12:44:01 -0800403 if (canAppendSamples(&batch.event, &mMsg)) {
Jeff Brown072ec962012-02-07 14:46:57 -0800404 // Append to the batch and save the new sequence number for the tail end.
Jeff Brown2d34e0c2012-02-13 13:18:09 -0800405 uint32_t chain = batch.seq;
Jeff Brown90fde932012-02-13 12:44:01 -0800406 appendSamples(&batch.event, &mMsg);
407 batch.seq = mMsg.body.motion.seq;
Jeff Brown2d34e0c2012-02-13 13:18:09 -0800408
409 // Update the sequence number chain.
410 SeqChain seqChain;
411 seqChain.seq = batch.seq;
412 seqChain.chain = chain;
413 mSeqChains.push(seqChain);
Jeff Brown072ec962012-02-07 14:46:57 -0800414#if DEBUG_TRANSPORT_ACTIONS
415 ALOGD("channel '%s' consumer ~ appended to batch event",
416 mChannel->getName().string());
417#endif
418 break;
419 } else {
420 MotionEvent* motionEvent = factory->createMotionEvent();
421 if (! motionEvent) return NO_MEMORY;
422
423 // We cannot append to the batch in progress, so we need to consume
Jeff Brown90fde932012-02-13 12:44:01 -0800424 // the previous batch right now and defer the new message until later.
425 mMsgDeferred = true;
Jeff Brown072ec962012-02-07 14:46:57 -0800426
427 // Return the end of the previous batch.
428 motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
429 *outSeq = batch.seq;
430 *outEvent = motionEvent;
431 mBatches.removeAt(batchIndex);
432#if DEBUG_TRANSPORT_ACTIONS
433 ALOGD("channel '%s' consumer ~ consumed batch event and "
434 "deferred current event, seq=%u",
435 mChannel->getName().string(), *outSeq);
436#endif
437 break;
438 }
439 }
440
441 // Start a new batch if needed.
Jeff Brown90fde932012-02-13 12:44:01 -0800442 if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
443 || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
Jeff Brown072ec962012-02-07 14:46:57 -0800444 mBatches.push();
445 Batch& batch = mBatches.editTop();
Jeff Brown90fde932012-02-13 12:44:01 -0800446 batch.seq = mMsg.body.motion.seq;
447 initializeMotionEvent(&batch.event, &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 Brown90fde932012-02-13 12:44:01 -0800458 initializeMotionEvent(motionEvent, &mMsg);
459 *outSeq = mMsg.body.motion.seq;
Jeff Brown072ec962012-02-07 14:46:57 -0800460 *outEvent = motionEvent;
461#if DEBUG_TRANSPORT_ACTIONS
462 ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
463 mChannel->getName().string(), *outSeq);
464#endif
465 break;
466 }
467
468 default:
469 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
Jeff Brown90fde932012-02-13 12:44:01 -0800470 mChannel->getName().string(), mMsg.header.type);
Jeff Brown072ec962012-02-07 14:46:57 -0800471 return UNKNOWN_ERROR;
472 }
473 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700474 return OK;
475}
476
Jeff Brown072ec962012-02-07 14:46:57 -0800477status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700478#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800479 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
480 mChannel->getName().string(), seq, handled ? "true" : "false");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700481#endif
482
Jeff Brown072ec962012-02-07 14:46:57 -0800483 if (!seq) {
484 ALOGE("Attempted to send a finished signal with sequence number 0.");
485 return BAD_VALUE;
486 }
487
Jeff Brown2d34e0c2012-02-13 13:18:09 -0800488 // Send finished signals for the batch sequence chain first.
489 size_t seqChainCount = mSeqChains.size();
490 if (seqChainCount) {
491 uint32_t currentSeq = seq;
492 uint32_t chainSeqs[seqChainCount];
493 size_t chainIndex = 0;
494 for (size_t i = seqChainCount; i-- > 0; ) {
495 const SeqChain& seqChain = mSeqChains.itemAt(i);
496 if (seqChain.seq == currentSeq) {
497 currentSeq = seqChain.chain;
498 chainSeqs[chainIndex++] = currentSeq;
499 mSeqChains.removeAt(i);
500 }
501 }
502 status_t status = OK;
503 while (!status && chainIndex-- > 0) {
504 status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
505 }
506 if (status) {
507 // An error occurred so at least one signal was not sent, reconstruct the chain.
508 do {
509 SeqChain seqChain;
510 seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
511 seqChain.chain = chainSeqs[chainIndex];
512 mSeqChains.push(seqChain);
513 } while (chainIndex-- > 0);
514 return status;
515 }
516 }
517
518 // Send finished signal for the last message in the batch.
519 return sendUnchainedFinishedSignal(seq, handled);
520}
521
522status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
Jeff Browncbee6d62012-02-03 20:11:27 -0800523 InputMessage msg;
524 msg.header.type = InputMessage::TYPE_FINISHED;
Jeff Brown072ec962012-02-07 14:46:57 -0800525 msg.body.finished.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800526 msg.body.finished.handled = handled;
527 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700528}
529
Jeff Brown072ec962012-02-07 14:46:57 -0800530bool InputConsumer::hasPendingBatch() const {
531 return !mBatches.isEmpty();
532}
533
534ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
535 for (size_t i = 0; i < mBatches.size(); i++) {
536 const Batch& batch = mBatches.itemAt(i);
537 if (batch.event.getDeviceId() == deviceId && batch.event.getSource() == source) {
538 return i;
539 }
540 }
541 return -1;
542}
543
544void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
545 event->initialize(
546 msg->body.key.deviceId,
547 msg->body.key.source,
548 msg->body.key.action,
549 msg->body.key.flags,
550 msg->body.key.keyCode,
551 msg->body.key.scanCode,
552 msg->body.key.metaState,
553 msg->body.key.repeatCount,
554 msg->body.key.downTime,
555 msg->body.key.eventTime);
556}
557
558void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
559 size_t pointerCount = msg->body.motion.pointerCount;
560 PointerProperties pointerProperties[pointerCount];
561 PointerCoords pointerCoords[pointerCount];
562 for (size_t i = 0; i < pointerCount; i++) {
563 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
564 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
565 }
566
567 event->initialize(
568 msg->body.motion.deviceId,
569 msg->body.motion.source,
570 msg->body.motion.action,
571 msg->body.motion.flags,
572 msg->body.motion.edgeFlags,
573 msg->body.motion.metaState,
574 msg->body.motion.buttonState,
575 msg->body.motion.xOffset,
576 msg->body.motion.yOffset,
577 msg->body.motion.xPrecision,
578 msg->body.motion.yPrecision,
579 msg->body.motion.downTime,
580 msg->body.motion.eventTime,
581 pointerCount,
582 pointerProperties,
583 pointerCoords);
584}
585
586bool InputConsumer::canAppendSamples(const MotionEvent* event, const InputMessage *msg) {
587 size_t pointerCount = msg->body.motion.pointerCount;
588 if (event->getPointerCount() != pointerCount
589 || event->getAction() != msg->body.motion.action) {
590 return false;
591 }
592 for (size_t i = 0; i < pointerCount; i++) {
593 if (*event->getPointerProperties(i) != msg->body.motion.pointers[i].properties) {
594 return false;
595 }
596 }
597 return true;
598}
599
600void InputConsumer::appendSamples(MotionEvent* event, const InputMessage* msg) {
601 size_t pointerCount = msg->body.motion.pointerCount;
602 PointerCoords pointerCoords[pointerCount];
603 for (size_t i = 0; i < pointerCount; i++) {
604 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
605 }
606
607 event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
608 event->addSample(msg->body.motion.eventTime, pointerCoords);
609}
610
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700611} // namespace android