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