blob: 44cb6db4f1175ce12e68bdb9e5bb8b02d84e0269 [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 // Send finished message for the earlier part of the batch.
405 // Claim that we handled the event. (The dispatcher doesn't care either
406 // way at the moment.)
407 status_t status = sendFinishedSignal(batch.seq, true);
408 if (status) {
409 return status;
410 }
411
412 // Append to the batch and save the new sequence number for the tail end.
Jeff Brown90fde932012-02-13 12:44:01 -0800413 appendSamples(&batch.event, &mMsg);
414 batch.seq = mMsg.body.motion.seq;
Jeff Brown072ec962012-02-07 14:46:57 -0800415#if DEBUG_TRANSPORT_ACTIONS
416 ALOGD("channel '%s' consumer ~ appended to batch event",
417 mChannel->getName().string());
418#endif
419 break;
420 } else {
421 MotionEvent* motionEvent = factory->createMotionEvent();
422 if (! motionEvent) return NO_MEMORY;
423
424 // 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 Brown072ec962012-02-07 14:46:57 -0800427
428 // Return the end of the previous batch.
429 motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
430 *outSeq = batch.seq;
431 *outEvent = motionEvent;
432 mBatches.removeAt(batchIndex);
433#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 Brown90fde932012-02-13 12:44:01 -0800447 batch.seq = mMsg.body.motion.seq;
448 initializeMotionEvent(&batch.event, &mMsg);
Jeff Brown072ec962012-02-07 14:46:57 -0800449#if DEBUG_TRANSPORT_ACTIONS
450 ALOGD("channel '%s' consumer ~ started batch event",
451 mChannel->getName().string());
452#endif
453 break;
454 }
455
456 MotionEvent* motionEvent = factory->createMotionEvent();
457 if (! motionEvent) return NO_MEMORY;
458
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 Brown072ec962012-02-07 14:46:57 -0800478status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700479#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800480 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
481 mChannel->getName().string(), seq, handled ? "true" : "false");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700482#endif
483
Jeff Brown072ec962012-02-07 14:46:57 -0800484 if (!seq) {
485 ALOGE("Attempted to send a finished signal with sequence number 0.");
486 return BAD_VALUE;
487 }
488
Jeff Browncbee6d62012-02-03 20:11:27 -0800489 InputMessage msg;
490 msg.header.type = InputMessage::TYPE_FINISHED;
Jeff Brown072ec962012-02-07 14:46:57 -0800491 msg.body.finished.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800492 msg.body.finished.handled = handled;
493 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700494}
495
Jeff Brown072ec962012-02-07 14:46:57 -0800496bool InputConsumer::hasPendingBatch() const {
497 return !mBatches.isEmpty();
498}
499
500ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
501 for (size_t i = 0; i < mBatches.size(); i++) {
502 const Batch& batch = mBatches.itemAt(i);
503 if (batch.event.getDeviceId() == deviceId && batch.event.getSource() == source) {
504 return i;
505 }
506 }
507 return -1;
508}
509
510void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
511 event->initialize(
512 msg->body.key.deviceId,
513 msg->body.key.source,
514 msg->body.key.action,
515 msg->body.key.flags,
516 msg->body.key.keyCode,
517 msg->body.key.scanCode,
518 msg->body.key.metaState,
519 msg->body.key.repeatCount,
520 msg->body.key.downTime,
521 msg->body.key.eventTime);
522}
523
524void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
525 size_t pointerCount = msg->body.motion.pointerCount;
526 PointerProperties pointerProperties[pointerCount];
527 PointerCoords pointerCoords[pointerCount];
528 for (size_t i = 0; i < pointerCount; i++) {
529 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
530 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
531 }
532
533 event->initialize(
534 msg->body.motion.deviceId,
535 msg->body.motion.source,
536 msg->body.motion.action,
537 msg->body.motion.flags,
538 msg->body.motion.edgeFlags,
539 msg->body.motion.metaState,
540 msg->body.motion.buttonState,
541 msg->body.motion.xOffset,
542 msg->body.motion.yOffset,
543 msg->body.motion.xPrecision,
544 msg->body.motion.yPrecision,
545 msg->body.motion.downTime,
546 msg->body.motion.eventTime,
547 pointerCount,
548 pointerProperties,
549 pointerCoords);
550}
551
552bool InputConsumer::canAppendSamples(const MotionEvent* event, const InputMessage *msg) {
553 size_t pointerCount = msg->body.motion.pointerCount;
554 if (event->getPointerCount() != pointerCount
555 || event->getAction() != msg->body.motion.action) {
556 return false;
557 }
558 for (size_t i = 0; i < pointerCount; i++) {
559 if (*event->getPointerProperties(i) != msg->body.motion.pointers[i].properties) {
560 return false;
561 }
562 }
563 return true;
564}
565
566void InputConsumer::appendSamples(MotionEvent* event, const InputMessage* msg) {
567 size_t pointerCount = msg->body.motion.pointerCount;
568 PointerCoords pointerCoords[pointerCount];
569 for (size_t i = 0; i < pointerCount; i++) {
570 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
571 }
572
573 event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
574 event->addSample(msg->body.motion.eventTime, pointerCoords);
575}
576
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700577} // namespace android