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