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