blob: 70473226fd844a21fc2d9a4b617bf06a9d1aa973 [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 Browncbee6d62012-02-03 20:11:27 -080031// --- InputMessage ---
Jeff Brown4e91a182011-04-07 11:38:09 -070032
Jeff Browncbee6d62012-02-03 20:11:27 -080033bool InputMessage::isValid(size_t actualSize) const {
34 if (size() == actualSize) {
35 switch (header.type) {
36 case TYPE_KEY:
37 return true;
38 case TYPE_MOTION:
39 return body.motion.pointerCount > 0
40 && body.motion.pointerCount <= MAX_POINTERS;
41 case TYPE_FINISHED:
42 return true;
43 }
44 }
45 return false;
46}
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070047
Jeff Browncbee6d62012-02-03 20:11:27 -080048size_t InputMessage::size() const {
49 switch (header.type) {
50 case TYPE_KEY:
51 return sizeof(Header) + body.key.size();
52 case TYPE_MOTION:
53 return sizeof(Header) + body.motion.size();
54 case TYPE_FINISHED:
55 return sizeof(Header) + body.finished.size();
56 }
57 return sizeof(Header);
58}
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070059
60
61// --- InputChannel ---
62
Jeff Browncbee6d62012-02-03 20:11:27 -080063InputChannel::InputChannel(const String8& name, int fd) :
64 mName(name), mFd(fd) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070065#if DEBUG_CHANNEL_LIFECYCLE
Jeff Browncbee6d62012-02-03 20:11:27 -080066 ALOGD("Input channel constructed: name='%s', fd=%d",
67 mName.string(), fd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070068#endif
69
Jeff Browncbee6d62012-02-03 20:11:27 -080070 int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
71 LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070072 "non-blocking. errno=%d", mName.string(), errno);
73}
74
75InputChannel::~InputChannel() {
76#if DEBUG_CHANNEL_LIFECYCLE
Jeff Browncbee6d62012-02-03 20:11:27 -080077 ALOGD("Input channel destroyed: name='%s', fd=%d",
78 mName.string(), mFd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070079#endif
80
Jeff Browncbee6d62012-02-03 20:11:27 -080081 ::close(mFd);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070082}
83
84status_t InputChannel::openInputChannelPair(const String8& name,
Jeff Brown5c225b12010-06-16 01:53:36 -070085 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
Jeff Browncbee6d62012-02-03 20:11:27 -080086 int sockets[2];
87 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
88 status_t result = -errno;
89 ALOGE("channel '%s' ~ Could not create socket pair. errno=%d",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070090 name.string(), errno);
Jeff Browncbee6d62012-02-03 20:11:27 -080091 outServerChannel.clear();
92 outClientChannel.clear();
93 return result;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070094 }
95
Jeff Browncbee6d62012-02-03 20:11:27 -080096 String8 serverChannelName = name;
97 serverChannelName.append(" (server)");
98 outServerChannel = new InputChannel(serverChannelName, sockets[0]);
99
100 String8 clientChannelName = name;
101 clientChannelName.append(" (client)");
102 outClientChannel = new InputChannel(clientChannelName, sockets[1]);
103 return OK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700104}
105
Jeff Browncbee6d62012-02-03 20:11:27 -0800106status_t InputChannel::sendMessage(const InputMessage* msg) {
107 size_t msgLength = msg->size();
Jeff Brown7dae0e42010-09-16 17:04:52 -0700108 ssize_t nWrite;
109 do {
Jeff Browncbee6d62012-02-03 20:11:27 -0800110 nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
Jeff Brown7dae0e42010-09-16 17:04:52 -0700111 } while (nWrite == -1 && errno == EINTR);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700112
Jeff Browncbee6d62012-02-03 20:11:27 -0800113 if (nWrite < 0) {
114 int error = errno;
115#if DEBUG_CHANNEL_MESSAGES
116 ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
117 msg->header.type, error);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700118#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800119 if (error == EAGAIN || error == EWOULDBLOCK) {
120 return WOULD_BLOCK;
121 }
122 if (error == EPIPE || error == ENOTCONN) {
123 return DEAD_OBJECT;
124 }
125 return -error;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700126 }
127
Jeff Browncbee6d62012-02-03 20:11:27 -0800128 if (size_t(nWrite) != msgLength) {
129#if DEBUG_CHANNEL_MESSAGES
130 ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
131 mName.string(), msg->header.type);
Jeff Brown5c225b12010-06-16 01:53:36 -0700132#endif
133 return DEAD_OBJECT;
134 }
135
Jeff Browncbee6d62012-02-03 20:11:27 -0800136#if DEBUG_CHANNEL_MESSAGES
137 ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700138#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800139 return OK;
140}
141
142status_t InputChannel::receiveMessage(InputMessage* msg) {
143 ssize_t nRead;
144 do {
145 nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
146 } while (nRead == -1 && errno == EINTR);
147
148 if (nRead < 0) {
149 int error = errno;
150#if DEBUG_CHANNEL_MESSAGES
151 ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
152#endif
153 if (error == EAGAIN || error == EWOULDBLOCK) {
154 return WOULD_BLOCK;
155 }
156 if (error == EPIPE || error == ENOTCONN) {
157 return DEAD_OBJECT;
158 }
159 return -error;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700160 }
161
Jeff Browncbee6d62012-02-03 20:11:27 -0800162 if (nRead == 0) { // check for EOF
163#if DEBUG_CHANNEL_MESSAGES
164 ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700165#endif
Jeff Browncbee6d62012-02-03 20:11:27 -0800166 return DEAD_OBJECT;
167 }
168
169 if (!msg->isValid(nRead)) {
170#if DEBUG_CHANNEL_MESSAGES
171 ALOGD("channel '%s' ~ received invalid message", mName.string());
172#endif
173 return BAD_VALUE;
174 }
175
176#if DEBUG_CHANNEL_MESSAGES
177 ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
178#endif
179 return OK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700180}
181
182
183// --- InputPublisher ---
184
185InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
Jeff Browncbee6d62012-02-03 20:11:27 -0800186 mChannel(channel) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700187}
188
189InputPublisher::~InputPublisher() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700190}
191
192status_t InputPublisher::publishKeyEvent(
193 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700194 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700195 int32_t action,
196 int32_t flags,
197 int32_t keyCode,
198 int32_t scanCode,
199 int32_t metaState,
200 int32_t repeatCount,
201 nsecs_t downTime,
202 nsecs_t eventTime) {
203#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000204 ALOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, source=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700205 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700206 "downTime=%lld, eventTime=%lld",
207 mChannel->getName().string(),
Jeff Brownc5ed5912010-07-14 18:48:53 -0700208 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700209 downTime, eventTime);
210#endif
211
Jeff Browncbee6d62012-02-03 20:11:27 -0800212 InputMessage msg;
213 msg.header.type = InputMessage::TYPE_KEY;
214 msg.body.key.deviceId = deviceId;
215 msg.body.key.source = source;
216 msg.body.key.action = action;
217 msg.body.key.flags = flags;
218 msg.body.key.keyCode = keyCode;
219 msg.body.key.scanCode = scanCode;
220 msg.body.key.metaState = metaState;
221 msg.body.key.repeatCount = repeatCount;
222 msg.body.key.downTime = downTime;
223 msg.body.key.eventTime = eventTime;
224 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700225}
226
227status_t InputPublisher::publishMotionEvent(
228 int32_t deviceId,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700229 int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700230 int32_t action,
Jeff Brown85a31762010-09-01 17:01:00 -0700231 int32_t flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700232 int32_t edgeFlags,
233 int32_t metaState,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700234 int32_t buttonState,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700235 float xOffset,
236 float yOffset,
237 float xPrecision,
238 float yPrecision,
239 nsecs_t downTime,
240 nsecs_t eventTime,
241 size_t pointerCount,
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700242 const PointerProperties* pointerProperties,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700243 const PointerCoords* pointerCoords) {
244#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000245 ALOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=0x%x, "
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700246 "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
247 "xOffset=%f, yOffset=%f, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700248 "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
249 "pointerCount=%d",
250 mChannel->getName().string(),
Jeff Brownfe9f8ab2011-05-06 18:20:01 -0700251 deviceId, source, action, flags, edgeFlags, metaState, buttonState,
252 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700253#endif
254
255 if (pointerCount > MAX_POINTERS || pointerCount < 1) {
Steve Block3762c312012-01-06 19:20:56 +0000256 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700257 mChannel->getName().string(), pointerCount);
258 return BAD_VALUE;
259 }
260
Jeff Browncbee6d62012-02-03 20:11:27 -0800261 InputMessage msg;
262 msg.header.type = InputMessage::TYPE_MOTION;
263 msg.body.motion.deviceId = deviceId;
264 msg.body.motion.source = source;
265 msg.body.motion.action = action;
266 msg.body.motion.flags = flags;
267 msg.body.motion.edgeFlags = edgeFlags;
268 msg.body.motion.metaState = metaState;
269 msg.body.motion.buttonState = buttonState;
270 msg.body.motion.xOffset = xOffset;
271 msg.body.motion.yOffset = yOffset;
272 msg.body.motion.xPrecision = xPrecision;
273 msg.body.motion.yPrecision = yPrecision;
274 msg.body.motion.downTime = downTime;
275 msg.body.motion.eventTime = eventTime;
276 msg.body.motion.pointerCount = pointerCount;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700277 for (size_t i = 0; i < pointerCount; i++) {
Jeff Browncbee6d62012-02-03 20:11:27 -0800278 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
279 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700280 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800281 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700282}
283
Jeff Brown49ed71d2010-12-06 17:13:33 -0800284status_t InputPublisher::receiveFinishedSignal(bool* outHandled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700285#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000286 ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700287 mChannel->getName().string());
288#endif
289
Jeff Browncbee6d62012-02-03 20:11:27 -0800290 InputMessage msg;
291 status_t result = mChannel->receiveMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700292 if (result) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800293 *outHandled = false;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700294 return result;
295 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800296 if (msg.header.type != InputMessage::TYPE_FINISHED) {
297 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
298 mChannel->getName().string(), msg.header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700299 return UNKNOWN_ERROR;
300 }
Jeff Browncbee6d62012-02-03 20:11:27 -0800301 *outHandled = msg.body.finished.handled;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700302 return OK;
303}
304
305// --- InputConsumer ---
306
307InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
Jeff Browncbee6d62012-02-03 20:11:27 -0800308 mChannel(channel) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700309}
310
311InputConsumer::~InputConsumer() {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700312}
313
Jeff Brown5c225b12010-06-16 01:53:36 -0700314status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent** outEvent) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700315#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000316 ALOGD("channel '%s' consumer ~ consume",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700317 mChannel->getName().string());
318#endif
319
Jeff Brown5c225b12010-06-16 01:53:36 -0700320 *outEvent = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700321
Jeff Browncbee6d62012-02-03 20:11:27 -0800322 InputMessage msg;
323 status_t result = mChannel->receiveMessage(&msg);
324 if (result) {
325 return result;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700326 }
327
Jeff Browncbee6d62012-02-03 20:11:27 -0800328 switch (msg.header.type) {
329 case InputMessage::TYPE_KEY: {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700330 KeyEvent* keyEvent = factory->createKeyEvent();
Jeff Browncbee6d62012-02-03 20:11:27 -0800331 if (!keyEvent) return NO_MEMORY;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700332
Jeff Browncbee6d62012-02-03 20:11:27 -0800333 keyEvent->initialize(
334 msg.body.key.deviceId,
335 msg.body.key.source,
336 msg.body.key.action,
337 msg.body.key.flags,
338 msg.body.key.keyCode,
339 msg.body.key.scanCode,
340 msg.body.key.metaState,
341 msg.body.key.repeatCount,
342 msg.body.key.downTime,
343 msg.body.key.eventTime);
Jeff Brown5c225b12010-06-16 01:53:36 -0700344 *outEvent = keyEvent;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700345 break;
346 }
347
Jeff Brownc5ed5912010-07-14 18:48:53 -0700348 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700349 MotionEvent* motionEvent = factory->createMotionEvent();
350 if (! motionEvent) return NO_MEMORY;
351
Jeff Browncbee6d62012-02-03 20:11:27 -0800352 size_t pointerCount = msg.body.motion.pointerCount;
353 PointerProperties pointerProperties[pointerCount];
354 PointerCoords pointerCoords[pointerCount];
355 for (size_t i = 0; i < pointerCount; i++) {
356 pointerProperties[i].copyFrom(msg.body.motion.pointers[i].properties);
357 pointerCoords[i].copyFrom(msg.body.motion.pointers[i].coords);
358 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700359
Jeff Browncbee6d62012-02-03 20:11:27 -0800360 motionEvent->initialize(
361 msg.body.motion.deviceId,
362 msg.body.motion.source,
363 msg.body.motion.action,
364 msg.body.motion.flags,
365 msg.body.motion.edgeFlags,
366 msg.body.motion.metaState,
367 msg.body.motion.buttonState,
368 msg.body.motion.xOffset,
369 msg.body.motion.yOffset,
370 msg.body.motion.xPrecision,
371 msg.body.motion.yPrecision,
372 msg.body.motion.downTime,
373 msg.body.motion.eventTime,
374 pointerCount,
375 pointerProperties,
376 pointerCoords);
Jeff Brown5c225b12010-06-16 01:53:36 -0700377 *outEvent = motionEvent;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700378 break;
379 }
380
381 default:
Jeff Browncbee6d62012-02-03 20:11:27 -0800382 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
383 mChannel->getName().string(), msg.header.type);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700384 return UNKNOWN_ERROR;
385 }
386
387 return OK;
388}
389
Jeff Brown3915bb82010-11-05 15:02:16 -0700390status_t InputConsumer::sendFinishedSignal(bool handled) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700391#if DEBUG_TRANSPORT_ACTIONS
Steve Block5baa3a62011-12-20 16:23:08 +0000392 ALOGD("channel '%s' consumer ~ sendFinishedSignal: handled=%d",
Jeff Brown3915bb82010-11-05 15:02:16 -0700393 mChannel->getName().string(), handled);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700394#endif
395
Jeff Browncbee6d62012-02-03 20:11:27 -0800396 InputMessage msg;
397 msg.header.type = InputMessage::TYPE_FINISHED;
398 msg.body.finished.handled = handled;
399 return mChannel->sendMessage(&msg);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700400}
401
402} // namespace android