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