15912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown//
25912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Copyright 2010 The Android Open Source Project
35912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown//
45912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Provides a shared memory transport for input events.
55912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown//
65912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define LOG_TAG "InputTransport"
75912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
85912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown//#define LOG_NDEBUG 0
95912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Log debug messages about channel messages (send message, receive message)
115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define DEBUG_CHANNEL_MESSAGES 0
125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Log debug messages whenever InputChannel objects are created/destroyed
145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define DEBUG_CHANNEL_LIFECYCLE 0
155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Log debug messages about transport actions
175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define DEBUG_TRANSPORT_ACTIONS 0
185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Log debug messages about touch event resampling
205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define DEBUG_RESAMPLING 0
215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <errno.h>
245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <fcntl.h>
25d0a4a6234f3d97f5e7fb86b028d3ee79dd4e3fa6Michael Wright#include <inttypes.h>
265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <math.h>
275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <sys/types.h>
285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <sys/socket.h>
295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <unistd.h>
305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <cutils/log.h>
325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <cutils/properties.h>
335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <input/InputTransport.h>
345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownnamespace android {
375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Socket buffer size.  The default is typically about 128KB, which is much larger than
395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// we really need.  So we make it smaller.  It just needs to be big enough to hold
405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// a few dozen large multi-finger motion events in the case where an application gets
415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// behind processing touches.
425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Nanoseconds per milliseconds.
455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic const nsecs_t NANOS_PER_MS = 1000000;
465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Latency added during resampling.  A few milliseconds doesn't hurt much but
485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// reduces the impact of mispredicted touch positions.
495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Minimum time difference between consecutive samples before attempting to resample.
525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
54de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes// Maximum time difference between consecutive samples before attempting to resample
55de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes// by extrapolation.
56de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyesstatic const nsecs_t RESAMPLE_MAX_DELTA = 20 * NANOS_PER_MS;
57de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes
585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// Maximum time to predict forward from the last known state, to avoid predicting too
595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// far into the future.  This time is further bounded by 50% of the last time delta.
605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatic const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Browntemplate<typename T>
635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Browninline static T min(const T& a, const T& b) {
645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return a < b ? a : b;
655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Browninline static float lerp(float a, float b, float alpha) {
685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return a + alpha * (b - a);
695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- InputMessage ---
725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool InputMessage::isValid(size_t actualSize) const {
745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (size() == actualSize) {
755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        switch (header.type) {
765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case TYPE_KEY:
775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return true;
785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case TYPE_MOTION:
795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return body.motion.pointerCount > 0
805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    && body.motion.pointerCount <= MAX_POINTERS;
815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case TYPE_FINISHED:
825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return true;
835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return false;
865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownsize_t InputMessage::size() const {
895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (header.type) {
905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case TYPE_KEY:
915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return sizeof(Header) + body.key.size();
925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case TYPE_MOTION:
935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return sizeof(Header) + body.motion.size();
945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case TYPE_FINISHED:
955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return sizeof(Header) + body.finished.size();
965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return sizeof(Header);
985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- InputChannel ---
1025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownInputChannel::InputChannel(const String8& name, int fd) :
1045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mName(name), mFd(fd) {
1055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_LIFECYCLE
1065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("Input channel constructed: name='%s', fd=%d",
1075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mName.string(), fd);
1085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
1095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
1115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
1125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            "non-blocking.  errno=%d", mName.string(), errno);
1135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownInputChannel::~InputChannel() {
1165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_LIFECYCLE
1175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("Input channel destroyed: name='%s', fd=%d",
1185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mName.string(), mFd);
1195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
1205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ::close(mFd);
1225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputChannel::openInputChannelPair(const String8& name,
1255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
1265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    int sockets[2];
1275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
1285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        status_t result = -errno;
1295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d",
1305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                name.string(), errno);
1315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        outServerChannel.clear();
1325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        outClientChannel.clear();
1335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return result;
1345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    int bufferSize = SOCKET_BUFFER_SIZE;
1375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
1385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
1395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
1405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
1415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    String8 serverChannelName = name;
1435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    serverChannelName.append(" (server)");
1445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    outServerChannel = new InputChannel(serverChannelName, sockets[0]);
1455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    String8 clientChannelName = name;
1475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    clientChannelName.append(" (client)");
1485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    outClientChannel = new InputChannel(clientChannelName, sockets[1]);
1495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
1505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputChannel::sendMessage(const InputMessage* msg) {
1535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t msgLength = msg->size();
1545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ssize_t nWrite;
1555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    do {
1565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
1575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } while (nWrite == -1 && errno == EINTR);
1585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (nWrite < 0) {
1605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int error = errno;
1615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_MESSAGES
1625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
1635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                msg->header.type, error);
1645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
1655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (error == EAGAIN || error == EWOULDBLOCK) {
1665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return WOULD_BLOCK;
1675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED || error == ECONNRESET) {
1695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return DEAD_OBJECT;
1705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return -error;
1725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (size_t(nWrite) != msgLength) {
1755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_MESSAGES
1765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
1775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                mName.string(), msg->header.type);
1785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
1795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return DEAD_OBJECT;
1805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
1815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_MESSAGES
1835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
1845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
1855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
1865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
1875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputChannel::receiveMessage(InputMessage* msg) {
1895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ssize_t nRead;
1905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    do {
1915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
1925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } while (nRead == -1 && errno == EINTR);
1935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (nRead < 0) {
1955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int error = errno;
1965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_MESSAGES
1975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
1985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
1995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (error == EAGAIN || error == EWOULDBLOCK) {
2005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return WOULD_BLOCK;
2015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
2025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
2035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return DEAD_OBJECT;
2045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
2055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return -error;
2065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (nRead == 0) { // check for EOF
2095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_MESSAGES
2105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
2115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
2125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return DEAD_OBJECT;
2135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!msg->isValid(nRead)) {
2165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_MESSAGES
2175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("channel '%s' ~ received invalid message", mName.string());
2185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
2195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
2205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_CHANNEL_MESSAGES
2235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
2245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
2255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
2265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownsp<InputChannel> InputChannel::dup() const {
2295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    int fd = ::dup(getFd());
2305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return fd >= 0 ? new InputChannel(getName(), fd) : NULL;
2315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- InputPublisher ---
2355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownInputPublisher::InputPublisher(const sp<InputChannel>& channel) :
2375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mChannel(channel) {
2385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownInputPublisher::~InputPublisher() {
2415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputPublisher::publishKeyEvent(
2445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t seq,
2455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t deviceId,
2465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t source,
2475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t action,
2485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t flags,
2495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t keyCode,
2505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t scanCode,
2515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t metaState,
2525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t repeatCount,
2535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t downTime,
2545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime) {
2555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
2565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
2575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
2585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            "downTime=%lld, eventTime=%lld",
2595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mChannel->getName().string(), seq,
2605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
2615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            downTime, eventTime);
2625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
2635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!seq) {
2655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGE("Attempted to publish a key event with sequence number 0.");
2665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
2675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
2685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputMessage msg;
2705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.header.type = InputMessage::TYPE_KEY;
2715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.seq = seq;
2725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.deviceId = deviceId;
2735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.source = source;
2745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.action = action;
2755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.flags = flags;
2765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.keyCode = keyCode;
2775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.scanCode = scanCode;
2785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.metaState = metaState;
2795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.repeatCount = repeatCount;
2805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.downTime = downTime;
2815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.key.eventTime = eventTime;
2825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return mChannel->sendMessage(&msg);
2835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
2845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputPublisher::publishMotionEvent(
2865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t seq,
2875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t deviceId,
2885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t source,
2895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t action,
2907b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright        int32_t actionButton,
2915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t flags,
2925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t edgeFlags,
2935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t metaState,
2945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        int32_t buttonState,
2955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xOffset,
2965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float yOffset,
2975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xPrecision,
2985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float yPrecision,
2995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t downTime,
3005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime,
301bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath        uint32_t pointerCount,
3025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerProperties* pointerProperties,
3035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerCoords* pointerCoords) {
3045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
3055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
3067b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            "action=0x%x, actionButton=0x%08x, flags=0x%x, edgeFlags=0x%x, "
3077b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            "metaState=0x%x, buttonState=0x%x, xOffset=%f, yOffset=%f, "
3085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
30963ff3a84ae5f60fc427aed4f63364b50695266d9Michael Wright            "pointerCount=%" PRIu32,
3105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mChannel->getName().string(), seq,
3117b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            deviceId, source, action, actionButton, flags, edgeFlags, metaState, buttonState,
3125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
3135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
3145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!seq) {
3165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGE("Attempted to publish a motion event with sequence number 0.");
3175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
3185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
32163ff3a84ae5f60fc427aed4f63364b50695266d9Michael Wright        ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %" PRIu32 ".",
3225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                mChannel->getName().string(), pointerCount);
3235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
3245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputMessage msg;
3275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.header.type = InputMessage::TYPE_MOTION;
3285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.seq = seq;
3295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.deviceId = deviceId;
3305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.source = source;
3315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.action = action;
3327b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright    msg.body.motion.actionButton = actionButton;
3335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.flags = flags;
3345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.edgeFlags = edgeFlags;
3355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.metaState = metaState;
3365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.buttonState = buttonState;
3375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.xOffset = xOffset;
3385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.yOffset = yOffset;
3395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.xPrecision = xPrecision;
3405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.yPrecision = yPrecision;
3415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.downTime = downTime;
3425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.eventTime = eventTime;
3435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.motion.pointerCount = pointerCount;
344bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath    for (uint32_t i = 0; i < pointerCount; i++) {
3455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
3465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
3475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return mChannel->sendMessage(&msg);
3495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
3525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
3535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
3545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mChannel->getName().string());
3555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
3565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputMessage msg;
3585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    status_t result = mChannel->receiveMessage(&msg);
3595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (result) {
3605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        *outSeq = 0;
3615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        *outHandled = false;
3625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return result;
3635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (msg.header.type != InputMessage::TYPE_FINISHED) {
3655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
3665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                mChannel->getName().string(), msg.header.type);
3675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return UNKNOWN_ERROR;
3685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    *outSeq = msg.body.finished.seq;
3705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    *outHandled = msg.body.finished.handled;
3715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
3725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown// --- InputConsumer ---
3755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownInputConsumer::InputConsumer(const sp<InputChannel>& channel) :
3775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mResampleTouch(isTouchResamplingEnabled()),
3785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        mChannel(channel), mMsgDeferred(false) {
3795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff BrownInputConsumer::~InputConsumer() {
3825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool InputConsumer::isTouchResamplingEnabled() {
3855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    char value[PROPERTY_VALUE_MAX];
386ad526f8505efe2ccd800e4665864b10bdae31e29Michael Wright    int length = property_get("ro.input.noresample", value, NULL);
3875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (length > 0) {
388ad526f8505efe2ccd800e4665864b10bdae31e29Michael Wright        if (!strcmp("1", value)) {
3895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return false;
3905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
391ad526f8505efe2ccd800e4665864b10bdae31e29Michael Wright        if (strcmp("0", value)) {
392ad526f8505efe2ccd800e4665864b10bdae31e29Michael Wright            ALOGD("Unrecognized property value for 'ro.input.noresample'.  "
3935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    "Use '1' or '0'.");
3945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
3955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
3965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return true;
3975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
3985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
3995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputConsumer::consume(InputEventFactoryInterface* factory,
4005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
4015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
4025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld",
4035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime);
4045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
4055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    *outSeq = 0;
4075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    *outEvent = NULL;
4085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Fetch the next input message.
4105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Loop until an event can be returned or no additional events are received.
4115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    while (!*outEvent) {
4125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (mMsgDeferred) {
4135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            // mMsg contains a valid input message from the previous call to consume
4145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            // that has not yet been processed.
4155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mMsgDeferred = false;
4165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        } else {
4175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            // Receive a fresh message.
4185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            status_t result = mChannel->receiveMessage(&mMsg);
4195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (result) {
4205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                // Consume the next batched event unless batches are being held for later.
4215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                if (consumeBatches || result != WOULD_BLOCK) {
4225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    result = consumeBatch(factory, frameTime, outSeq, outEvent);
4235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    if (*outEvent) {
4245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
4255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                        ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
4265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                                mChannel->getName().string(), *outSeq);
4275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
4285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                        break;
4295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    }
4305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                }
4315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                return result;
4325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
4335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
4345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        switch (mMsg.header.type) {
4365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case InputMessage::TYPE_KEY: {
4375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            KeyEvent* keyEvent = factory->createKeyEvent();
4385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (!keyEvent) return NO_MEMORY;
4395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            initializeKeyEvent(keyEvent, &mMsg);
4415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            *outSeq = mMsg.body.key.seq;
4425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            *outEvent = keyEvent;
4435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
4445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
4455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    mChannel->getName().string(), *outSeq);
4465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
4475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            break;
4485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
4495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        case AINPUT_EVENT_TYPE_MOTION: {
4515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
4525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (batchIndex >= 0) {
4535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                Batch& batch = mBatches.editItemAt(batchIndex);
4545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                if (canAddSample(batch, &mMsg)) {
4555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    batch.samples.push(mMsg);
4565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
4575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    ALOGD("channel '%s' consumer ~ appended to batch event",
4585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                            mChannel->getName().string());
4595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
4605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    break;
4615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                } else {
4625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    // We cannot append to the batch in progress, so we need to consume
4635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    // the previous batch right now and defer the new message until later.
4645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    mMsgDeferred = true;
4655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    status_t result = consumeSamples(factory,
4665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                            batch, batch.samples.size(), outSeq, outEvent);
4675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    mBatches.removeAt(batchIndex);
4685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    if (result) {
4695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                        return result;
4705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    }
4715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
4725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    ALOGD("channel '%s' consumer ~ consumed batch event and "
4735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                            "deferred current event, seq=%u",
4745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                            mChannel->getName().string(), *outSeq);
4755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
4765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    break;
4775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                }
4785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
4795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            // Start a new batch if needed.
4815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
4825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
4835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                mBatches.push();
4845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                Batch& batch = mBatches.editTop();
4855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                batch.samples.push(mMsg);
4865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
4875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                ALOGD("channel '%s' consumer ~ started batch event",
4885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                        mChannel->getName().string());
4895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
4905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                break;
4915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
4925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            MotionEvent* motionEvent = factory->createMotionEvent();
4945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (! motionEvent) return NO_MEMORY;
4955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
4965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            updateTouchState(&mMsg);
4975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            initializeMotionEvent(motionEvent, &mMsg);
4985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            *outSeq = mMsg.body.motion.seq;
4995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            *outEvent = motionEvent;
5005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
5015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
5025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    mChannel->getName().string(), *outSeq);
5035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
5045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            break;
5055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        default:
5085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
5095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    mChannel->getName().string(), mMsg.header.type);
5105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return UNKNOWN_ERROR;
5115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
5145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
5175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
5185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    status_t result;
5191faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin    for (size_t i = mBatches.size(); i > 0; ) {
5201faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin        i--;
5215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        Batch& batch = mBatches.editItemAt(i);
5223223217aed6dcfa55b5b952cd6be71f70e41ba63Michael Wright        if (frameTime < 0) {
5235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            result = consumeSamples(factory, batch, batch.samples.size(),
5245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    outSeq, outEvent);
5255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mBatches.removeAt(i);
5265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return result;
5275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5293223217aed6dcfa55b5b952cd6be71f70e41ba63Michael Wright        nsecs_t sampleTime = frameTime;
5303223217aed6dcfa55b5b952cd6be71f70e41ba63Michael Wright        if (mResampleTouch) {
5313223217aed6dcfa55b5b952cd6be71f70e41ba63Michael Wright            sampleTime -= RESAMPLE_LATENCY;
5323223217aed6dcfa55b5b952cd6be71f70e41ba63Michael Wright        }
5335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ssize_t split = findSampleNoLaterThan(batch, sampleTime);
5345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (split < 0) {
5355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            continue;
5365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
5395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const InputMessage* next;
5405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (batch.samples.isEmpty()) {
5415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mBatches.removeAt(i);
5425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            next = NULL;
5435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        } else {
5445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            next = &batch.samples.itemAt(0);
5455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5463223217aed6dcfa55b5b952cd6be71f70e41ba63Michael Wright        if (!result && mResampleTouch) {
5475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
5485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return result;
5505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return WOULD_BLOCK;
5535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
5565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
5575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    MotionEvent* motionEvent = factory->createMotionEvent();
5585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (! motionEvent) return NO_MEMORY;
5595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t chain = 0;
5615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < count; i++) {
5625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        InputMessage& msg = batch.samples.editItemAt(i);
5635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        updateTouchState(&msg);
5645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (i) {
5655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            SeqChain seqChain;
5665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            seqChain.seq = msg.body.motion.seq;
5675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            seqChain.chain = chain;
5685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mSeqChains.push(seqChain);
5695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            addSample(motionEvent, &msg);
5705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        } else {
5715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            initializeMotionEvent(motionEvent, &msg);
5725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
5735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        chain = msg.body.motion.seq;
5745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    batch.samples.removeItemsAt(0, count);
5765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    *outSeq = chain;
5785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    *outEvent = motionEvent;
5795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return OK;
5805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
5815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputConsumer::updateTouchState(InputMessage* msg) {
5835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!mResampleTouch ||
5845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
5855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return;
5865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
5875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    int32_t deviceId = msg->body.motion.deviceId;
5895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    int32_t source = msg->body.motion.source;
5905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    nsecs_t eventTime = msg->body.motion.eventTime;
5915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
5925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Update the touch state history to incorporate the new input message.
5935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // If the message is in the past relative to the most recently produced resampled
5945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // touch, then use the resampled time and coordinates instead.
5955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) {
5965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_ACTION_DOWN: {
5975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ssize_t index = findTouchState(deviceId, source);
5985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (index < 0) {
5995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mTouchStates.push();
6005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            index = mTouchStates.size() - 1;
6015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        TouchState& touchState = mTouchStates.editItemAt(index);
6035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        touchState.initialize(deviceId, source);
6045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        touchState.addHistory(msg);
6055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_ACTION_MOVE: {
6095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ssize_t index = findTouchState(deviceId, source);
6105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (index >= 0) {
6115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            TouchState& touchState = mTouchStates.editItemAt(index);
6125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            touchState.addHistory(msg);
6135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            if (eventTime < touchState.lastResample.eventTime) {
6145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                rewriteMessage(touchState, msg);
6155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            } else {
6165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                touchState.lastResample.idBits.clear();
6175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
6185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
6235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ssize_t index = findTouchState(deviceId, source);
6245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (index >= 0) {
6255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            TouchState& touchState = mTouchStates.editItemAt(index);
6265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
6275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            rewriteMessage(touchState, msg);
6285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_ACTION_POINTER_UP: {
6335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ssize_t index = findTouchState(deviceId, source);
6345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (index >= 0) {
6355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            TouchState& touchState = mTouchStates.editItemAt(index);
6365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            rewriteMessage(touchState, msg);
6375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
6385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_ACTION_SCROLL: {
6435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ssize_t index = findTouchState(deviceId, source);
6445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (index >= 0) {
6455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const TouchState& touchState = mTouchStates.itemAt(index);
6465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            rewriteMessage(touchState, msg);
6475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_ACTION_UP:
6525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    case AMOTION_EVENT_ACTION_CANCEL: {
6535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ssize_t index = findTouchState(deviceId, source);
6545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (index >= 0) {
6555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const TouchState& touchState = mTouchStates.itemAt(index);
6565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            rewriteMessage(touchState, msg);
6575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mTouchStates.removeAt(index);
6585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        break;
6605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
6635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
665bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath    for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) {
6665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t id = msg->body.motion.pointers[i].properties.id;
6675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (state.lastResample.idBits.hasBit(id)) {
6685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
6695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
6705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
6715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
6725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
6735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y),
6745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
6755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
6765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
6775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
6785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
6795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
6805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
6825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
6845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const InputMessage* next) {
6855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!mResampleTouch
6865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER)
6875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
6885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return;
6895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
6925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (index < 0) {
6935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
6945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("Not resampled, no touch state for device.");
6955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
6965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return;
6975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
6985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
6995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    TouchState& touchState = mTouchStates.editItemAt(index);
7005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (touchState.historySize < 1) {
7015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
7025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("Not resampled, no history for device.");
7035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
7045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return;
7055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
7065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
7075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Ensure that the current sample has all of the pointers that need to be reported.
7085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const History* current = touchState.getHistory(0);
7095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t pointerCount = event->getPointerCount();
7105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
7115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t id = event->getPointerId(i);
7125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (!current->idBits.hasBit(id)) {
7135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
7145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGD("Not resampled, missing id %d", id);
7155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
7165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return;
7175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
7185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
7195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
7205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Find the data to use for resampling.
7215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const History* other;
7225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    History future;
7235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float alpha;
7245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (next) {
7255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Interpolate between current sample and future sample.
7265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // So current->eventTime <= sampleTime <= future.eventTime.
7275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        future.initializeFrom(next);
7285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        other = &future;
7295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t delta = future.eventTime - current->eventTime;
7305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (delta < RESAMPLE_MIN_DELTA) {
7315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
732de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes            ALOGD("Not resampled, delta time is too small: %lld ns.", delta);
7335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
7345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return;
7355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
7365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        alpha = float(sampleTime - current->eventTime) / delta;
7375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } else if (touchState.historySize >= 2) {
7385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Extrapolate future sample using current sample and past sample.
7395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // So other->eventTime <= current->eventTime <= sampleTime.
7405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        other = touchState.getHistory(1);
7415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t delta = current->eventTime - other->eventTime;
7425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (delta < RESAMPLE_MIN_DELTA) {
7435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
744de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes            ALOGD("Not resampled, delta time is too small: %lld ns.", delta);
745de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes#endif
746de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes            return;
747de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes        } else if (delta > RESAMPLE_MAX_DELTA) {
748de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes#if DEBUG_RESAMPLING
749de18f6c32add6fb22065807a00ddc88b363df527Andrew de los Reyes            ALOGD("Not resampled, delta time is too large: %lld ns.", delta);
7505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
7515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return;
7525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
7535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
7545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (sampleTime > maxPredict) {
7555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
7565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGD("Sample time is too far in the future, adjusting prediction "
7575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    "from %lld to %lld ns.",
7585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    sampleTime - current->eventTime, maxPredict - current->eventTime);
7595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
7605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            sampleTime = maxPredict;
7615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
7625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        alpha = float(current->eventTime - sampleTime) / delta;
7635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    } else {
7645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
7655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGD("Not resampled, insufficient data.");
7665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
7675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return;
7685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
7695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
7705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Resample touch coordinates.
7715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    touchState.lastResample.eventTime = sampleTime;
7725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    touchState.lastResample.idBits.clear();
7735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
7745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t id = event->getPointerId(i);
7755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        touchState.lastResample.idToIndex[id] = i;
7765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        touchState.lastResample.idBits.markBit(id);
7775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
7785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const PointerCoords& currentCoords = current->getPointerById(id);
7795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (other->idBits.hasBit(id)
7805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                && shouldResampleTool(event->getToolType(i))) {
7815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const PointerCoords& otherCoords = other->getPointerById(id);
7825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            resampledCoords.copyFrom(currentCoords);
7835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
7845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    lerp(currentCoords.getX(), otherCoords.getX(), alpha));
7855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
7865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    lerp(currentCoords.getY(), otherCoords.getY(), alpha));
7875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
7885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
7895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    "other (%0.3f, %0.3f), alpha %0.3f",
7905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    id, resampledCoords.getX(), resampledCoords.getY(),
7915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    currentCoords.getX(), currentCoords.getY(),
7925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    otherCoords.getX(), otherCoords.getY(),
7935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    alpha);
7945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
7955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        } else {
7965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            resampledCoords.copyFrom(currentCoords);
7975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_RESAMPLING
7985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
7995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    id, resampledCoords.getX(), resampledCoords.getY(),
8005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                    currentCoords.getX(), currentCoords.getY());
8015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
8025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
8035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
8045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    event->addSample(sampleTime, touchState.lastResample.pointers);
8065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool InputConsumer::shouldResampleTool(int32_t toolType) {
8095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
8105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
8115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
8145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#if DEBUG_TRANSPORT_ACTIONS
8155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
8165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            mChannel->getName().string(), seq, handled ? "true" : "false");
8175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif
8185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (!seq) {
8205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        ALOGE("Attempted to send a finished signal with sequence number 0.");
8215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return BAD_VALUE;
8225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
8235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Send finished signals for the batch sequence chain first.
8255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t seqChainCount = mSeqChains.size();
8265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (seqChainCount) {
8275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t currentSeq = seq;
8285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t chainSeqs[seqChainCount];
8295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        size_t chainIndex = 0;
8301faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin        for (size_t i = seqChainCount; i > 0; ) {
8311faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin             i--;
8325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown             const SeqChain& seqChain = mSeqChains.itemAt(i);
8335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown             if (seqChain.seq == currentSeq) {
8345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                 currentSeq = seqChain.chain;
8355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                 chainSeqs[chainIndex++] = currentSeq;
8365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                 mSeqChains.removeAt(i);
8375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown             }
8385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
8395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        status_t status = OK;
8401faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin        while (!status && chainIndex > 0) {
8411faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin            chainIndex--;
8425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
8435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
8445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (status) {
8455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            // An error occurred so at least one signal was not sent, reconstruct the chain.
8465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            do {
8475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                SeqChain seqChain;
8485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
8495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                seqChain.chain = chainSeqs[chainIndex];
8505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                mSeqChains.push(seqChain);
8511faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin                if (chainIndex != 0) {
8521faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin                    chainIndex--;
8531faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin                }
8541faef80170b71ee4162dc910bfe1aea9d7181e58Dan Austin            } while (chainIndex > 0);
8555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return status;
8565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
8575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
8585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Send finished signal for the last message in the batch.
8605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return sendUnchainedFinishedSignal(seq, handled);
8615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownstatus_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
8645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    InputMessage msg;
8655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.header.type = InputMessage::TYPE_FINISHED;
8665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.finished.seq = seq;
8675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    msg.body.finished.handled = handled;
8685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return mChannel->sendMessage(&msg);
8695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool InputConsumer::hasDeferredEvent() const {
8725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return mMsgDeferred;
8735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool InputConsumer::hasPendingBatch() const {
8765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return !mBatches.isEmpty();
8775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
8805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < mBatches.size(); i++) {
8815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const Batch& batch = mBatches.itemAt(i);
8825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const InputMessage& head = batch.samples.itemAt(0);
8835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
8845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return i;
8855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
8865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
8875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return -1;
8885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
8905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
8915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < mTouchStates.size(); i++) {
8925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        const TouchState& touchState = mTouchStates.itemAt(i);
8935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (touchState.deviceId == deviceId && touchState.source == source) {
8945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return i;
8955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
8965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
8975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return -1;
8985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
8995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
9015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    event->initialize(
9025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.deviceId,
9035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.source,
9045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.action,
9055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.flags,
9065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.keyCode,
9075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.scanCode,
9085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.metaState,
9095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.repeatCount,
9105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.downTime,
9115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.key.eventTime);
9125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
9135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
915bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath    uint32_t pointerCount = msg->body.motion.pointerCount;
9165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    PointerProperties pointerProperties[pointerCount];
9175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    PointerCoords pointerCoords[pointerCount];
918bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath    for (uint32_t i = 0; i < pointerCount; i++) {
9195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
9205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
9215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
9225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    event->initialize(
9245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.deviceId,
9255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.source,
9265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.action,
9277b159c9a4f589da7fdab7c16f3aefea25e0e7e4fMichael Wright            msg->body.motion.actionButton,
9285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.flags,
9295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.edgeFlags,
9305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.metaState,
9315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.buttonState,
9325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.xOffset,
9335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.yOffset,
9345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.xPrecision,
9355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.yPrecision,
9365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.downTime,
9375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            msg->body.motion.eventTime,
9385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            pointerCount,
9395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            pointerProperties,
9405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            pointerCoords);
9415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
9425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownvoid InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
944bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath    uint32_t pointerCount = msg->body.motion.pointerCount;
9455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    PointerCoords pointerCoords[pointerCount];
946bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath    for (uint32_t i = 0; i < pointerCount; i++) {
9475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
9485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
9495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
9515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    event->addSample(msg->body.motion.eventTime, pointerCoords);
9525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
9535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownbool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
9555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const InputMessage& head = batch.samples.itemAt(0);
956bc6001b026069714177526eb1120b0011d6f2a51Narayan Kamath    uint32_t pointerCount = msg->body.motion.pointerCount;
9575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    if (head.body.motion.pointerCount != pointerCount
9585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            || head.body.motion.action != msg->body.motion.action) {
9595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        return false;
9605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
9615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
9625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        if (head.body.motion.pointers[i].properties
9635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                != msg->body.motion.pointers[i].properties) {
9645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return false;
9655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
9665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
9675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return true;
9685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
9695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
9715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t numSamples = batch.samples.size();
9725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    size_t index = 0;
9735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    while (index < numSamples
9745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            && batch.samples.itemAt(index).body.motion.eventTime <= time) {
9755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        index += 1;
9765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    }
9775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    return ssize_t(index) - 1;
9785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown}
9795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
9805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} // namespace android
981