blob: f7bcb68cc6a0642809d1cc0d86fa78615a935f84 [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 Brown5c225b12010-06-16 01:53:36 -070016#define DEBUG_TRANSPORT_ACTIONS 0
Jeff Browncbee6d62012-02-03 20:11:27 -080017// Log debug messages about transport actions
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(
206 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700207 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700208 int32_t action,
209 int32_t flags,
210 int32_t keyCode,
211 int32_t scanCode,
212 int32_t metaState,
213 int32_t repeatCount,
214 nsecs_t downTime,
215 nsecs_t eventTime) {
216#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000217 ALOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, source=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700218 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700219 "downTime=%lld, eventTime=%lld",
220 mChannel->getName().string(),
Jeff Brownc5ed5912010-07-14 18:48:53 -0700221 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700222 downTime, eventTime);
223#endif
224
Jeff Browncbee6d62012-02-03 20:11:27 -0800225 InputMessage msg;
226 msg.header.type = InputMessage::TYPE_KEY;
227 msg.body.key.deviceId = deviceId;
228 msg.body.key.source = source;
229 msg.body.key.action = action;
230 msg.body.key.flags = flags;
231 msg.body.key.keyCode = keyCode;
232 msg.body.key.scanCode = scanCode;
233 msg.body.key.metaState = metaState;
234 msg.body.key.repeatCount = repeatCount;
235 msg.body.key.downTime = downTime;
236 msg.body.key.eventTime = eventTime;
237 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700238}
239
240status_t InputPublisher::publishMotionEvent(
241 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700242 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700243 int32_t action,
Jeff Brown85a31762010-09-01 17:01:00 -0700244 int32_t flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700245 int32_t edgeFlags,
246 int32_t metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700247 int32_t buttonState,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700248 float xOffset,
249 float yOffset,
250 float xPrecision,
251 float yPrecision,
252 nsecs_t downTime,
253 nsecs_t eventTime,
254 size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700255 const PointerProperties* pointerProperties,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700256 const PointerCoords* pointerCoords) {
257#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000258 ALOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=0x%x, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700259 "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
260 "xOffset=%f, yOffset=%f, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700261 "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
262 "pointerCount=%d",
263 mChannel->getName().string(),
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700264 deviceId, source, action, flags, edgeFlags, metaState, buttonState,
265 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700266#endif
267
268 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Steve Block3762c312012-01-06 19:20:56 +0000269 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700270 mChannel->getName().string(), pointerCount);
271 return BAD_VALUE;
272 }
273
Jeff Browncbee6d62012-02-03 20:11:27 -0800274 InputMessage msg;
275 msg.header.type = InputMessage::TYPE_MOTION;
276 msg.body.motion.deviceId = deviceId;
277 msg.body.motion.source = source;
278 msg.body.motion.action = action;
279 msg.body.motion.flags = flags;
280 msg.body.motion.edgeFlags = edgeFlags;
281 msg.body.motion.metaState = metaState;
282 msg.body.motion.buttonState = buttonState;
283 msg.body.motion.xOffset = xOffset;
284 msg.body.motion.yOffset = yOffset;
285 msg.body.motion.xPrecision = xPrecision;
286 msg.body.motion.yPrecision = yPrecision;
287 msg.body.motion.downTime = downTime;
288 msg.body.motion.eventTime = eventTime;
289 msg.body.motion.pointerCount = pointerCount;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700290 for (size_t i = 0; i < pointerCount; i++) {
Jeff Browncbee6d62012-02-03 20:11:27 -0800291 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
292 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700293 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800294 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700295}
296
Jeff Brown49ed71d2010-12-06 17:13:33 -0800297status_t InputPublisher::receiveFinishedSignal(bool* outHandled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700298#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000299 ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700300 mChannel->getName().string());
301#endif
302
Jeff Browncbee6d62012-02-03 20:11:27 -0800303 InputMessage msg;
304 status_t result = mChannel->receiveMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700305 if (result) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800306 *outHandled = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700307 return result;
308 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800309 if (msg.header.type != InputMessage::TYPE_FINISHED) {
310 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
311 mChannel->getName().string(), msg.header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700312 return UNKNOWN_ERROR;
313 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800314 *outHandled = msg.body.finished.handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700315 return OK;
316}
317
318// --- InputConsumer ---
319
320InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
Jeff Browncbee6d62012-02-03 20:11:27 -0800321 mChannel(channel) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700322}
323
324InputConsumer::~InputConsumer() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700325}
326
Jeff Brown5c225b12010-06-16 01:53:36 -0700327status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent** outEvent) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700328#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000329 ALOGD("channel '%s' consumer ~ consume",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700330 mChannel->getName().string());
331#endif
332
Jeff Brown5c225b12010-06-16 01:53:36 -0700333 *outEvent = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700334
Jeff Browncbee6d62012-02-03 20:11:27 -0800335 InputMessage msg;
336 status_t result = mChannel->receiveMessage(&msg);
337 if (result) {
338 return result;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700339 }
340
Jeff Browncbee6d62012-02-03 20:11:27 -0800341 switch (msg.header.type) {
342 case InputMessage::TYPE_KEY: {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700343 KeyEvent* keyEvent = factory->createKeyEvent();
Jeff Browncbee6d62012-02-03 20:11:27 -0800344 if (!keyEvent) return NO_MEMORY;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700345
Jeff Browncbee6d62012-02-03 20:11:27 -0800346 keyEvent->initialize(
347 msg.body.key.deviceId,
348 msg.body.key.source,
349 msg.body.key.action,
350 msg.body.key.flags,
351 msg.body.key.keyCode,
352 msg.body.key.scanCode,
353 msg.body.key.metaState,
354 msg.body.key.repeatCount,
355 msg.body.key.downTime,
356 msg.body.key.eventTime);
Jeff Brown5c225b12010-06-16 01:53:36 -0700357 *outEvent = keyEvent;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700358 break;
359 }
360
Jeff Brownc5ed5912010-07-14 18:48:53 -0700361 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700362 MotionEvent* motionEvent = factory->createMotionEvent();
363 if (! motionEvent) return NO_MEMORY;
364
Jeff Browncbee6d62012-02-03 20:11:27 -0800365 size_t pointerCount = msg.body.motion.pointerCount;
366 PointerProperties pointerProperties[pointerCount];
367 PointerCoords pointerCoords[pointerCount];
368 for (size_t i = 0; i < pointerCount; i++) {
369 pointerProperties[i].copyFrom(msg.body.motion.pointers[i].properties);
370 pointerCoords[i].copyFrom(msg.body.motion.pointers[i].coords);
371 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700372
Jeff Browncbee6d62012-02-03 20:11:27 -0800373 motionEvent->initialize(
374 msg.body.motion.deviceId,
375 msg.body.motion.source,
376 msg.body.motion.action,
377 msg.body.motion.flags,
378 msg.body.motion.edgeFlags,
379 msg.body.motion.metaState,
380 msg.body.motion.buttonState,
381 msg.body.motion.xOffset,
382 msg.body.motion.yOffset,
383 msg.body.motion.xPrecision,
384 msg.body.motion.yPrecision,
385 msg.body.motion.downTime,
386 msg.body.motion.eventTime,
387 pointerCount,
388 pointerProperties,
389 pointerCoords);
Jeff Brown5c225b12010-06-16 01:53:36 -0700390 *outEvent = motionEvent;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700391 break;
392 }
393
394 default:
Jeff Browncbee6d62012-02-03 20:11:27 -0800395 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
396 mChannel->getName().string(), msg.header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700397 return UNKNOWN_ERROR;
398 }
399
400 return OK;
401}
402
Jeff Brown3915bb82010-11-05 15:02:16 -0700403status_t InputConsumer::sendFinishedSignal(bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700404#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000405 ALOGD("channel '%s' consumer ~ sendFinishedSignal: handled=%d",
Jeff Brown3915bb82010-11-05 15:02:16 -0700406 mChannel->getName().string(), handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700407#endif
408
Jeff Browncbee6d62012-02-03 20:11:27 -0800409 InputMessage msg;
410 msg.header.type = InputMessage::TYPE_FINISHED;
411 msg.body.finished.handled = handled;
412 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700413}
414
415} // namespace android