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