blob: 98c4bddc8d31f8e31e01ad0f2d328875f3c74bb4 [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 Brown072ec962012-02-07 14:46:57 -0800337 mChannel(channel), mDeferredEventSeq(0) {
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 // Report deferred event first, if we had to end a batch earlier than we expected
354 // during the previous time consume was called.
355 if (mDeferredEventSeq) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700356 MotionEvent* motionEvent = factory->createMotionEvent();
357 if (! motionEvent) return NO_MEMORY;
358
Jeff Brown072ec962012-02-07 14:46:57 -0800359 motionEvent->copyFrom(&mDeferredEvent, true /*keepHistory*/);
360 *outSeq = mDeferredEventSeq;
361 *outEvent = motionEvent;
362 mDeferredEventSeq = 0;
363#if DEBUG_TRANSPORT_ACTIONS
364 ALOGD("channel '%s' consumer ~ consumed deferred event, seq=%u",
365 mChannel->getName().string(), *outSeq);
366#endif
367 return OK;
368 }
369
370 // Fetch the next input message.
371 // Loop until an event can be returned or no additional events are received.
372 while (!*outEvent) {
373 InputMessage msg;
374 status_t result = mChannel->receiveMessage(&msg);
375 if (result) {
376 // Consume the next batched event unless batches are being held for later.
377 if (!mBatches.isEmpty() && (consumeBatches || result != WOULD_BLOCK)) {
378 MotionEvent* motionEvent = factory->createMotionEvent();
379 if (! motionEvent) return NO_MEMORY;
380
381 const Batch& batch = mBatches.top();
382 motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
383 *outSeq = batch.seq;
384 *outEvent = motionEvent;
385 mBatches.pop();
386#if DEBUG_TRANSPORT_ACTIONS
387 ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
388 mChannel->getName().string(), *outSeq);
389#endif
390 break;
391 }
392 return result;
Jeff Browncbee6d62012-02-03 20:11:27 -0800393 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700394
Jeff Brown072ec962012-02-07 14:46:57 -0800395 switch (msg.header.type) {
396 case InputMessage::TYPE_KEY: {
397 KeyEvent* keyEvent = factory->createKeyEvent();
398 if (!keyEvent) return NO_MEMORY;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700399
Jeff Brown072ec962012-02-07 14:46:57 -0800400 initializeKeyEvent(keyEvent, &msg);
401 *outSeq = msg.body.key.seq;
402 *outEvent = keyEvent;
403#if DEBUG_TRANSPORT_ACTIONS
404 ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
405 mChannel->getName().string(), *outSeq);
406#endif
407 break;
408 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700409
Jeff Brown072ec962012-02-07 14:46:57 -0800410 case AINPUT_EVENT_TYPE_MOTION: {
411 ssize_t batchIndex = findBatch(msg.body.motion.deviceId, msg.body.motion.source);
412 if (batchIndex >= 0) {
413 Batch& batch = mBatches.editItemAt(batchIndex);
414 if (canAppendSamples(&batch.event, &msg)) {
415 // Send finished message for the earlier part of the batch.
416 // Claim that we handled the event. (The dispatcher doesn't care either
417 // way at the moment.)
418 status_t status = sendFinishedSignal(batch.seq, true);
419 if (status) {
420 return status;
421 }
422
423 // Append to the batch and save the new sequence number for the tail end.
424 appendSamples(&batch.event, &msg);
425 batch.seq = msg.body.motion.seq;
426#if DEBUG_TRANSPORT_ACTIONS
427 ALOGD("channel '%s' consumer ~ appended to batch event",
428 mChannel->getName().string());
429#endif
430 break;
431 } else {
432 MotionEvent* motionEvent = factory->createMotionEvent();
433 if (! motionEvent) return NO_MEMORY;
434
435 // We cannot append to the batch in progress, so we need to consume
436 // the previous batch right now and defer the new event until later.
437 mDeferredEventSeq = msg.body.motion.seq;
438 initializeMotionEvent(&mDeferredEvent, &msg);
439
440 // Return the end of the previous batch.
441 motionEvent->copyFrom(&batch.event, true /*keepHistory*/);
442 *outSeq = batch.seq;
443 *outEvent = motionEvent;
444 mBatches.removeAt(batchIndex);
445#if DEBUG_TRANSPORT_ACTIONS
446 ALOGD("channel '%s' consumer ~ consumed batch event and "
447 "deferred current event, seq=%u",
448 mChannel->getName().string(), *outSeq);
449#endif
450 break;
451 }
452 }
453
454 // Start a new batch if needed.
455 if (msg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
456 || msg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
457 mBatches.push();
458 Batch& batch = mBatches.editTop();
459 batch.seq = msg.body.motion.seq;
460 initializeMotionEvent(&batch.event, &msg);
461#if DEBUG_TRANSPORT_ACTIONS
462 ALOGD("channel '%s' consumer ~ started batch event",
463 mChannel->getName().string());
464#endif
465 break;
466 }
467
468 MotionEvent* motionEvent = factory->createMotionEvent();
469 if (! motionEvent) return NO_MEMORY;
470
471 initializeMotionEvent(motionEvent, &msg);
472 *outSeq = msg.body.motion.seq;
473 *outEvent = motionEvent;
474#if DEBUG_TRANSPORT_ACTIONS
475 ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
476 mChannel->getName().string(), *outSeq);
477#endif
478 break;
479 }
480
481 default:
482 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
483 mChannel->getName().string(), msg.header.type);
484 return UNKNOWN_ERROR;
485 }
486 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700487 return OK;
488}
489
Jeff Brown072ec962012-02-07 14:46:57 -0800490status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700491#if DEBUG_TRANSPORT_ACTIONS
Jeff Brown072ec962012-02-07 14:46:57 -0800492 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
493 mChannel->getName().string(), seq, handled ? "true" : "false");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700494#endif
495
Jeff Brown072ec962012-02-07 14:46:57 -0800496 if (!seq) {
497 ALOGE("Attempted to send a finished signal with sequence number 0.");
498 return BAD_VALUE;
499 }
500
Jeff Browncbee6d62012-02-03 20:11:27 -0800501 InputMessage msg;
502 msg.header.type = InputMessage::TYPE_FINISHED;
Jeff Brown072ec962012-02-07 14:46:57 -0800503 msg.body.finished.seq = seq;
Jeff Browncbee6d62012-02-03 20:11:27 -0800504 msg.body.finished.handled = handled;
505 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700506}
507
Jeff Brown072ec962012-02-07 14:46:57 -0800508bool InputConsumer::hasPendingBatch() const {
509 return !mBatches.isEmpty();
510}
511
512ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
513 for (size_t i = 0; i < mBatches.size(); i++) {
514 const Batch& batch = mBatches.itemAt(i);
515 if (batch.event.getDeviceId() == deviceId && batch.event.getSource() == source) {
516 return i;
517 }
518 }
519 return -1;
520}
521
522void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
523 event->initialize(
524 msg->body.key.deviceId,
525 msg->body.key.source,
526 msg->body.key.action,
527 msg->body.key.flags,
528 msg->body.key.keyCode,
529 msg->body.key.scanCode,
530 msg->body.key.metaState,
531 msg->body.key.repeatCount,
532 msg->body.key.downTime,
533 msg->body.key.eventTime);
534}
535
536void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
537 size_t pointerCount = msg->body.motion.pointerCount;
538 PointerProperties pointerProperties[pointerCount];
539 PointerCoords pointerCoords[pointerCount];
540 for (size_t i = 0; i < pointerCount; i++) {
541 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
542 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
543 }
544
545 event->initialize(
546 msg->body.motion.deviceId,
547 msg->body.motion.source,
548 msg->body.motion.action,
549 msg->body.motion.flags,
550 msg->body.motion.edgeFlags,
551 msg->body.motion.metaState,
552 msg->body.motion.buttonState,
553 msg->body.motion.xOffset,
554 msg->body.motion.yOffset,
555 msg->body.motion.xPrecision,
556 msg->body.motion.yPrecision,
557 msg->body.motion.downTime,
558 msg->body.motion.eventTime,
559 pointerCount,
560 pointerProperties,
561 pointerCoords);
562}
563
564bool InputConsumer::canAppendSamples(const MotionEvent* event, const InputMessage *msg) {
565 size_t pointerCount = msg->body.motion.pointerCount;
566 if (event->getPointerCount() != pointerCount
567 || event->getAction() != msg->body.motion.action) {
568 return false;
569 }
570 for (size_t i = 0; i < pointerCount; i++) {
571 if (*event->getPointerProperties(i) != msg->body.motion.pointers[i].properties) {
572 return false;
573 }
574 }
575 return true;
576}
577
578void InputConsumer::appendSamples(MotionEvent* event, const InputMessage* msg) {
579 size_t pointerCount = msg->body.motion.pointerCount;
580 PointerCoords pointerCoords[pointerCount];
581 for (size_t i = 0; i < pointerCount; i++) {
582 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
583 }
584
585 event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
586 event->addSample(msg->body.motion.eventTime, pointerCoords);
587}
588
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700589} // namespace android