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 signalling (send signal, receive signal) 11 #define DEBUG_CHANNEL_SIGNALS 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 (initialize, reset, publish, ...) 17 #define DEBUG_TRANSPORT_ACTIONS 0 18 19 20 #include <cutils/ashmem.h> 21 #include <cutils/log.h> 22 #include <errno.h> 23 #include <fcntl.h> 24 #include <sys/mman.h> 25 #include <ui/InputTransport.h> 26 #include <unistd.h> 27 28 namespace android { 29 30 #define ROUND_UP(value, boundary) (((value) + (boundary) - 1) & ~((boundary) - 1)) 31 #define MIN_HISTORY_DEPTH 20 32 33 // Must be at least sizeof(InputMessage) + sufficient space for pointer data 34 static const int DEFAULT_MESSAGE_BUFFER_SIZE = ROUND_UP( 35 sizeof(InputMessage) + MIN_HISTORY_DEPTH 36 * (sizeof(InputMessage::SampleData) + MAX_POINTERS * sizeof(PointerCoords)), 37 4096); 38 39 // Signal sent by the producer to the consumer to inform it that a new message is 40 // available to be consumed in the shared memory buffer. 41 static const char INPUT_SIGNAL_DISPATCH = 'D'; 42 43 // Signal sent by the consumer to the producer to inform it that it has finished 44 // consuming the most recent message and it handled it. 45 static const char INPUT_SIGNAL_FINISHED_HANDLED = 'f'; 46 47 // Signal sent by the consumer to the producer to inform it that it has finished 48 // consuming the most recent message but it did not handle it. 49 static const char INPUT_SIGNAL_FINISHED_UNHANDLED = 'u'; 50 51 52 // --- InputChannel --- 53 54 InputChannel::InputChannel(const String8& name, int32_t ashmemFd, int32_t receivePipeFd, 55 int32_t sendPipeFd) : 56 mName(name), mAshmemFd(ashmemFd), mReceivePipeFd(receivePipeFd), mSendPipeFd(sendPipeFd) { 57 #if DEBUG_CHANNEL_LIFECYCLE 58 LOGD("Input channel constructed: name='%s', ashmemFd=%d, receivePipeFd=%d, sendPipeFd=%d", 59 mName.string(), ashmemFd, receivePipeFd, sendPipeFd); 60 #endif 61 62 int result = fcntl(mReceivePipeFd, F_SETFL, O_NONBLOCK); 63 LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make receive pipe " 64 "non-blocking. errno=%d", mName.string(), errno); 65 66 result = fcntl(mSendPipeFd, F_SETFL, O_NONBLOCK); 67 LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make send pipe " 68 "non-blocking. errno=%d", mName.string(), errno); 69 } 70 71 InputChannel::~InputChannel() { 72 #if DEBUG_CHANNEL_LIFECYCLE 73 LOGD("Input channel destroyed: name='%s', ashmemFd=%d, receivePipeFd=%d, sendPipeFd=%d", 74 mName.string(), mAshmemFd, mReceivePipeFd, mSendPipeFd); 75 #endif 76 77 ::close(mAshmemFd); 78 ::close(mReceivePipeFd); 79 ::close(mSendPipeFd); 80 } 81 82 status_t InputChannel::openInputChannelPair(const String8& name, 83 sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) { 84 status_t result; 85 86 String8 ashmemName("InputChannel "); 87 ashmemName.append(name); 88 int serverAshmemFd = ashmem_create_region(ashmemName.string(), DEFAULT_MESSAGE_BUFFER_SIZE); 89 if (serverAshmemFd < 0) { 90 result = -errno; 91 LOGE("channel '%s' ~ Could not create shared memory region. errno=%d", 92 name.string(), errno); 93 } else { 94 result = ashmem_set_prot_region(serverAshmemFd, PROT_READ | PROT_WRITE); 95 if (result < 0) { 96 LOGE("channel '%s' ~ Error %d trying to set protection of ashmem fd %d.", 97 name.string(), result, serverAshmemFd); 98 } else { 99 // Dup the file descriptor because the server and client input channel objects that 100 // are returned may have different lifetimes but they share the same shared memory region. 101 int clientAshmemFd; 102 clientAshmemFd = dup(serverAshmemFd); 103 if (clientAshmemFd < 0) { 104 result = -errno; 105 LOGE("channel '%s' ~ Could not dup() shared memory region fd. errno=%d", 106 name.string(), errno); 107 } else { 108 int forward[2]; 109 if (pipe(forward)) { 110 result = -errno; 111 LOGE("channel '%s' ~ Could not create forward pipe. errno=%d", 112 name.string(), errno); 113 } else { 114 int reverse[2]; 115 if (pipe(reverse)) { 116 result = -errno; 117 LOGE("channel '%s' ~ Could not create reverse pipe. errno=%d", 118 name.string(), errno); 119 } else { 120 String8 serverChannelName = name; 121 serverChannelName.append(" (server)"); 122 outServerChannel = new InputChannel(serverChannelName, 123 serverAshmemFd, reverse[0], forward[1]); 124 125 String8 clientChannelName = name; 126 clientChannelName.append(" (client)"); 127 outClientChannel = new InputChannel(clientChannelName, 128 clientAshmemFd, forward[0], reverse[1]); 129 return OK; 130 } 131 ::close(forward[0]); 132 ::close(forward[1]); 133 } 134 ::close(clientAshmemFd); 135 } 136 } 137 ::close(serverAshmemFd); 138 } 139 140 outServerChannel.clear(); 141 outClientChannel.clear(); 142 return result; 143 } 144 145 status_t InputChannel::sendSignal(char signal) { 146 ssize_t nWrite; 147 do { 148 nWrite = ::write(mSendPipeFd, & signal, 1); 149 } while (nWrite == -1 && errno == EINTR); 150 151 if (nWrite == 1) { 152 #if DEBUG_CHANNEL_SIGNALS 153 LOGD("channel '%s' ~ sent signal '%c'", mName.string(), signal); 154 #endif 155 return OK; 156 } 157 158 #if DEBUG_CHANNEL_SIGNALS 159 LOGD("channel '%s' ~ error sending signal '%c', errno=%d", mName.string(), signal, errno); 160 #endif 161 return -errno; 162 } 163 164 status_t InputChannel::receiveSignal(char* outSignal) { 165 ssize_t nRead; 166 do { 167 nRead = ::read(mReceivePipeFd, outSignal, 1); 168 } while (nRead == -1 && errno == EINTR); 169 170 if (nRead == 1) { 171 #if DEBUG_CHANNEL_SIGNALS 172 LOGD("channel '%s' ~ received signal '%c'", mName.string(), *outSignal); 173 #endif 174 return OK; 175 } 176 177 if (nRead == 0) { // check for EOF 178 #if DEBUG_CHANNEL_SIGNALS 179 LOGD("channel '%s' ~ receive signal failed because peer was closed", mName.string()); 180 #endif 181 return DEAD_OBJECT; 182 } 183 184 if (errno == EAGAIN) { 185 #if DEBUG_CHANNEL_SIGNALS 186 LOGD("channel '%s' ~ receive signal failed because no signal available", mName.string()); 187 #endif 188 return WOULD_BLOCK; 189 } 190 191 #if DEBUG_CHANNEL_SIGNALS 192 LOGD("channel '%s' ~ receive signal failed, errno=%d", mName.string(), errno); 193 #endif 194 return -errno; 195 } 196 197 198 // --- InputPublisher --- 199 200 InputPublisher::InputPublisher(const sp<InputChannel>& channel) : 201 mChannel(channel), mSharedMessage(NULL), 202 mPinned(false), mSemaphoreInitialized(false), mWasDispatched(false), 203 mMotionEventSampleDataTail(NULL) { 204 } 205 206 InputPublisher::~InputPublisher() { 207 reset(); 208 209 if (mSharedMessage) { 210 munmap(mSharedMessage, mAshmemSize); 211 } 212 } 213 214 status_t InputPublisher::initialize() { 215 #if DEBUG_TRANSPORT_ACTIONS 216 LOGD("channel '%s' publisher ~ initialize", 217 mChannel->getName().string()); 218 #endif 219 220 int ashmemFd = mChannel->getAshmemFd(); 221 int result = ashmem_get_size_region(ashmemFd); 222 if (result < 0) { 223 LOGE("channel '%s' publisher ~ Error %d getting size of ashmem fd %d.", 224 mChannel->getName().string(), result, ashmemFd); 225 return UNKNOWN_ERROR; 226 } 227 mAshmemSize = (size_t) result; 228 229 mSharedMessage = static_cast<InputMessage*>(mmap(NULL, mAshmemSize, 230 PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0)); 231 if (! mSharedMessage) { 232 LOGE("channel '%s' publisher ~ mmap failed on ashmem fd %d.", 233 mChannel->getName().string(), ashmemFd); 234 return NO_MEMORY; 235 } 236 237 mPinned = true; 238 mSharedMessage->consumed = false; 239 240 return reset(); 241 } 242 243 status_t InputPublisher::reset() { 244 #if DEBUG_TRANSPORT_ACTIONS 245 LOGD("channel '%s' publisher ~ reset", 246 mChannel->getName().string()); 247 #endif 248 249 if (mPinned) { 250 // Destroy the semaphore since we are about to unpin the memory region that contains it. 251 int result; 252 if (mSemaphoreInitialized) { 253 if (mSharedMessage->consumed) { 254 result = sem_post(& mSharedMessage->semaphore); 255 if (result < 0) { 256 LOGE("channel '%s' publisher ~ Error %d in sem_post.", 257 mChannel->getName().string(), errno); 258 return UNKNOWN_ERROR; 259 } 260 } 261 262 result = sem_destroy(& mSharedMessage->semaphore); 263 if (result < 0) { 264 LOGE("channel '%s' publisher ~ Error %d in sem_destroy.", 265 mChannel->getName().string(), errno); 266 return UNKNOWN_ERROR; 267 } 268 269 mSemaphoreInitialized = false; 270 } 271 272 // Unpin the region since we no longer care about its contents. 273 int ashmemFd = mChannel->getAshmemFd(); 274 result = ashmem_unpin_region(ashmemFd, 0, 0); 275 if (result < 0) { 276 LOGE("channel '%s' publisher ~ Error %d unpinning ashmem fd %d.", 277 mChannel->getName().string(), result, ashmemFd); 278 return UNKNOWN_ERROR; 279 } 280 281 mPinned = false; 282 } 283 284 mMotionEventSampleDataTail = NULL; 285 mWasDispatched = false; 286 return OK; 287 } 288 289 status_t InputPublisher::publishInputEvent( 290 int32_t type, 291 int32_t deviceId, 292 int32_t source) { 293 if (mPinned) { 294 LOGE("channel '%s' publisher ~ Attempted to publish a new event but publisher has " 295 "not yet been reset.", mChannel->getName().string()); 296 return INVALID_OPERATION; 297 } 298 299 // Pin the region. 300 // We do not check for ASHMEM_NOT_PURGED because we don't care about the previous 301 // contents of the buffer so it does not matter whether it was purged in the meantime. 302 int ashmemFd = mChannel->getAshmemFd(); 303 int result = ashmem_pin_region(ashmemFd, 0, 0); 304 if (result < 0) { 305 LOGE("channel '%s' publisher ~ Error %d pinning ashmem fd %d.", 306 mChannel->getName().string(), result, ashmemFd); 307 return UNKNOWN_ERROR; 308 } 309 310 mPinned = true; 311 312 result = sem_init(& mSharedMessage->semaphore, 1, 1); 313 if (result < 0) { 314 LOGE("channel '%s' publisher ~ Error %d in sem_init.", 315 mChannel->getName().string(), errno); 316 return UNKNOWN_ERROR; 317 } 318 319 mSemaphoreInitialized = true; 320 321 mSharedMessage->consumed = false; 322 mSharedMessage->type = type; 323 mSharedMessage->deviceId = deviceId; 324 mSharedMessage->source = source; 325 return OK; 326 } 327 328 status_t InputPublisher::publishKeyEvent( 329 int32_t deviceId, 330 int32_t source, 331 int32_t action, 332 int32_t flags, 333 int32_t keyCode, 334 int32_t scanCode, 335 int32_t metaState, 336 int32_t repeatCount, 337 nsecs_t downTime, 338 nsecs_t eventTime) { 339 #if DEBUG_TRANSPORT_ACTIONS 340 LOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, source=0x%x, " 341 "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d," 342 "downTime=%lld, eventTime=%lld", 343 mChannel->getName().string(), 344 deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, 345 downTime, eventTime); 346 #endif 347 348 status_t result = publishInputEvent(AINPUT_EVENT_TYPE_KEY, deviceId, source); 349 if (result < 0) { 350 return result; 351 } 352 353 mSharedMessage->key.action = action; 354 mSharedMessage->key.flags = flags; 355 mSharedMessage->key.keyCode = keyCode; 356 mSharedMessage->key.scanCode = scanCode; 357 mSharedMessage->key.metaState = metaState; 358 mSharedMessage->key.repeatCount = repeatCount; 359 mSharedMessage->key.downTime = downTime; 360 mSharedMessage->key.eventTime = eventTime; 361 return OK; 362 } 363 364 status_t InputPublisher::publishMotionEvent( 365 int32_t deviceId, 366 int32_t source, 367 int32_t action, 368 int32_t flags, 369 int32_t edgeFlags, 370 int32_t metaState, 371 int32_t buttonState, 372 float xOffset, 373 float yOffset, 374 float xPrecision, 375 float yPrecision, 376 nsecs_t downTime, 377 nsecs_t eventTime, 378 size_t pointerCount, 379 const PointerProperties* pointerProperties, 380 const PointerCoords* pointerCoords) { 381 #if DEBUG_TRANSPORT_ACTIONS 382 LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=0x%x, " 383 "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, " 384 "xOffset=%f, yOffset=%f, " 385 "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, " 386 "pointerCount=%d", 387 mChannel->getName().string(), 388 deviceId, source, action, flags, edgeFlags, metaState, buttonState, 389 xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount); 390 #endif 391 392 if (pointerCount > MAX_POINTERS || pointerCount < 1) { 393 LOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.", 394 mChannel->getName().string(), pointerCount); 395 return BAD_VALUE; 396 } 397 398 status_t result = publishInputEvent(AINPUT_EVENT_TYPE_MOTION, deviceId, source); 399 if (result < 0) { 400 return result; 401 } 402 403 mSharedMessage->motion.action = action; 404 mSharedMessage->motion.flags = flags; 405 mSharedMessage->motion.edgeFlags = edgeFlags; 406 mSharedMessage->motion.metaState = metaState; 407 mSharedMessage->motion.buttonState = buttonState; 408 mSharedMessage->motion.xOffset = xOffset; 409 mSharedMessage->motion.yOffset = yOffset; 410 mSharedMessage->motion.xPrecision = xPrecision; 411 mSharedMessage->motion.yPrecision = yPrecision; 412 mSharedMessage->motion.downTime = downTime; 413 mSharedMessage->motion.pointerCount = pointerCount; 414 415 mSharedMessage->motion.sampleCount = 1; 416 mSharedMessage->motion.sampleData[0].eventTime = eventTime; 417 418 for (size_t i = 0; i < pointerCount; i++) { 419 mSharedMessage->motion.pointerProperties[i].copyFrom(pointerProperties[i]); 420 mSharedMessage->motion.sampleData[0].coords[i].copyFrom(pointerCoords[i]); 421 } 422 423 // Cache essential information about the motion event to ensure that a malicious consumer 424 // cannot confuse the publisher by modifying the contents of the shared memory buffer while 425 // it is being updated. 426 if (action == AMOTION_EVENT_ACTION_MOVE 427 || action == AMOTION_EVENT_ACTION_HOVER_MOVE) { 428 mMotionEventPointerCount = pointerCount; 429 mMotionEventSampleDataStride = InputMessage::sampleDataStride(pointerCount); 430 mMotionEventSampleDataTail = InputMessage::sampleDataPtrIncrement( 431 mSharedMessage->motion.sampleData, mMotionEventSampleDataStride); 432 } else { 433 mMotionEventSampleDataTail = NULL; 434 } 435 return OK; 436 } 437 438 status_t InputPublisher::appendMotionSample( 439 nsecs_t eventTime, 440 const PointerCoords* pointerCoords) { 441 #if DEBUG_TRANSPORT_ACTIONS 442 LOGD("channel '%s' publisher ~ appendMotionSample: eventTime=%lld", 443 mChannel->getName().string(), eventTime); 444 #endif 445 446 if (! mPinned || ! mMotionEventSampleDataTail) { 447 LOGE("channel '%s' publisher ~ Cannot append motion sample because there is no current " 448 "AMOTION_EVENT_ACTION_MOVE or AMOTION_EVENT_ACTION_HOVER_MOVE event.", 449 mChannel->getName().string()); 450 return INVALID_OPERATION; 451 } 452 453 InputMessage::SampleData* newTail = InputMessage::sampleDataPtrIncrement( 454 mMotionEventSampleDataTail, mMotionEventSampleDataStride); 455 size_t newBytesUsed = reinterpret_cast<char*>(newTail) - 456 reinterpret_cast<char*>(mSharedMessage); 457 458 if (newBytesUsed > mAshmemSize) { 459 #if DEBUG_TRANSPORT_ACTIONS 460 LOGD("channel '%s' publisher ~ Cannot append motion sample because the shared memory " 461 "buffer is full. Buffer size: %d bytes, pointers: %d, samples: %d", 462 mChannel->getName().string(), 463 mAshmemSize, mMotionEventPointerCount, mSharedMessage->motion.sampleCount); 464 #endif 465 return NO_MEMORY; 466 } 467 468 int result; 469 if (mWasDispatched) { 470 result = sem_trywait(& mSharedMessage->semaphore); 471 if (result < 0) { 472 if (errno == EAGAIN) { 473 // Only possible source of contention is the consumer having consumed (or being in the 474 // process of consuming) the message and left the semaphore count at 0. 475 #if DEBUG_TRANSPORT_ACTIONS 476 LOGD("channel '%s' publisher ~ Cannot append motion sample because the message has " 477 "already been consumed.", mChannel->getName().string()); 478 #endif 479 return FAILED_TRANSACTION; 480 } else { 481 LOGE("channel '%s' publisher ~ Error %d in sem_trywait.", 482 mChannel->getName().string(), errno); 483 return UNKNOWN_ERROR; 484 } 485 } 486 } 487 488 mMotionEventSampleDataTail->eventTime = eventTime; 489 for (size_t i = 0; i < mMotionEventPointerCount; i++) { 490 mMotionEventSampleDataTail->coords[i].copyFrom(pointerCoords[i]); 491 } 492 mMotionEventSampleDataTail = newTail; 493 494 mSharedMessage->motion.sampleCount += 1; 495 496 if (mWasDispatched) { 497 result = sem_post(& mSharedMessage->semaphore); 498 if (result < 0) { 499 LOGE("channel '%s' publisher ~ Error %d in sem_post.", 500 mChannel->getName().string(), errno); 501 return UNKNOWN_ERROR; 502 } 503 } 504 return OK; 505 } 506 507 status_t InputPublisher::sendDispatchSignal() { 508 #if DEBUG_TRANSPORT_ACTIONS 509 LOGD("channel '%s' publisher ~ sendDispatchSignal", 510 mChannel->getName().string()); 511 #endif 512 513 mWasDispatched = true; 514 return mChannel->sendSignal(INPUT_SIGNAL_DISPATCH); 515 } 516 517 status_t InputPublisher::receiveFinishedSignal(bool* outHandled) { 518 #if DEBUG_TRANSPORT_ACTIONS 519 LOGD("channel '%s' publisher ~ receiveFinishedSignal", 520 mChannel->getName().string()); 521 #endif 522 523 char signal; 524 status_t result = mChannel->receiveSignal(& signal); 525 if (result) { 526 *outHandled = false; 527 return result; 528 } 529 if (signal == INPUT_SIGNAL_FINISHED_HANDLED) { 530 *outHandled = true; 531 } else if (signal == INPUT_SIGNAL_FINISHED_UNHANDLED) { 532 *outHandled = false; 533 } else { 534 LOGE("channel '%s' publisher ~ Received unexpected signal '%c' from consumer", 535 mChannel->getName().string(), signal); 536 return UNKNOWN_ERROR; 537 } 538 return OK; 539 } 540 541 // --- InputConsumer --- 542 543 InputConsumer::InputConsumer(const sp<InputChannel>& channel) : 544 mChannel(channel), mSharedMessage(NULL) { 545 } 546 547 InputConsumer::~InputConsumer() { 548 if (mSharedMessage) { 549 munmap(mSharedMessage, mAshmemSize); 550 } 551 } 552 553 status_t InputConsumer::initialize() { 554 #if DEBUG_TRANSPORT_ACTIONS 555 LOGD("channel '%s' consumer ~ initialize", 556 mChannel->getName().string()); 557 #endif 558 559 int ashmemFd = mChannel->getAshmemFd(); 560 int result = ashmem_get_size_region(ashmemFd); 561 if (result < 0) { 562 LOGE("channel '%s' consumer ~ Error %d getting size of ashmem fd %d.", 563 mChannel->getName().string(), result, ashmemFd); 564 return UNKNOWN_ERROR; 565 } 566 567 mAshmemSize = (size_t) result; 568 569 mSharedMessage = static_cast<InputMessage*>(mmap(NULL, mAshmemSize, 570 PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0)); 571 if (! mSharedMessage) { 572 LOGE("channel '%s' consumer ~ mmap failed on ashmem fd %d.", 573 mChannel->getName().string(), ashmemFd); 574 return NO_MEMORY; 575 } 576 577 return OK; 578 } 579 580 status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent** outEvent) { 581 #if DEBUG_TRANSPORT_ACTIONS 582 LOGD("channel '%s' consumer ~ consume", 583 mChannel->getName().string()); 584 #endif 585 586 *outEvent = NULL; 587 588 int ashmemFd = mChannel->getAshmemFd(); 589 int result = ashmem_pin_region(ashmemFd, 0, 0); 590 if (result != ASHMEM_NOT_PURGED) { 591 if (result == ASHMEM_WAS_PURGED) { 592 LOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d because it was purged " 593 "which probably indicates that the publisher and consumer are out of sync.", 594 mChannel->getName().string(), result, ashmemFd); 595 return INVALID_OPERATION; 596 } 597 598 LOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d.", 599 mChannel->getName().string(), result, ashmemFd); 600 return UNKNOWN_ERROR; 601 } 602 603 if (mSharedMessage->consumed) { 604 LOGE("channel '%s' consumer ~ The current message has already been consumed.", 605 mChannel->getName().string()); 606 return INVALID_OPERATION; 607 } 608 609 // Acquire but *never release* the semaphore. Contention on the semaphore is used to signal 610 // to the publisher that the message has been consumed (or is in the process of being 611 // consumed). Eventually the publisher will reinitialize the semaphore for the next message. 612 result = sem_wait(& mSharedMessage->semaphore); 613 if (result < 0) { 614 LOGE("channel '%s' consumer ~ Error %d in sem_wait.", 615 mChannel->getName().string(), errno); 616 return UNKNOWN_ERROR; 617 } 618 619 mSharedMessage->consumed = true; 620 621 switch (mSharedMessage->type) { 622 case AINPUT_EVENT_TYPE_KEY: { 623 KeyEvent* keyEvent = factory->createKeyEvent(); 624 if (! keyEvent) return NO_MEMORY; 625 626 populateKeyEvent(keyEvent); 627 628 *outEvent = keyEvent; 629 break; 630 } 631 632 case AINPUT_EVENT_TYPE_MOTION: { 633 MotionEvent* motionEvent = factory->createMotionEvent(); 634 if (! motionEvent) return NO_MEMORY; 635 636 populateMotionEvent(motionEvent); 637 638 *outEvent = motionEvent; 639 break; 640 } 641 642 default: 643 LOGE("channel '%s' consumer ~ Received message of unknown type %d", 644 mChannel->getName().string(), mSharedMessage->type); 645 return UNKNOWN_ERROR; 646 } 647 648 return OK; 649 } 650 651 status_t InputConsumer::sendFinishedSignal(bool handled) { 652 #if DEBUG_TRANSPORT_ACTIONS 653 LOGD("channel '%s' consumer ~ sendFinishedSignal: handled=%d", 654 mChannel->getName().string(), handled); 655 #endif 656 657 return mChannel->sendSignal(handled 658 ? INPUT_SIGNAL_FINISHED_HANDLED 659 : INPUT_SIGNAL_FINISHED_UNHANDLED); 660 } 661 662 status_t InputConsumer::receiveDispatchSignal() { 663 #if DEBUG_TRANSPORT_ACTIONS 664 LOGD("channel '%s' consumer ~ receiveDispatchSignal", 665 mChannel->getName().string()); 666 #endif 667 668 char signal; 669 status_t result = mChannel->receiveSignal(& signal); 670 if (result) { 671 return result; 672 } 673 if (signal != INPUT_SIGNAL_DISPATCH) { 674 LOGE("channel '%s' consumer ~ Received unexpected signal '%c' from publisher", 675 mChannel->getName().string(), signal); 676 return UNKNOWN_ERROR; 677 } 678 return OK; 679 } 680 681 void InputConsumer::populateKeyEvent(KeyEvent* keyEvent) const { 682 keyEvent->initialize( 683 mSharedMessage->deviceId, 684 mSharedMessage->source, 685 mSharedMessage->key.action, 686 mSharedMessage->key.flags, 687 mSharedMessage->key.keyCode, 688 mSharedMessage->key.scanCode, 689 mSharedMessage->key.metaState, 690 mSharedMessage->key.repeatCount, 691 mSharedMessage->key.downTime, 692 mSharedMessage->key.eventTime); 693 } 694 695 void InputConsumer::populateMotionEvent(MotionEvent* motionEvent) const { 696 motionEvent->initialize( 697 mSharedMessage->deviceId, 698 mSharedMessage->source, 699 mSharedMessage->motion.action, 700 mSharedMessage->motion.flags, 701 mSharedMessage->motion.edgeFlags, 702 mSharedMessage->motion.metaState, 703 mSharedMessage->motion.buttonState, 704 mSharedMessage->motion.xOffset, 705 mSharedMessage->motion.yOffset, 706 mSharedMessage->motion.xPrecision, 707 mSharedMessage->motion.yPrecision, 708 mSharedMessage->motion.downTime, 709 mSharedMessage->motion.sampleData[0].eventTime, 710 mSharedMessage->motion.pointerCount, 711 mSharedMessage->motion.pointerProperties, 712 mSharedMessage->motion.sampleData[0].coords); 713 714 size_t sampleCount = mSharedMessage->motion.sampleCount; 715 if (sampleCount > 1) { 716 InputMessage::SampleData* sampleData = mSharedMessage->motion.sampleData; 717 size_t sampleDataStride = InputMessage::sampleDataStride( 718 mSharedMessage->motion.pointerCount); 719 720 while (--sampleCount > 0) { 721 sampleData = InputMessage::sampleDataPtrIncrement(sampleData, sampleDataStride); 722 motionEvent->addSample(sampleData->eventTime, sampleData->coords); 723 } 724 } 725 } 726 727 } // namespace android 728