1// 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 10// Log debug messages about channel messages (send message, receive message) 11#define DEBUG_CHANNEL_MESSAGES 0 12 13// Log debug messages whenever InputChannel objects are created/destroyed 14#define DEBUG_CHANNEL_LIFECYCLE 0 15 16// Log debug messages about transport actions 17#define DEBUG_TRANSPORT_ACTIONS 0 18 19// Log debug messages about touch event resampling 20#define DEBUG_RESAMPLING 0 21 22#include <errno.h> 23#include <fcntl.h> 24#include <inttypes.h> 25#include <math.h> 26#include <sys/socket.h> 27#include <sys/types.h> 28#include <unistd.h> 29 30#include <cutils/properties.h> 31#include <log/log.h> 32 33#include <input/InputTransport.h> 34 35namespace android { 36 37// Socket buffer size. The default is typically about 128KB, which is much larger than 38// we really need. So we make it smaller. It just needs to be big enough to hold 39// a few dozen large multi-finger motion events in the case where an application gets 40// behind processing touches. 41static const size_t SOCKET_BUFFER_SIZE = 32 * 1024; 42 43// Nanoseconds per milliseconds. 44static const nsecs_t NANOS_PER_MS = 1000000; 45 46// Latency added during resampling. A few milliseconds doesn't hurt much but 47// reduces the impact of mispredicted touch positions. 48static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS; 49 50// Minimum time difference between consecutive samples before attempting to resample. 51static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS; 52 53// Maximum time difference between consecutive samples before attempting to resample 54// by extrapolation. 55static const nsecs_t RESAMPLE_MAX_DELTA = 20 * NANOS_PER_MS; 56 57// Maximum time to predict forward from the last known state, to avoid predicting too 58// far into the future. This time is further bounded by 50% of the last time delta. 59static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS; 60 61template<typename T> 62inline static T min(const T& a, const T& b) { 63 return a < b ? a : b; 64} 65 66inline static float lerp(float a, float b, float alpha) { 67 return a + alpha * (b - a); 68} 69 70// --- InputMessage --- 71 72bool InputMessage::isValid(size_t actualSize) const { 73 if (size() == actualSize) { 74 switch (header.type) { 75 case TYPE_KEY: 76 return true; 77 case TYPE_MOTION: 78 return body.motion.pointerCount > 0 79 && body.motion.pointerCount <= MAX_POINTERS; 80 case TYPE_FINISHED: 81 return true; 82 } 83 } 84 return false; 85} 86 87size_t InputMessage::size() const { 88 switch (header.type) { 89 case TYPE_KEY: 90 return sizeof(Header) + body.key.size(); 91 case TYPE_MOTION: 92 return sizeof(Header) + body.motion.size(); 93 case TYPE_FINISHED: 94 return sizeof(Header) + body.finished.size(); 95 } 96 return sizeof(Header); 97} 98 99 100// --- InputChannel --- 101 102InputChannel::InputChannel(const std::string& name, int fd) : 103 mName(name), mFd(fd) { 104#if DEBUG_CHANNEL_LIFECYCLE 105 ALOGD("Input channel constructed: name='%s', fd=%d", 106 mName.c_str(), fd); 107#endif 108 109 int result = fcntl(mFd, F_SETFL, O_NONBLOCK); 110 LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket " 111 "non-blocking. errno=%d", mName.c_str(), errno); 112} 113 114InputChannel::~InputChannel() { 115#if DEBUG_CHANNEL_LIFECYCLE 116 ALOGD("Input channel destroyed: name='%s', fd=%d", 117 mName.c_str(), mFd); 118#endif 119 120 ::close(mFd); 121} 122 123status_t InputChannel::openInputChannelPair(const std::string& name, 124 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) { 125 int sockets[2]; 126 if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) { 127 status_t result = -errno; 128 ALOGE("channel '%s' ~ Could not create socket pair. errno=%d", 129 name.c_str(), errno); 130 outServerChannel.clear(); 131 outClientChannel.clear(); 132 return result; 133 } 134 135 int bufferSize = SOCKET_BUFFER_SIZE; 136 setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); 137 setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); 138 setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)); 139 setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)); 140 141 std::string serverChannelName = name; 142 serverChannelName += " (server)"; 143 outServerChannel = new InputChannel(serverChannelName, sockets[0]); 144 145 std::string clientChannelName = name; 146 clientChannelName += " (client)"; 147 outClientChannel = new InputChannel(clientChannelName, sockets[1]); 148 return OK; 149} 150 151status_t InputChannel::sendMessage(const InputMessage* msg) { 152 size_t msgLength = msg->size(); 153 ssize_t nWrite; 154 do { 155 nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); 156 } while (nWrite == -1 && errno == EINTR); 157 158 if (nWrite < 0) { 159 int error = errno; 160#if DEBUG_CHANNEL_MESSAGES 161 ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.c_str(), 162 msg->header.type, error); 163#endif 164 if (error == EAGAIN || error == EWOULDBLOCK) { 165 return WOULD_BLOCK; 166 } 167 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) { 168 return DEAD_OBJECT; 169 } 170 return -error; 171 } 172 173 if (size_t(nWrite) != msgLength) { 174#if DEBUG_CHANNEL_MESSAGES 175 ALOGD("channel '%s' ~ error sending message type %d, send was incomplete", 176 mName.c_str(), msg->header.type); 177#endif 178 return DEAD_OBJECT; 179 } 180 181#if DEBUG_CHANNEL_MESSAGES 182 ALOGD("channel '%s' ~ sent message of type %d", mName.c_str(), msg->header.type); 183#endif 184 return OK; 185} 186 187status_t InputChannel::receiveMessage(InputMessage* msg) { 188 ssize_t nRead; 189 do { 190 nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT); 191 } while (nRead == -1 && errno == EINTR); 192 193 if (nRead < 0) { 194 int error = errno; 195#if DEBUG_CHANNEL_MESSAGES 196 ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.c_str(), errno); 197#endif 198 if (error == EAGAIN || error == EWOULDBLOCK) { 199 return WOULD_BLOCK; 200 } 201 if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) { 202 return DEAD_OBJECT; 203 } 204 return -error; 205 } 206 207 if (nRead == 0) { // check for EOF 208#if DEBUG_CHANNEL_MESSAGES 209 ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.c_str()); 210#endif 211 return DEAD_OBJECT; 212 } 213 214 if (!msg->isValid(nRead)) { 215#if DEBUG_CHANNEL_MESSAGES 216 ALOGD("channel '%s' ~ received invalid message", mName.c_str()); 217#endif 218 return BAD_VALUE; 219 } 220 221#if DEBUG_CHANNEL_MESSAGES 222 ALOGD("channel '%s' ~ received message of type %d", mName.c_str(), msg->header.type); 223#endif 224 return OK; 225} 226 227sp<InputChannel> InputChannel::dup() const { 228 int fd = ::dup(getFd()); 229 return fd >= 0 ? new InputChannel(getName(), fd) : NULL; 230} 231 232 233// --- InputPublisher --- 234 235InputPublisher::InputPublisher(const sp<InputChannel>& channel) : 236 mChannel(channel) { 237} 238 239InputPublisher::~InputPublisher() { 240} 241 242status_t InputPublisher::publishKeyEvent( 243 uint32_t seq, 244 int32_t deviceId, 245 int32_t source, 246 int32_t action, 247 int32_t flags, 248 int32_t keyCode, 249 int32_t scanCode, 250 int32_t metaState, 251 int32_t repeatCount, 252 nsecs_t downTime, 253 nsecs_t eventTime) { 254#if DEBUG_TRANSPORT_ACTIONS 255 ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, " 256 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d," 257 "downTime=%" PRId64 ", eventTime=%" PRId64, 258 mChannel->getName().c_str(), seq, 259 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, 260 downTime, eventTime); 261#endif 262 263 if (!seq) { 264 ALOGE("Attempted to publish a key event with sequence number 0."); 265 return BAD_VALUE; 266 } 267 268 InputMessage msg; 269 msg.header.type = InputMessage::TYPE_KEY; 270 msg.body.key.seq = seq; 271 msg.body.key.deviceId = deviceId; 272 msg.body.key.source = source; 273 msg.body.key.action = action; 274 msg.body.key.flags = flags; 275 msg.body.key.keyCode = keyCode; 276 msg.body.key.scanCode = scanCode; 277 msg.body.key.metaState = metaState; 278 msg.body.key.repeatCount = repeatCount; 279 msg.body.key.downTime = downTime; 280 msg.body.key.eventTime = eventTime; 281 return mChannel->sendMessage(&msg); 282} 283 284status_t InputPublisher::publishMotionEvent( 285 uint32_t seq, 286 int32_t deviceId, 287 int32_t source, 288 int32_t displayId, 289 int32_t action, 290 int32_t actionButton, 291 int32_t flags, 292 int32_t edgeFlags, 293 int32_t metaState, 294 int32_t buttonState, 295 float xOffset, 296 float yOffset, 297 float xPrecision, 298 float yPrecision, 299 nsecs_t downTime, 300 nsecs_t eventTime, 301 uint32_t pointerCount, 302 const PointerProperties* pointerProperties, 303 const PointerCoords* pointerCoords) { 304#if DEBUG_TRANSPORT_ACTIONS 305 ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, " 306 "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, " 307 "metaState=0x%x, buttonState=0x%x, xOffset=%f, yOffset=%f, " 308 "xPrecision=%f, yPrecision=%f, downTime=%" PRId64 ", eventTime=%" PRId64 ", " 309 "pointerCount=%" PRIu32, 310 mChannel->getName().c_str(), seq, 311 deviceId, source, action, actionButton, flags, edgeFlags, metaState, buttonState, 312 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount); 313#endif 314 315 if (!seq) { 316 ALOGE("Attempted to publish a motion event with sequence number 0."); 317 return BAD_VALUE; 318 } 319 320 if (pointerCount > MAX_POINTERS || pointerCount < 1) { 321 ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %" PRIu32 ".", 322 mChannel->getName().c_str(), pointerCount); 323 return BAD_VALUE; 324 } 325 326 InputMessage msg; 327 msg.header.type = InputMessage::TYPE_MOTION; 328 msg.body.motion.seq = seq; 329 msg.body.motion.deviceId = deviceId; 330 msg.body.motion.source = source; 331 msg.body.motion.displayId = displayId; 332 msg.body.motion.action = action; 333 msg.body.motion.actionButton = actionButton; 334 msg.body.motion.flags = flags; 335 msg.body.motion.edgeFlags = edgeFlags; 336 msg.body.motion.metaState = metaState; 337 msg.body.motion.buttonState = buttonState; 338 msg.body.motion.xOffset = xOffset; 339 msg.body.motion.yOffset = yOffset; 340 msg.body.motion.xPrecision = xPrecision; 341 msg.body.motion.yPrecision = yPrecision; 342 msg.body.motion.downTime = downTime; 343 msg.body.motion.eventTime = eventTime; 344 msg.body.motion.pointerCount = pointerCount; 345 for (uint32_t i = 0; i < pointerCount; i++) { 346 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]); 347 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]); 348 } 349 return mChannel->sendMessage(&msg); 350} 351 352status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) { 353#if DEBUG_TRANSPORT_ACTIONS 354 ALOGD("channel '%s' publisher ~ receiveFinishedSignal", 355 mChannel->getName().c_str()); 356#endif 357 358 InputMessage msg; 359 status_t result = mChannel->receiveMessage(&msg); 360 if (result) { 361 *outSeq = 0; 362 *outHandled = false; 363 return result; 364 } 365 if (msg.header.type != InputMessage::TYPE_FINISHED) { 366 ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer", 367 mChannel->getName().c_str(), msg.header.type); 368 return UNKNOWN_ERROR; 369 } 370 *outSeq = msg.body.finished.seq; 371 *outHandled = msg.body.finished.handled; 372 return OK; 373} 374 375// --- InputConsumer --- 376 377InputConsumer::InputConsumer(const sp<InputChannel>& channel) : 378 mResampleTouch(isTouchResamplingEnabled()), 379 mChannel(channel), mMsgDeferred(false) { 380} 381 382InputConsumer::~InputConsumer() { 383} 384 385bool InputConsumer::isTouchResamplingEnabled() { 386 char value[PROPERTY_VALUE_MAX]; 387 int length = property_get("ro.input.noresample", value, NULL); 388 if (length > 0) { 389 if (!strcmp("1", value)) { 390 return false; 391 } 392 if (strcmp("0", value)) { 393 ALOGD("Unrecognized property value for 'ro.input.noresample'. " 394 "Use '1' or '0'."); 395 } 396 } 397 return true; 398} 399 400status_t InputConsumer::consume(InputEventFactoryInterface* factory, 401 bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent, 402 int32_t* displayId) { 403#if DEBUG_TRANSPORT_ACTIONS 404 ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%" PRId64, 405 mChannel->getName().c_str(), consumeBatches ? "true" : "false", frameTime); 406#endif 407 408 *outSeq = 0; 409 *outEvent = NULL; 410 *displayId = -1; // Invalid display. 411 412 // Fetch the next input message. 413 // Loop until an event can be returned or no additional events are received. 414 while (!*outEvent) { 415 if (mMsgDeferred) { 416 // mMsg contains a valid input message from the previous call to consume 417 // that has not yet been processed. 418 mMsgDeferred = false; 419 } else { 420 // Receive a fresh message. 421 status_t result = mChannel->receiveMessage(&mMsg); 422 if (result) { 423 // Consume the next batched event unless batches are being held for later. 424 if (consumeBatches || result != WOULD_BLOCK) { 425 result = consumeBatch(factory, frameTime, outSeq, outEvent, displayId); 426 if (*outEvent) { 427#if DEBUG_TRANSPORT_ACTIONS 428 ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u", 429 mChannel->getName().c_str(), *outSeq); 430#endif 431 break; 432 } 433 } 434 return result; 435 } 436 } 437 438 switch (mMsg.header.type) { 439 case InputMessage::TYPE_KEY: { 440 KeyEvent* keyEvent = factory->createKeyEvent(); 441 if (!keyEvent) return NO_MEMORY; 442 443 initializeKeyEvent(keyEvent, &mMsg); 444 *outSeq = mMsg.body.key.seq; 445 *outEvent = keyEvent; 446#if DEBUG_TRANSPORT_ACTIONS 447 ALOGD("channel '%s' consumer ~ consumed key event, seq=%u", 448 mChannel->getName().c_str(), *outSeq); 449#endif 450 break; 451 } 452 453 case InputMessage::TYPE_MOTION: { 454 ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source); 455 if (batchIndex >= 0) { 456 Batch& batch = mBatches.editItemAt(batchIndex); 457 if (canAddSample(batch, &mMsg)) { 458 batch.samples.push(mMsg); 459#if DEBUG_TRANSPORT_ACTIONS 460 ALOGD("channel '%s' consumer ~ appended to batch event", 461 mChannel->getName().c_str()); 462#endif 463 break; 464 } else { 465 // We cannot append to the batch in progress, so we need to consume 466 // the previous batch right now and defer the new message until later. 467 mMsgDeferred = true; 468 status_t result = consumeSamples(factory, 469 batch, batch.samples.size(), outSeq, outEvent, displayId); 470 mBatches.removeAt(batchIndex); 471 if (result) { 472 return result; 473 } 474#if DEBUG_TRANSPORT_ACTIONS 475 ALOGD("channel '%s' consumer ~ consumed batch event and " 476 "deferred current event, seq=%u", 477 mChannel->getName().c_str(), *outSeq); 478#endif 479 break; 480 } 481 } 482 483 // Start a new batch if needed. 484 if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE 485 || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) { 486 mBatches.push(); 487 Batch& batch = mBatches.editTop(); 488 batch.samples.push(mMsg); 489#if DEBUG_TRANSPORT_ACTIONS 490 ALOGD("channel '%s' consumer ~ started batch event", 491 mChannel->getName().c_str()); 492#endif 493 break; 494 } 495 496 MotionEvent* motionEvent = factory->createMotionEvent(); 497 if (! motionEvent) return NO_MEMORY; 498 499 updateTouchState(mMsg); 500 initializeMotionEvent(motionEvent, &mMsg); 501 *outSeq = mMsg.body.motion.seq; 502 *outEvent = motionEvent; 503 *displayId = mMsg.body.motion.displayId; 504#if DEBUG_TRANSPORT_ACTIONS 505 ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u", 506 mChannel->getName().c_str(), *outSeq); 507#endif 508 break; 509 } 510 511 default: 512 ALOGE("channel '%s' consumer ~ Received unexpected message of type %d", 513 mChannel->getName().c_str(), mMsg.header.type); 514 return UNKNOWN_ERROR; 515 } 516 } 517 return OK; 518} 519 520status_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory, 521 nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId) { 522 status_t result; 523 for (size_t i = mBatches.size(); i > 0; ) { 524 i--; 525 Batch& batch = mBatches.editItemAt(i); 526 if (frameTime < 0) { 527 result = consumeSamples(factory, batch, batch.samples.size(), 528 outSeq, outEvent, displayId); 529 mBatches.removeAt(i); 530 return result; 531 } 532 533 nsecs_t sampleTime = frameTime; 534 if (mResampleTouch) { 535 sampleTime -= RESAMPLE_LATENCY; 536 } 537 ssize_t split = findSampleNoLaterThan(batch, sampleTime); 538 if (split < 0) { 539 continue; 540 } 541 542 result = consumeSamples(factory, batch, split + 1, outSeq, outEvent, displayId); 543 const InputMessage* next; 544 if (batch.samples.isEmpty()) { 545 mBatches.removeAt(i); 546 next = NULL; 547 } else { 548 next = &batch.samples.itemAt(0); 549 } 550 if (!result && mResampleTouch) { 551 resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next); 552 } 553 return result; 554 } 555 556 return WOULD_BLOCK; 557} 558 559status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory, 560 Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent, int32_t* displayId) { 561 MotionEvent* motionEvent = factory->createMotionEvent(); 562 if (! motionEvent) return NO_MEMORY; 563 564 uint32_t chain = 0; 565 for (size_t i = 0; i < count; i++) { 566 InputMessage& msg = batch.samples.editItemAt(i); 567 updateTouchState(msg); 568 if (i) { 569 SeqChain seqChain; 570 seqChain.seq = msg.body.motion.seq; 571 seqChain.chain = chain; 572 mSeqChains.push(seqChain); 573 addSample(motionEvent, &msg); 574 } else { 575 *displayId = msg.body.motion.displayId; 576 initializeMotionEvent(motionEvent, &msg); 577 } 578 chain = msg.body.motion.seq; 579 } 580 batch.samples.removeItemsAt(0, count); 581 582 *outSeq = chain; 583 *outEvent = motionEvent; 584 return OK; 585} 586 587void InputConsumer::updateTouchState(InputMessage& msg) { 588 if (!mResampleTouch || 589 !(msg.body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) { 590 return; 591 } 592 593 int32_t deviceId = msg.body.motion.deviceId; 594 int32_t source = msg.body.motion.source; 595 596 // Update the touch state history to incorporate the new input message. 597 // If the message is in the past relative to the most recently produced resampled 598 // touch, then use the resampled time and coordinates instead. 599 switch (msg.body.motion.action & AMOTION_EVENT_ACTION_MASK) { 600 case AMOTION_EVENT_ACTION_DOWN: { 601 ssize_t index = findTouchState(deviceId, source); 602 if (index < 0) { 603 mTouchStates.push(); 604 index = mTouchStates.size() - 1; 605 } 606 TouchState& touchState = mTouchStates.editItemAt(index); 607 touchState.initialize(deviceId, source); 608 touchState.addHistory(msg); 609 break; 610 } 611 612 case AMOTION_EVENT_ACTION_MOVE: { 613 ssize_t index = findTouchState(deviceId, source); 614 if (index >= 0) { 615 TouchState& touchState = mTouchStates.editItemAt(index); 616 touchState.addHistory(msg); 617 rewriteMessage(touchState, msg); 618 } 619 break; 620 } 621 622 case AMOTION_EVENT_ACTION_POINTER_DOWN: { 623 ssize_t index = findTouchState(deviceId, source); 624 if (index >= 0) { 625 TouchState& touchState = mTouchStates.editItemAt(index); 626 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId()); 627 rewriteMessage(touchState, msg); 628 } 629 break; 630 } 631 632 case AMOTION_EVENT_ACTION_POINTER_UP: { 633 ssize_t index = findTouchState(deviceId, source); 634 if (index >= 0) { 635 TouchState& touchState = mTouchStates.editItemAt(index); 636 rewriteMessage(touchState, msg); 637 touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId()); 638 } 639 break; 640 } 641 642 case AMOTION_EVENT_ACTION_SCROLL: { 643 ssize_t index = findTouchState(deviceId, source); 644 if (index >= 0) { 645 TouchState& touchState = mTouchStates.editItemAt(index); 646 rewriteMessage(touchState, msg); 647 } 648 break; 649 } 650 651 case AMOTION_EVENT_ACTION_UP: 652 case AMOTION_EVENT_ACTION_CANCEL: { 653 ssize_t index = findTouchState(deviceId, source); 654 if (index >= 0) { 655 TouchState& touchState = mTouchStates.editItemAt(index); 656 rewriteMessage(touchState, msg); 657 mTouchStates.removeAt(index); 658 } 659 break; 660 } 661 } 662} 663 664/** 665 * Replace the coordinates in msg with the coordinates in lastResample, if necessary. 666 * 667 * If lastResample is no longer valid for a specific pointer (i.e. the lastResample time 668 * is in the past relative to msg and the past two events do not contain identical coordinates), 669 * then invalidate the lastResample data for that pointer. 670 * If the two past events have identical coordinates, then lastResample data for that pointer will 671 * remain valid, and will be used to replace these coordinates. Thus, if a certain coordinate x0 is 672 * resampled to the new value x1, then x1 will always be used to replace x0 until some new value 673 * not equal to x0 is received. 674 */ 675void InputConsumer::rewriteMessage(TouchState& state, InputMessage& msg) { 676 nsecs_t eventTime = msg.body.motion.eventTime; 677 for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) { 678 uint32_t id = msg.body.motion.pointers[i].properties.id; 679 if (state.lastResample.idBits.hasBit(id)) { 680 if (eventTime < state.lastResample.eventTime || 681 state.recentCoordinatesAreIdentical(id)) { 682 PointerCoords& msgCoords = msg.body.motion.pointers[i].coords; 683 const PointerCoords& resampleCoords = state.lastResample.getPointerById(id); 684#if DEBUG_RESAMPLING 685 ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id, 686 resampleCoords.getX(), resampleCoords.getY(), 687 msgCoords.getX(), msgCoords.getY()); 688#endif 689 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX()); 690 msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY()); 691 } else { 692 state.lastResample.idBits.clearBit(id); 693 } 694 } 695 } 696} 697 698void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, 699 const InputMessage* next) { 700 if (!mResampleTouch 701 || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER) 702 || event->getAction() != AMOTION_EVENT_ACTION_MOVE) { 703 return; 704 } 705 706 ssize_t index = findTouchState(event->getDeviceId(), event->getSource()); 707 if (index < 0) { 708#if DEBUG_RESAMPLING 709 ALOGD("Not resampled, no touch state for device."); 710#endif 711 return; 712 } 713 714 TouchState& touchState = mTouchStates.editItemAt(index); 715 if (touchState.historySize < 1) { 716#if DEBUG_RESAMPLING 717 ALOGD("Not resampled, no history for device."); 718#endif 719 return; 720 } 721 722 // Ensure that the current sample has all of the pointers that need to be reported. 723 const History* current = touchState.getHistory(0); 724 size_t pointerCount = event->getPointerCount(); 725 for (size_t i = 0; i < pointerCount; i++) { 726 uint32_t id = event->getPointerId(i); 727 if (!current->idBits.hasBit(id)) { 728#if DEBUG_RESAMPLING 729 ALOGD("Not resampled, missing id %d", id); 730#endif 731 return; 732 } 733 } 734 735 // Find the data to use for resampling. 736 const History* other; 737 History future; 738 float alpha; 739 if (next) { 740 // Interpolate between current sample and future sample. 741 // So current->eventTime <= sampleTime <= future.eventTime. 742 future.initializeFrom(*next); 743 other = &future; 744 nsecs_t delta = future.eventTime - current->eventTime; 745 if (delta < RESAMPLE_MIN_DELTA) { 746#if DEBUG_RESAMPLING 747 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta); 748#endif 749 return; 750 } 751 alpha = float(sampleTime - current->eventTime) / delta; 752 } else if (touchState.historySize >= 2) { 753 // Extrapolate future sample using current sample and past sample. 754 // So other->eventTime <= current->eventTime <= sampleTime. 755 other = touchState.getHistory(1); 756 nsecs_t delta = current->eventTime - other->eventTime; 757 if (delta < RESAMPLE_MIN_DELTA) { 758#if DEBUG_RESAMPLING 759 ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta); 760#endif 761 return; 762 } else if (delta > RESAMPLE_MAX_DELTA) { 763#if DEBUG_RESAMPLING 764 ALOGD("Not resampled, delta time is too large: %" PRId64 " ns.", delta); 765#endif 766 return; 767 } 768 nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION); 769 if (sampleTime > maxPredict) { 770#if DEBUG_RESAMPLING 771 ALOGD("Sample time is too far in the future, adjusting prediction " 772 "from %" PRId64 " to %" PRId64 " ns.", 773 sampleTime - current->eventTime, maxPredict - current->eventTime); 774#endif 775 sampleTime = maxPredict; 776 } 777 alpha = float(current->eventTime - sampleTime) / delta; 778 } else { 779#if DEBUG_RESAMPLING 780 ALOGD("Not resampled, insufficient data."); 781#endif 782 return; 783 } 784 785 // Resample touch coordinates. 786 History oldLastResample; 787 oldLastResample.initializeFrom(touchState.lastResample); 788 touchState.lastResample.eventTime = sampleTime; 789 touchState.lastResample.idBits.clear(); 790 for (size_t i = 0; i < pointerCount; i++) { 791 uint32_t id = event->getPointerId(i); 792 touchState.lastResample.idToIndex[id] = i; 793 touchState.lastResample.idBits.markBit(id); 794 if (oldLastResample.hasPointerId(id) && touchState.recentCoordinatesAreIdentical(id)) { 795 // We maintain the previously resampled value for this pointer (stored in 796 // oldLastResample) when the coordinates for this pointer haven't changed since then. 797 // This way we don't introduce artificial jitter when pointers haven't actually moved. 798 799 // We know here that the coordinates for the pointer haven't changed because we 800 // would've cleared the resampled bit in rewriteMessage if they had. We can't modify 801 // lastResample in place becasue the mapping from pointer ID to index may have changed. 802 touchState.lastResample.pointers[i].copyFrom(oldLastResample.getPointerById(id)); 803 continue; 804 } 805 806 PointerCoords& resampledCoords = touchState.lastResample.pointers[i]; 807 const PointerCoords& currentCoords = current->getPointerById(id); 808 resampledCoords.copyFrom(currentCoords); 809 if (other->idBits.hasBit(id) 810 && shouldResampleTool(event->getToolType(i))) { 811 const PointerCoords& otherCoords = other->getPointerById(id); 812 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X, 813 lerp(currentCoords.getX(), otherCoords.getX(), alpha)); 814 resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, 815 lerp(currentCoords.getY(), otherCoords.getY(), alpha)); 816#if DEBUG_RESAMPLING 817 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), " 818 "other (%0.3f, %0.3f), alpha %0.3f", 819 id, resampledCoords.getX(), resampledCoords.getY(), 820 currentCoords.getX(), currentCoords.getY(), 821 otherCoords.getX(), otherCoords.getY(), 822 alpha); 823#endif 824 } else { 825#if DEBUG_RESAMPLING 826 ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)", 827 id, resampledCoords.getX(), resampledCoords.getY(), 828 currentCoords.getX(), currentCoords.getY()); 829#endif 830 } 831 } 832 833 event->addSample(sampleTime, touchState.lastResample.pointers); 834} 835 836bool InputConsumer::shouldResampleTool(int32_t toolType) { 837 return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER 838 || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN; 839} 840 841status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) { 842#if DEBUG_TRANSPORT_ACTIONS 843 ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s", 844 mChannel->getName().c_str(), seq, handled ? "true" : "false"); 845#endif 846 847 if (!seq) { 848 ALOGE("Attempted to send a finished signal with sequence number 0."); 849 return BAD_VALUE; 850 } 851 852 // Send finished signals for the batch sequence chain first. 853 size_t seqChainCount = mSeqChains.size(); 854 if (seqChainCount) { 855 uint32_t currentSeq = seq; 856 uint32_t chainSeqs[seqChainCount]; 857 size_t chainIndex = 0; 858 for (size_t i = seqChainCount; i > 0; ) { 859 i--; 860 const SeqChain& seqChain = mSeqChains.itemAt(i); 861 if (seqChain.seq == currentSeq) { 862 currentSeq = seqChain.chain; 863 chainSeqs[chainIndex++] = currentSeq; 864 mSeqChains.removeAt(i); 865 } 866 } 867 status_t status = OK; 868 while (!status && chainIndex > 0) { 869 chainIndex--; 870 status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled); 871 } 872 if (status) { 873 // An error occurred so at least one signal was not sent, reconstruct the chain. 874 for (;;) { 875 SeqChain seqChain; 876 seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq; 877 seqChain.chain = chainSeqs[chainIndex]; 878 mSeqChains.push(seqChain); 879 if (!chainIndex) break; 880 chainIndex--; 881 } 882 return status; 883 } 884 } 885 886 // Send finished signal for the last message in the batch. 887 return sendUnchainedFinishedSignal(seq, handled); 888} 889 890status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) { 891 InputMessage msg; 892 msg.header.type = InputMessage::TYPE_FINISHED; 893 msg.body.finished.seq = seq; 894 msg.body.finished.handled = handled; 895 return mChannel->sendMessage(&msg); 896} 897 898bool InputConsumer::hasDeferredEvent() const { 899 return mMsgDeferred; 900} 901 902bool InputConsumer::hasPendingBatch() const { 903 return !mBatches.isEmpty(); 904} 905 906ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const { 907 for (size_t i = 0; i < mBatches.size(); i++) { 908 const Batch& batch = mBatches.itemAt(i); 909 const InputMessage& head = batch.samples.itemAt(0); 910 if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) { 911 return i; 912 } 913 } 914 return -1; 915} 916 917ssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const { 918 for (size_t i = 0; i < mTouchStates.size(); i++) { 919 const TouchState& touchState = mTouchStates.itemAt(i); 920 if (touchState.deviceId == deviceId && touchState.source == source) { 921 return i; 922 } 923 } 924 return -1; 925} 926 927void InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) { 928 event->initialize( 929 msg->body.key.deviceId, 930 msg->body.key.source, 931 msg->body.key.action, 932 msg->body.key.flags, 933 msg->body.key.keyCode, 934 msg->body.key.scanCode, 935 msg->body.key.metaState, 936 msg->body.key.repeatCount, 937 msg->body.key.downTime, 938 msg->body.key.eventTime); 939} 940 941void InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) { 942 uint32_t pointerCount = msg->body.motion.pointerCount; 943 PointerProperties pointerProperties[pointerCount]; 944 PointerCoords pointerCoords[pointerCount]; 945 for (uint32_t i = 0; i < pointerCount; i++) { 946 pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties); 947 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords); 948 } 949 950 event->initialize( 951 msg->body.motion.deviceId, 952 msg->body.motion.source, 953 msg->body.motion.action, 954 msg->body.motion.actionButton, 955 msg->body.motion.flags, 956 msg->body.motion.edgeFlags, 957 msg->body.motion.metaState, 958 msg->body.motion.buttonState, 959 msg->body.motion.xOffset, 960 msg->body.motion.yOffset, 961 msg->body.motion.xPrecision, 962 msg->body.motion.yPrecision, 963 msg->body.motion.downTime, 964 msg->body.motion.eventTime, 965 pointerCount, 966 pointerProperties, 967 pointerCoords); 968} 969 970void InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) { 971 uint32_t pointerCount = msg->body.motion.pointerCount; 972 PointerCoords pointerCoords[pointerCount]; 973 for (uint32_t i = 0; i < pointerCount; i++) { 974 pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords); 975 } 976 977 event->setMetaState(event->getMetaState() | msg->body.motion.metaState); 978 event->addSample(msg->body.motion.eventTime, pointerCoords); 979} 980 981bool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) { 982 const InputMessage& head = batch.samples.itemAt(0); 983 uint32_t pointerCount = msg->body.motion.pointerCount; 984 if (head.body.motion.pointerCount != pointerCount 985 || head.body.motion.action != msg->body.motion.action) { 986 return false; 987 } 988 for (size_t i = 0; i < pointerCount; i++) { 989 if (head.body.motion.pointers[i].properties 990 != msg->body.motion.pointers[i].properties) { 991 return false; 992 } 993 } 994 return true; 995} 996 997ssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) { 998 size_t numSamples = batch.samples.size(); 999 size_t index = 0; 1000 while (index < numSamples 1001 && batch.samples.itemAt(index).body.motion.eventTime <= time) { 1002 index += 1; 1003 } 1004 return ssize_t(index) - 1; 1005} 1006 1007} // namespace android 1008