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