widget/gonk/libui/InputTransport.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial