1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gonk/libui/InputTransport.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,957 @@ 1.4 +// 1.5 +// Copyright 2010 The Android Open Source Project 1.6 +// 1.7 +// Provides a shared memory transport for input events. 1.8 +// 1.9 +#define LOG_TAG "InputTransport" 1.10 + 1.11 +//#define LOG_NDEBUG 0 1.12 + 1.13 +// Log debug messages about channel messages (send message, receive message) 1.14 +#define DEBUG_CHANNEL_MESSAGES 0 1.15 + 1.16 +// Log debug messages whenever InputChannel objects are created/destroyed 1.17 +#define DEBUG_CHANNEL_LIFECYCLE 0 1.18 + 1.19 +// Log debug messages about transport actions 1.20 +#define DEBUG_TRANSPORT_ACTIONS 0 1.21 + 1.22 +// Log debug messages about touch event resampling 1.23 +#define DEBUG_RESAMPLING 0 1.24 + 1.25 + 1.26 +#include "cutils_log.h" 1.27 +#include <cutils/properties.h> 1.28 +#include <errno.h> 1.29 +#include <fcntl.h> 1.30 +#include "InputTransport.h" 1.31 +#include <unistd.h> 1.32 +#include <sys/types.h> 1.33 +#include <sys/socket.h> 1.34 +#include <math.h> 1.35 + 1.36 + 1.37 +namespace android { 1.38 + 1.39 +// Socket buffer size. The default is typically about 128KB, which is much larger than 1.40 +// we really need. So we make it smaller. It just needs to be big enough to hold 1.41 +// a few dozen large multi-finger motion events in the case where an application gets 1.42 +// behind processing touches. 1.43 +static const size_t SOCKET_BUFFER_SIZE = 32 * 1024; 1.44 + 1.45 +// Nanoseconds per milliseconds. 1.46 +static const nsecs_t NANOS_PER_MS = 1000000; 1.47 + 1.48 +// Latency added during resampling. A few milliseconds doesn't hurt much but 1.49 +// reduces the impact of mispredicted touch positions. 1.50 +static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS; 1.51 + 1.52 +// Minimum time difference between consecutive samples before attempting to resample. 1.53 +static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS; 1.54 + 1.55 +// Maximum time to predict forward from the last known state, to avoid predicting too 1.56 +// far into the future. This time is further bounded by 50% of the last time delta. 1.57 +static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS; 1.58 + 1.59 +template<typename T> 1.60 +inline static T min(const T& a, const T& b) { 1.61 + return a < b ? a : b; 1.62 +} 1.63 + 1.64 +inline static float lerp(float a, float b, float alpha) { 1.65 + return a + alpha * (b - a); 1.66 +} 1.67 + 1.68 +// --- InputMessage --- 1.69 + 1.70 +bool InputMessage::isValid(size_t actualSize) const { 1.71 + if (size() == actualSize) { 1.72 + switch (header.type) { 1.73 + case TYPE_KEY: 1.74 + return true; 1.75 + case TYPE_MOTION: 1.76 + return body.motion.pointerCount > 0 1.77 + && body.motion.pointerCount <= MAX_POINTERS; 1.78 + case TYPE_FINISHED: 1.79 + return true; 1.80 + } 1.81 + } 1.82 + return false; 1.83 +} 1.84 + 1.85 +size_t InputMessage::size() const { 1.86 + switch (header.type) { 1.87 + case TYPE_KEY: 1.88 + return sizeof(Header) + body.key.size(); 1.89 + case TYPE_MOTION: 1.90 + return sizeof(Header) + body.motion.size(); 1.91 + case TYPE_FINISHED: 1.92 + return sizeof(Header) + body.finished.size(); 1.93 + } 1.94 + return sizeof(Header); 1.95 +} 1.96 + 1.97 + 1.98 +// --- InputChannel --- 1.99 + 1.100 +InputChannel::InputChannel(const String8& name, int fd) : 1.101 + mName(name), mFd(fd) { 1.102 +#if DEBUG_CHANNEL_LIFECYCLE 1.103 + ALOGD("Input channel constructed: name='%s', fd=%d", 1.104 + mName.string(), fd); 1.105 +#endif 1.106 + 1.107 + int result = fcntl(mFd, F_SETFL, O_NONBLOCK); 1.108 + LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket " 1.109 + "non-blocking. errno=%d", mName.string(), errno); 1.110 +} 1.111 + 1.112 +InputChannel::~InputChannel() { 1.113 +#if DEBUG_CHANNEL_LIFECYCLE 1.114 + ALOGD("Input channel destroyed: name='%s', fd=%d", 1.115 + mName.string(), mFd); 1.116 +#endif 1.117 + 1.118 + ::close(mFd); 1.119 +} 1.120 + 1.121 +status_t InputChannel::openInputChannelPair(const String8& name, 1.122 + sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) { 1.123 + int sockets[2]; 1.124 + if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) { 1.125 + status_t result = -errno; 1.126 + ALOGE("channel '%s' ~ Could not create socket pair. errno=%d", 1.127 + name.string(), errno); 1.128 + outServerChannel.clear(); 1.129 + outClientChannel.clear(); 1.130 + return result; 1.131 + } 1.132 + 1.133 + int bufferSize = SOCKET_BUFFER_SIZE; 1.134 + setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); 1.135 + setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); 1.136 + setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); 1.137 + setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); 1.138 + 1.139 + String8 serverChannelName = name; 1.140 + serverChannelName.append(" (server)"); 1.141 + outServerChannel = new InputChannel(serverChannelName, sockets[0]); 1.142 + 1.143 + String8 clientChannelName = name; 1.144 + clientChannelName.append(" (client)"); 1.145 + outClientChannel = new InputChannel(clientChannelName, sockets[1]); 1.146 + return OK; 1.147 +} 1.148 + 1.149 +status_t InputChannel::sendMessage(const InputMessage* msg) { 1.150 + size_t msgLength = msg->size(); 1.151 + ssize_t nWrite; 1.152 + do { 1.153 + nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); 1.154 + } while (nWrite == -1 && errno == EINTR); 1.155 + 1.156 + if (nWrite < 0) { 1.157 + int error = errno; 1.158 +#if DEBUG_CHANNEL_MESSAGES 1.159 + ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(), 1.160 + msg->header.type, error); 1.161 +#endif 1.162 + if (error == EAGAIN || error == EWOULDBLOCK) { 1.163 + return WOULD_BLOCK; 1.164 + } 1.165 + if (error == EPIPE || error == ENOTCONN) { 1.166 + return DEAD_OBJECT; 1.167 + } 1.168 + return -error; 1.169 + } 1.170 + 1.171 + if (size_t(nWrite) != msgLength) { 1.172 +#if DEBUG_CHANNEL_MESSAGES 1.173 + ALOGD("channel '%s' ~ error sending message type %d, send was incomplete", 1.174 + mName.string(), msg->header.type); 1.175 +#endif 1.176 + return DEAD_OBJECT; 1.177 + } 1.178 + 1.179 +#if DEBUG_CHANNEL_MESSAGES 1.180 + ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type); 1.181 +#endif 1.182 + return OK; 1.183 +} 1.184 + 1.185 +status_t InputChannel::receiveMessage(InputMessage* msg) { 1.186 + ssize_t nRead; 1.187 + do { 1.188 + nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT); 1.189 + } while (nRead == -1 && errno == EINTR); 1.190 + 1.191 + if (nRead < 0) { 1.192 + int error = errno; 1.193 +#if DEBUG_CHANNEL_MESSAGES 1.194 + ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno); 1.195 +#endif 1.196 + if (error == EAGAIN || error == EWOULDBLOCK) { 1.197 + return WOULD_BLOCK; 1.198 + } 1.199 + if (error == EPIPE || error == ENOTCONN) { 1.200 + return DEAD_OBJECT; 1.201 + } 1.202 + return -error; 1.203 + } 1.204 + 1.205 + if (nRead == 0) { // check for EOF 1.206 +#if DEBUG_CHANNEL_MESSAGES 1.207 + ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string()); 1.208 +#endif 1.209 + return DEAD_OBJECT; 1.210 + } 1.211 + 1.212 + if (!msg->isValid(nRead)) { 1.213 +#if DEBUG_CHANNEL_MESSAGES 1.214 + ALOGD("channel '%s' ~ received invalid message", mName.string()); 1.215 +#endif 1.216 + return BAD_VALUE; 1.217 + } 1.218 + 1.219 +#if DEBUG_CHANNEL_MESSAGES 1.220 + ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type); 1.221 +#endif 1.222 + return OK; 1.223 +} 1.224 + 1.225 +sp<InputChannel> InputChannel::dup() const { 1.226 + int fd = ::dup(getFd()); 1.227 + return fd >= 0 ? new InputChannel(getName(), fd) : NULL; 1.228 +} 1.229 + 1.230 + 1.231 +// --- InputPublisher --- 1.232 + 1.233 +InputPublisher::InputPublisher(const sp<InputChannel>& channel) : 1.234 + mChannel(channel) { 1.235 +} 1.236 + 1.237 +InputPublisher::~InputPublisher() { 1.238 +} 1.239 + 1.240 +status_t InputPublisher::publishKeyEvent( 1.241 + uint32_t seq, 1.242 + int32_t deviceId, 1.243 + int32_t source, 1.244 + int32_t action, 1.245 + int32_t flags, 1.246 + int32_t keyCode, 1.247 + int32_t scanCode, 1.248 + int32_t metaState, 1.249 + int32_t repeatCount, 1.250 + nsecs_t downTime, 1.251 + nsecs_t eventTime) { 1.252 +#if DEBUG_TRANSPORT_ACTIONS 1.253 + ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, " 1.254 + "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d," 1.255 + "downTime=%lld, eventTime=%lld", 1.256 + mChannel->getName().string(), seq, 1.257 + deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, 1.258 + downTime, eventTime); 1.259 +#endif 1.260 + 1.261 + if (!seq) { 1.262 + ALOGE("Attempted to publish a key event with sequence number 0."); 1.263 + return BAD_VALUE; 1.264 + } 1.265 + 1.266 + InputMessage msg; 1.267 + msg.header.type = InputMessage::TYPE_KEY; 1.268 + msg.body.key.seq = seq; 1.269 + msg.body.key.deviceId = deviceId; 1.270 + msg.body.key.source = source; 1.271 + msg.body.key.action = action; 1.272 + msg.body.key.flags = flags; 1.273 + msg.body.key.keyCode = keyCode; 1.274 + msg.body.key.scanCode = scanCode; 1.275 + msg.body.key.metaState = metaState; 1.276 + msg.body.key.repeatCount = repeatCount; 1.277 + msg.body.key.downTime = downTime; 1.278 + msg.body.key.eventTime = eventTime; 1.279 + return mChannel->sendMessage(&msg); 1.280 +} 1.281 + 1.282 +status_t InputPublisher::publishMotionEvent( 1.283 + uint32_t seq, 1.284 + int32_t deviceId, 1.285 + int32_t source, 1.286 + int32_t action, 1.287 + int32_t flags, 1.288 + int32_t edgeFlags, 1.289 + int32_t metaState, 1.290 + int32_t buttonState, 1.291 + float xOffset, 1.292 + float yOffset, 1.293 + float xPrecision, 1.294 + float yPrecision, 1.295 + nsecs_t downTime, 1.296 + nsecs_t eventTime, 1.297 + size_t pointerCount, 1.298 + const PointerProperties* pointerProperties, 1.299 + const PointerCoords* pointerCoords) { 1.300 +#if DEBUG_TRANSPORT_ACTIONS 1.301 + ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, " 1.302 + "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, " 1.303 + "xOffset=%f, yOffset=%f, " 1.304 + "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, " 1.305 + "pointerCount=%d", 1.306 + mChannel->getName().string(), seq, 1.307 + deviceId, source, action, flags, edgeFlags, metaState, buttonState, 1.308 + xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount); 1.309 +#endif 1.310 + 1.311 + if (!seq) { 1.312 + ALOGE("Attempted to publish a motion event with sequence number 0."); 1.313 + return BAD_VALUE; 1.314 + } 1.315 + 1.316 + if (pointerCount > MAX_POINTERS || pointerCount < 1) { 1.317 + ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.", 1.318 + mChannel->getName().string(), pointerCount); 1.319 + return BAD_VALUE; 1.320 + } 1.321 + 1.322 + InputMessage msg; 1.323 + msg.header.type = InputMessage::TYPE_MOTION; 1.324 + msg.body.motion.seq = seq; 1.325 + msg.body.motion.deviceId = deviceId; 1.326 + msg.body.motion.source = source; 1.327 + msg.body.motion.action = action; 1.328 + msg.body.motion.flags = flags; 1.329 + msg.body.motion.edgeFlags = edgeFlags; 1.330 + msg.body.motion.metaState = metaState; 1.331 + msg.body.motion.buttonState = buttonState; 1.332 + msg.body.motion.xOffset = xOffset; 1.333 + msg.body.motion.yOffset = yOffset; 1.334 + msg.body.motion.xPrecision = xPrecision; 1.335 + msg.body.motion.yPrecision = yPrecision; 1.336 + msg.body.motion.downTime = downTime; 1.337 + msg.body.motion.eventTime = eventTime; 1.338 + msg.body.motion.pointerCount = pointerCount; 1.339 + for (size_t i = 0; i < pointerCount; i++) { 1.340 + msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]); 1.341 + msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]); 1.342 + } 1.343 + return mChannel->sendMessage(&msg); 1.344 +} 1.345 + 1.346 +status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) { 1.347 +#if DEBUG_TRANSPORT_ACTIONS 1.348 + ALOGD("channel '%s' publisher ~ receiveFinishedSignal", 1.349 + mChannel->getName().string()); 1.350 +#endif 1.351 + 1.352 + InputMessage msg; 1.353 + status_t result = mChannel->receiveMessage(&msg); 1.354 + if (result) { 1.355 + *outSeq = 0; 1.356 + *outHandled = false; 1.357 + return result; 1.358 + } 1.359 + if (msg.header.type != InputMessage::TYPE_FINISHED) { 1.360 + ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer", 1.361 + mChannel->getName().string(), msg.header.type); 1.362 + return UNKNOWN_ERROR; 1.363 + } 1.364 + *outSeq = msg.body.finished.seq; 1.365 + *outHandled = msg.body.finished.handled; 1.366 + return OK; 1.367 +} 1.368 + 1.369 +// --- InputConsumer --- 1.370 + 1.371 +InputConsumer::InputConsumer(const sp<InputChannel>& channel) : 1.372 + mResampleTouch(isTouchResamplingEnabled()), 1.373 + mChannel(channel), mMsgDeferred(false) { 1.374 +} 1.375 + 1.376 +InputConsumer::~InputConsumer() { 1.377 +} 1.378 + 1.379 +bool InputConsumer::isTouchResamplingEnabled() { 1.380 + char value[PROPERTY_VALUE_MAX]; 1.381 + int length = property_get("debug.inputconsumer.resample", value, NULL); 1.382 + if (length > 0) { 1.383 + if (!strcmp("0", value)) { 1.384 + return false; 1.385 + } 1.386 + if (strcmp("1", value)) { 1.387 + ALOGD("Unrecognized property value for 'debug.inputconsumer.resample'. " 1.388 + "Use '1' or '0'."); 1.389 + } 1.390 + } 1.391 + return true; 1.392 +} 1.393 + 1.394 +status_t InputConsumer::consume(InputEventFactoryInterface* factory, 1.395 + bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) { 1.396 +#if DEBUG_TRANSPORT_ACTIONS 1.397 + ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld", 1.398 + mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime); 1.399 +#endif 1.400 + 1.401 + *outSeq = 0; 1.402 + *outEvent = NULL; 1.403 + 1.404 + // Fetch the next input message. 1.405 + // Loop until an event can be returned or no additional events are received. 1.406 + while (!*outEvent) { 1.407 + if (mMsgDeferred) { 1.408 + // mMsg contains a valid input message from the previous call to consume 1.409 + // that has not yet been processed. 1.410 + mMsgDeferred = false; 1.411 + } else { 1.412 + // Receive a fresh message. 1.413 + status_t result = mChannel->receiveMessage(&mMsg); 1.414 + if (result) { 1.415 + // Consume the next batched event unless batches are being held for later. 1.416 + if (consumeBatches || result != WOULD_BLOCK) { 1.417 + result = consumeBatch(factory, frameTime, outSeq, outEvent); 1.418 + if (*outEvent) { 1.419 +#if DEBUG_TRANSPORT_ACTIONS 1.420 + ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u", 1.421 + mChannel->getName().string(), *outSeq); 1.422 +#endif 1.423 + break; 1.424 + } 1.425 + } 1.426 + return result; 1.427 + } 1.428 + } 1.429 + 1.430 + switch (mMsg.header.type) { 1.431 + case InputMessage::TYPE_KEY: { 1.432 + KeyEvent* keyEvent = factory->createKeyEvent(); 1.433 + if (!keyEvent) return NO_MEMORY; 1.434 + 1.435 + initializeKeyEvent(keyEvent, &mMsg); 1.436 + *outSeq = mMsg.body.key.seq; 1.437 + *outEvent = keyEvent; 1.438 +#if DEBUG_TRANSPORT_ACTIONS 1.439 + ALOGD("channel '%s' consumer ~ consumed key event, seq=%u", 1.440 + mChannel->getName().string(), *outSeq); 1.441 +#endif 1.442 + break; 1.443 + } 1.444 + 1.445 + case AINPUT_EVENT_TYPE_MOTION: { 1.446 + ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source); 1.447 + if (batchIndex >= 0) { 1.448 + Batch& batch = mBatches.editItemAt(batchIndex); 1.449 + if (canAddSample(batch, &mMsg)) { 1.450 + batch.samples.push(mMsg); 1.451 +#if DEBUG_TRANSPORT_ACTIONS 1.452 + ALOGD("channel '%s' consumer ~ appended to batch event", 1.453 + mChannel->getName().string()); 1.454 +#endif 1.455 + break; 1.456 + } else { 1.457 + // We cannot append to the batch in progress, so we need to consume 1.458 + // the previous batch right now and defer the new message until later. 1.459 + mMsgDeferred = true; 1.460 + status_t result = consumeSamples(factory, 1.461 + batch, batch.samples.size(), outSeq, outEvent); 1.462 + mBatches.removeAt(batchIndex); 1.463 + if (result) { 1.464 + return result; 1.465 + } 1.466 +#if DEBUG_TRANSPORT_ACTIONS 1.467 + ALOGD("channel '%s' consumer ~ consumed batch event and " 1.468 + "deferred current event, seq=%u", 1.469 + mChannel->getName().string(), *outSeq); 1.470 +#endif 1.471 + break; 1.472 + } 1.473 + } 1.474 + 1.475 + // Start a new batch if needed. 1.476 + if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE 1.477 + || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) { 1.478 + mBatches.push(); 1.479 + Batch& batch = mBatches.editTop(); 1.480 + batch.samples.push(mMsg); 1.481 +#if DEBUG_TRANSPORT_ACTIONS 1.482 + ALOGD("channel '%s' consumer ~ started batch event", 1.483 + mChannel->getName().string()); 1.484 +#endif 1.485 + break; 1.486 + } 1.487 + 1.488 + MotionEvent* motionEvent = factory->createMotionEvent(); 1.489 + if (! motionEvent) return NO_MEMORY; 1.490 + 1.491 + updateTouchState(&mMsg); 1.492 + initializeMotionEvent(motionEvent, &mMsg); 1.493 + *outSeq = mMsg.body.motion.seq; 1.494 + *outEvent = motionEvent; 1.495 +#if DEBUG_TRANSPORT_ACTIONS 1.496 + ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u", 1.497 + mChannel->getName().string(), *outSeq); 1.498 +#endif 1.499 + break; 1.500 + } 1.501 + 1.502 + default: 1.503 + ALOGE("channel '%s' consumer ~ Received unexpected message of type %d", 1.504 + mChannel->getName().string(), mMsg.header.type); 1.505 + return UNKNOWN_ERROR; 1.506 + } 1.507 + } 1.508 + return OK; 1.509 +} 1.510 + 1.511 +status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory, 1.512 + nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) { 1.513 + status_t result; 1.514 + for (size_t i = mBatches.size(); i-- > 0; ) { 1.515 + Batch& batch = mBatches.editItemAt(i); 1.516 + if (frameTime < 0) { 1.517 + result = consumeSamples(factory, batch, batch.samples.size(), 1.518 + outSeq, outEvent); 1.519 + mBatches.removeAt(i); 1.520 + return result; 1.521 + } 1.522 + 1.523 + nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY; 1.524 + ssize_t split = findSampleNoLaterThan(batch, sampleTime); 1.525 + if (split < 0) { 1.526 + continue; 1.527 + } 1.528 + 1.529 + result = consumeSamples(factory, batch, split + 1, outSeq, outEvent); 1.530 + const InputMessage* next; 1.531 + if (batch.samples.isEmpty()) { 1.532 + mBatches.removeAt(i); 1.533 + next = NULL; 1.534 + } else { 1.535 + next = &batch.samples.itemAt(0); 1.536 + } 1.537 + if (!result) { 1.538 + resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next); 1.539 + } 1.540 + return result; 1.541 + } 1.542 + 1.543 + return WOULD_BLOCK; 1.544 +} 1.545 + 1.546 +status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory, 1.547 + Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) { 1.548 + MotionEvent* motionEvent = factory->createMotionEvent(); 1.549 + if (! motionEvent) return NO_MEMORY; 1.550 + 1.551 + uint32_t chain = 0; 1.552 + for (size_t i = 0; i < count; i++) { 1.553 + InputMessage& msg = batch.samples.editItemAt(i); 1.554 + updateTouchState(&msg); 1.555 + if (i) { 1.556 + SeqChain seqChain; 1.557 + seqChain.seq = msg.body.motion.seq; 1.558 + seqChain.chain = chain; 1.559 + mSeqChains.push(seqChain); 1.560 + addSample(motionEvent, &msg); 1.561 + } else { 1.562 + initializeMotionEvent(motionEvent, &msg); 1.563 + } 1.564 + chain = msg.body.motion.seq; 1.565 + } 1.566 + batch.samples.removeItemsAt(0, count); 1.567 + 1.568 + *outSeq = chain; 1.569 + *outEvent = motionEvent; 1.570 + return OK; 1.571 +} 1.572 + 1.573 +void InputConsumer::updateTouchState(InputMessage* msg) { 1.574 + if (!mResampleTouch || 1.575 + !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) { 1.576 + return; 1.577 + } 1.578 + 1.579 + int32_t deviceId = msg->body.motion.deviceId; 1.580 + int32_t source = msg->body.motion.source; 1.581 + nsecs_t eventTime = msg->body.motion.eventTime; 1.582 + 1.583 + // Update the touch state history to incorporate the new input message. 1.584 + // If the message is in the past relative to the most recently produced resampled 1.585 + // touch, then use the resampled time and coordinates instead. 1.586 + switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) { 1.587 + case AMOTION_EVENT_ACTION_DOWN: { 1.588 + ssize_t index = findTouchState(deviceId, source); 1.589 + if (index < 0) { 1.590 + mTouchStates.push(); 1.591 + index = mTouchStates.size() - 1; 1.592 + } 1.593 + TouchState& touchState = mTouchStates.editItemAt(index); 1.594 + touchState.initialize(deviceId, source); 1.595 + touchState.addHistory(msg); 1.596 + break; 1.597 + } 1.598 + 1.599 + case AMOTION_EVENT_ACTION_MOVE: { 1.600 + ssize_t index = findTouchState(deviceId, source); 1.601 + if (index >= 0) { 1.602 + TouchState& touchState = mTouchStates.editItemAt(index); 1.603 + touchState.addHistory(msg); 1.604 + if (eventTime < touchState.lastResample.eventTime) { 1.605 + rewriteMessage(touchState, msg); 1.606 + } else { 1.607 + touchState.lastResample.idBits.clear(); 1.608 + } 1.609 + } 1.610 + break; 1.611 + } 1.612 + 1.613 + case AMOTION_EVENT_ACTION_POINTER_DOWN: { 1.614 + ssize_t index = findTouchState(deviceId, source); 1.615 + if (index >= 0) { 1.616 + TouchState& touchState = mTouchStates.editItemAt(index); 1.617 + touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId()); 1.618 + rewriteMessage(touchState, msg); 1.619 + } 1.620 + break; 1.621 + } 1.622 + 1.623 + case AMOTION_EVENT_ACTION_POINTER_UP: { 1.624 + ssize_t index = findTouchState(deviceId, source); 1.625 + if (index >= 0) { 1.626 + TouchState& touchState = mTouchStates.editItemAt(index); 1.627 + rewriteMessage(touchState, msg); 1.628 + touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId()); 1.629 + } 1.630 + break; 1.631 + } 1.632 + 1.633 + case AMOTION_EVENT_ACTION_SCROLL: { 1.634 + ssize_t index = findTouchState(deviceId, source); 1.635 + if (index >= 0) { 1.636 + const TouchState& touchState = mTouchStates.itemAt(index); 1.637 + rewriteMessage(touchState, msg); 1.638 + } 1.639 + break; 1.640 + } 1.641 + 1.642 + case AMOTION_EVENT_ACTION_UP: 1.643 + case AMOTION_EVENT_ACTION_CANCEL: { 1.644 + ssize_t index = findTouchState(deviceId, source); 1.645 + if (index >= 0) { 1.646 + const TouchState& touchState = mTouchStates.itemAt(index); 1.647 + rewriteMessage(touchState, msg); 1.648 + mTouchStates.removeAt(index); 1.649 + } 1.650 + break; 1.651 + } 1.652 + } 1.653 +} 1.654 + 1.655 +void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) { 1.656 + for (size_t i = 0; i < msg->body.motion.pointerCount; i++) { 1.657 + uint32_t id = msg->body.motion.pointers[i].properties.id; 1.658 + if (state.lastResample.idBits.hasBit(id)) { 1.659 + PointerCoords& msgCoords = msg->body.motion.pointers[i].coords; 1.660 + const PointerCoords& resampleCoords = state.lastResample.getPointerById(id); 1.661 +#if DEBUG_RESAMPLING 1.662 + ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id, 1.663 + resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X), 1.664 + resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1.665 + msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X), 1.666 + msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y)); 1.667 +#endif 1.668 + msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX()); 1.669 + msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY()); 1.670 + } 1.671 + } 1.672 +} 1.673 + 1.674 +void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, 1.675 + const InputMessage* next) { 1.676 + if (!mResampleTouch 1.677 + || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER) 1.678 + || event->getAction() != AMOTION_EVENT_ACTION_MOVE) { 1.679 + return; 1.680 + } 1.681 + 1.682 + ssize_t index = findTouchState(event->getDeviceId(), event->getSource()); 1.683 + if (index < 0) { 1.684 +#if DEBUG_RESAMPLING 1.685 + ALOGD("Not resampled, no touch state for device."); 1.686 +#endif 1.687 + return; 1.688 + } 1.689 + 1.690 + TouchState& touchState = mTouchStates.editItemAt(index); 1.691 + if (touchState.historySize < 1) { 1.692 +#if DEBUG_RESAMPLING 1.693 + ALOGD("Not resampled, no history for device."); 1.694 +#endif 1.695 + return; 1.696 + } 1.697 + 1.698 + // Ensure that the current sample has all of the pointers that need to be reported. 1.699 + const History* current = touchState.getHistory(0); 1.700 + size_t pointerCount = event->getPointerCount(); 1.701 + for (size_t i = 0; i < pointerCount; i++) { 1.702 + uint32_t id = event->getPointerId(i); 1.703 + if (!current->idBits.hasBit(id)) { 1.704 +#if DEBUG_RESAMPLING 1.705 + ALOGD("Not resampled, missing id %d", id); 1.706 +#endif 1.707 + return; 1.708 + } 1.709 + } 1.710 + 1.711 + // Find the data to use for resampling. 1.712 + const History* other; 1.713 + History future; 1.714 + float alpha; 1.715 + if (next) { 1.716 + // Interpolate between current sample and future sample. 1.717 + // So current->eventTime <= sampleTime <= future.eventTime. 1.718 + future.initializeFrom(next); 1.719 + other = &future; 1.720 + nsecs_t delta = future.eventTime - current->eventTime; 1.721 + if (delta < RESAMPLE_MIN_DELTA) { 1.722 +#if DEBUG_RESAMPLING 1.723 + ALOGD("Not resampled, delta time is %lld ns.", delta); 1.724 +#endif 1.725 + return; 1.726 + } 1.727 + alpha = float(sampleTime - current->eventTime) / delta; 1.728 + } else if (touchState.historySize >= 2) { 1.729 + // Extrapolate future sample using current sample and past sample. 1.730 + // So other->eventTime <= current->eventTime <= sampleTime. 1.731 + other = touchState.getHistory(1); 1.732 + nsecs_t delta = current->eventTime - other->eventTime; 1.733 + if (delta < RESAMPLE_MIN_DELTA) { 1.734 +#if DEBUG_RESAMPLING 1.735 + ALOGD("Not resampled, delta time is %lld ns.", delta); 1.736 +#endif 1.737 + return; 1.738 + } 1.739 + nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION); 1.740 + if (sampleTime > maxPredict) { 1.741 +#if DEBUG_RESAMPLING 1.742 + ALOGD("Sample time is too far in the future, adjusting prediction " 1.743 + "from %lld to %lld ns.", 1.744 + sampleTime - current->eventTime, maxPredict - current->eventTime); 1.745 +#endif 1.746 + sampleTime = maxPredict; 1.747 + } 1.748 + alpha = float(current->eventTime - sampleTime) / delta; 1.749 + } else { 1.750 +#if DEBUG_RESAMPLING 1.751 + ALOGD("Not resampled, insufficient data."); 1.752 +#endif 1.753 + return; 1.754 + } 1.755 + 1.756 + // Resample touch coordinates. 1.757 + touchState.lastResample.eventTime = sampleTime; 1.758 + touchState.lastResample.idBits.clear(); 1.759 + for (size_t i = 0; i < pointerCount; i++) { 1.760 + uint32_t id = event->getPointerId(i); 1.761 + touchState.lastResample.idToIndex[id] = i; 1.762 + touchState.lastResample.idBits.markBit(id); 1.763 + PointerCoords& resampledCoords = touchState.lastResample.pointers[i]; 1.764 + const PointerCoords& currentCoords = current->getPointerById(id); 1.765 + if (other->idBits.hasBit(id) 1.766 + && shouldResampleTool(event->getToolType(i))) { 1.767 + const PointerCoords& otherCoords = other->getPointerById(id); 1.768 + resampledCoords.copyFrom(currentCoords); 1.769 + resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X, 1.770 + lerp(currentCoords.getX(), otherCoords.getX(), alpha)); 1.771 + resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, 1.772 + lerp(currentCoords.getY(), otherCoords.getY(), alpha)); 1.773 +#if DEBUG_RESAMPLING 1.774 + ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), " 1.775 + "other (%0.3f, %0.3f), alpha %0.3f", 1.776 + id, resampledCoords.getX(), resampledCoords.getY(), 1.777 + currentCoords.getX(), currentCoords.getY(), 1.778 + otherCoords.getX(), otherCoords.getY(), 1.779 + alpha); 1.780 +#endif 1.781 + } else { 1.782 + resampledCoords.copyFrom(currentCoords); 1.783 +#if DEBUG_RESAMPLING 1.784 + ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)", 1.785 + id, resampledCoords.getX(), resampledCoords.getY(), 1.786 + currentCoords.getX(), currentCoords.getY()); 1.787 +#endif 1.788 + } 1.789 + } 1.790 + 1.791 + event->addSample(sampleTime, touchState.lastResample.pointers); 1.792 +} 1.793 + 1.794 +bool InputConsumer::shouldResampleTool(int32_t toolType) { 1.795 + return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER 1.796 + || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN; 1.797 +} 1.798 + 1.799 +status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { 1.800 +#if DEBUG_TRANSPORT_ACTIONS 1.801 + ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s", 1.802 + mChannel->getName().string(), seq, handled ? "true" : "false"); 1.803 +#endif 1.804 + 1.805 + if (!seq) { 1.806 + ALOGE("Attempted to send a finished signal with sequence number 0."); 1.807 + return BAD_VALUE; 1.808 + } 1.809 + 1.810 + // Send finished signals for the batch sequence chain first. 1.811 + size_t seqChainCount = mSeqChains.size(); 1.812 + if (seqChainCount) { 1.813 + uint32_t currentSeq = seq; 1.814 + uint32_t chainSeqs[seqChainCount]; 1.815 + size_t chainIndex = 0; 1.816 + for (size_t i = seqChainCount; i-- > 0; ) { 1.817 + const SeqChain& seqChain = mSeqChains.itemAt(i); 1.818 + if (seqChain.seq == currentSeq) { 1.819 + currentSeq = seqChain.chain; 1.820 + chainSeqs[chainIndex++] = currentSeq; 1.821 + mSeqChains.removeAt(i); 1.822 + } 1.823 + } 1.824 + status_t status = OK; 1.825 + while (!status && chainIndex-- > 0) { 1.826 + status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled); 1.827 + } 1.828 + if (status) { 1.829 + // An error occurred so at least one signal was not sent, reconstruct the chain. 1.830 + do { 1.831 + SeqChain seqChain; 1.832 + seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq; 1.833 + seqChain.chain = chainSeqs[chainIndex]; 1.834 + mSeqChains.push(seqChain); 1.835 + } while (chainIndex-- > 0); 1.836 + return status; 1.837 + } 1.838 + } 1.839 + 1.840 + // Send finished signal for the last message in the batch. 1.841 + return sendUnchainedFinishedSignal(seq, handled); 1.842 +} 1.843 + 1.844 +status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) { 1.845 + InputMessage msg; 1.846 + msg.header.type = InputMessage::TYPE_FINISHED; 1.847 + msg.body.finished.seq = seq; 1.848 + msg.body.finished.handled = handled; 1.849 + return mChannel->sendMessage(&msg); 1.850 +} 1.851 + 1.852 +bool InputConsumer::hasDeferredEvent() const { 1.853 + return mMsgDeferred; 1.854 +} 1.855 + 1.856 +bool InputConsumer::hasPendingBatch() const { 1.857 + return !mBatches.isEmpty(); 1.858 +} 1.859 + 1.860 +ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const { 1.861 + for (size_t i = 0; i < mBatches.size(); i++) { 1.862 + const Batch& batch = mBatches.itemAt(i); 1.863 + const InputMessage& head = batch.samples.itemAt(0); 1.864 + if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) { 1.865 + return i; 1.866 + } 1.867 + } 1.868 + return -1; 1.869 +} 1.870 + 1.871 +ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const { 1.872 + for (size_t i = 0; i < mTouchStates.size(); i++) { 1.873 + const TouchState& touchState = mTouchStates.itemAt(i); 1.874 + if (touchState.deviceId == deviceId && touchState.source == source) { 1.875 + return i; 1.876 + } 1.877 + } 1.878 + return -1; 1.879 +} 1.880 + 1.881 +void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) { 1.882 + event->initialize( 1.883 + msg->body.key.deviceId, 1.884 + msg->body.key.source, 1.885 + msg->body.key.action, 1.886 + msg->body.key.flags, 1.887 + msg->body.key.keyCode, 1.888 + msg->body.key.scanCode, 1.889 + msg->body.key.metaState, 1.890 + msg->body.key.repeatCount, 1.891 + msg->body.key.downTime, 1.892 + msg->body.key.eventTime); 1.893 +} 1.894 + 1.895 +void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) { 1.896 + size_t pointerCount = msg->body.motion.pointerCount; 1.897 + PointerProperties pointerProperties[pointerCount]; 1.898 + PointerCoords pointerCoords[pointerCount]; 1.899 + for (size_t i = 0; i < pointerCount; i++) { 1.900 + pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties); 1.901 + pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords); 1.902 + } 1.903 + 1.904 + event->initialize( 1.905 + msg->body.motion.deviceId, 1.906 + msg->body.motion.source, 1.907 + msg->body.motion.action, 1.908 + msg->body.motion.flags, 1.909 + msg->body.motion.edgeFlags, 1.910 + msg->body.motion.metaState, 1.911 + msg->body.motion.buttonState, 1.912 + msg->body.motion.xOffset, 1.913 + msg->body.motion.yOffset, 1.914 + msg->body.motion.xPrecision, 1.915 + msg->body.motion.yPrecision, 1.916 + msg->body.motion.downTime, 1.917 + msg->body.motion.eventTime, 1.918 + pointerCount, 1.919 + pointerProperties, 1.920 + pointerCoords); 1.921 +} 1.922 + 1.923 +void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) { 1.924 + size_t pointerCount = msg->body.motion.pointerCount; 1.925 + PointerCoords pointerCoords[pointerCount]; 1.926 + for (size_t i = 0; i < pointerCount; i++) { 1.927 + pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords); 1.928 + } 1.929 + 1.930 + event->setMetaState(event->getMetaState() | msg->body.motion.metaState); 1.931 + event->addSample(msg->body.motion.eventTime, pointerCoords); 1.932 +} 1.933 + 1.934 +bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) { 1.935 + const InputMessage& head = batch.samples.itemAt(0); 1.936 + size_t pointerCount = msg->body.motion.pointerCount; 1.937 + if (head.body.motion.pointerCount != pointerCount 1.938 + || head.body.motion.action != msg->body.motion.action) { 1.939 + return false; 1.940 + } 1.941 + for (size_t i = 0; i < pointerCount; i++) { 1.942 + if (head.body.motion.pointers[i].properties 1.943 + != msg->body.motion.pointers[i].properties) { 1.944 + return false; 1.945 + } 1.946 + } 1.947 + return true; 1.948 +} 1.949 + 1.950 +ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) { 1.951 + size_t numSamples = batch.samples.size(); 1.952 + size_t index = 0; 1.953 + while (index < numSamples 1.954 + && batch.samples.itemAt(index).body.motion.eventTime <= time) { 1.955 + index += 1; 1.956 + } 1.957 + return ssize_t(index) - 1; 1.958 +} 1.959 + 1.960 +} // namespace android