146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//
246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Copyright 2010 The Android Open Source Project
346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//
446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Provides a shared memory transport for input events.
546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//
646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "InputTransport"
746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//#define LOG_NDEBUG 0
946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown// Log debug messages about channel messages (send message, receive message)
11cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#define DEBUG_CHANNEL_MESSAGES 0
1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages whenever InputChannel objects are created/destroyed
145c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown#define DEBUG_CHANNEL_LIFECYCLE 0
1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
16cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown// Log debug messages about transport actions
17072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#define DEBUG_TRANSPORT_ACTIONS 0
1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
19771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown// Log debug messages about touch event resampling
20771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#define DEBUG_RESAMPLING 0
21771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <cutils/log.h>
247174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown#include <cutils/properties.h>
2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <errno.h>
2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <fcntl.h>
27b93a03f841d93498bfea6cc92a22faa34bce1337Mathias Agopian#include <androidfw/InputTransport.h>
2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <unistd.h>
29cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#include <sys/types.h>
30cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#include <sys/socket.h>
31771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#include <math.h>
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
34cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brownnamespace android {
3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
36d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown// Socket buffer size.  The default is typically about 128KB, which is much larger than
37d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown// we really need.  So we make it smaller.  It just needs to be big enough to hold
38d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown// a few dozen large multi-finger motion events in the case where an application gets
39d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown// behind processing touches.
40d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brownstatic const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
41d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown
42771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown// Nanoseconds per milliseconds.
43771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownstatic const nsecs_t NANOS_PER_MS = 1000000;
44771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
45771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown// Latency added during resampling.  A few milliseconds doesn't hurt much but
46771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown// reduces the impact of mispredicted touch positions.
477174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brownstatic const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS;
48771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
49771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown// Minimum time difference between consecutive samples before attempting to resample.
507174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brownstatic const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS;
51771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
527174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown// Maximum time to predict forward from the last known state, to avoid predicting too
537174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown// far into the future.  This time is further bounded by 50% of the last time delta.
547174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brownstatic const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS;
55771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
567174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Browntemplate<typename T>
577174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Browninline static T min(const T& a, const T& b) {
587174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    return a < b ? a : b;
597174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown}
607174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
617174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Browninline static float lerp(float a, float b, float alpha) {
627174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    return a + alpha * (b - a);
637174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown}
64d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown
65cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown// --- InputMessage ---
66cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
67cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brownbool InputMessage::isValid(size_t actualSize) const {
68cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    if (size() == actualSize) {
69cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        switch (header.type) {
70cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        case TYPE_KEY:
71cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return true;
72cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        case TYPE_MOTION:
73cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return body.motion.pointerCount > 0
74cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown                    && body.motion.pointerCount <= MAX_POINTERS;
75cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        case TYPE_FINISHED:
76cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return true;
77cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        }
78cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
79cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return false;
80cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown}
813915bb845b032dc184dba5e60970b803390ca3edJeff Brown
82cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brownsize_t InputMessage::size() const {
83cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    switch (header.type) {
84cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    case TYPE_KEY:
85cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return sizeof(Header) + body.key.size();
86cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    case TYPE_MOTION:
87cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return sizeof(Header) + body.motion.size();
88cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    case TYPE_FINISHED:
89cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return sizeof(Header) + body.finished.size();
90cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
91cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return sizeof(Header);
92cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown}
9346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
9546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputChannel ---
9646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
97cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff BrownInputChannel::InputChannel(const String8& name, int fd) :
98cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        mName(name), mFd(fd) {
9946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_CHANNEL_LIFECYCLE
100cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    ALOGD("Input channel constructed: name='%s', fd=%d",
101cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            mName.string(), fd);
10246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
104cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    int result = fcntl(mFd, F_SETFL, O_NONBLOCK);
105cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make socket "
10646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "non-blocking.  errno=%d", mName.string(), errno);
10746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
10846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
10946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputChannel::~InputChannel() {
11046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_CHANNEL_LIFECYCLE
111cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    ALOGD("Input channel destroyed: name='%s', fd=%d",
112cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            mName.string(), mFd);
11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
115cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    ::close(mFd);
11646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
11746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
11846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatus_t InputChannel::openInputChannelPair(const String8& name,
1195c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
120cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    int sockets[2];
121cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
122cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        status_t result = -errno;
123cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        ALOGE("channel '%s' ~ Could not create socket pair.  errno=%d",
12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                name.string(), errno);
125cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        outServerChannel.clear();
126cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        outClientChannel.clear();
127cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return result;
12846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
130d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown    int bufferSize = SOCKET_BUFFER_SIZE;
131d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown    setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
132d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown    setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
133d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown    setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize));
134d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown    setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize));
135d1c48a0525d05021036d4b14e937e221c0ae1318Jeff Brown
136cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    String8 serverChannelName = name;
137cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    serverChannelName.append(" (server)");
138cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    outServerChannel = new InputChannel(serverChannelName, sockets[0]);
139cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
140cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    String8 clientChannelName = name;
141cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    clientChannelName.append(" (client)");
142cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    outClientChannel = new InputChannel(clientChannelName, sockets[1]);
143cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return OK;
14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
146cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brownstatus_t InputChannel::sendMessage(const InputMessage* msg) {
147cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    size_t msgLength = msg->size();
1487dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown    ssize_t nWrite;
1497dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown    do {
150cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
1517dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown    } while (nWrite == -1 && errno == EINTR);
15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
153cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    if (nWrite < 0) {
154cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        int error = errno;
155cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#if DEBUG_CHANNEL_MESSAGES
156cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        ALOGD("channel '%s' ~ error sending message of type %d, errno=%d", mName.string(),
157cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown                msg->header.type, error);
15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
159cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        if (error == EAGAIN || error == EWOULDBLOCK) {
160cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return WOULD_BLOCK;
161cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        }
162cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        if (error == EPIPE || error == ENOTCONN) {
163cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return DEAD_OBJECT;
164cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        }
165cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return -error;
16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
168cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    if (size_t(nWrite) != msgLength) {
169cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#if DEBUG_CHANNEL_MESSAGES
170cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        ALOGD("channel '%s' ~ error sending message type %d, send was incomplete",
171cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown                mName.string(), msg->header.type);
17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
173cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return DEAD_OBJECT;
174cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    }
175cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown
176cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#if DEBUG_CHANNEL_MESSAGES
177cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    ALOGD("channel '%s' ~ sent message of type %d", mName.string(), msg->header.type);
178cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#endif
179cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return OK;
18046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
18146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
182cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brownstatus_t InputChannel::receiveMessage(InputMessage* msg) {
1837dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown    ssize_t nRead;
1847dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown    do {
185cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);
1867dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown    } while (nRead == -1 && errno == EINTR);
1877dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown
188cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    if (nRead < 0) {
189cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        int error = errno;
190cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#if DEBUG_CHANNEL_MESSAGES
191cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        ALOGD("channel '%s' ~ receive message failed, errno=%d", mName.string(), errno);
19246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
193cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        if (error == EAGAIN || error == EWOULDBLOCK) {
194cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return WOULD_BLOCK;
195cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        }
196cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        if (error == EPIPE || error == ENOTCONN) {
197cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown            return DEAD_OBJECT;
198cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        }
199cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return -error;
20046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
20146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2025c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    if (nRead == 0) { // check for EOF
203cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#if DEBUG_CHANNEL_MESSAGES
204cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        ALOGD("channel '%s' ~ receive message failed because peer was closed", mName.string());
2055c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown#endif
2065c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown        return DEAD_OBJECT;
2075c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    }
2085c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown
209cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    if (!msg->isValid(nRead)) {
210cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#if DEBUG_CHANNEL_MESSAGES
211cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        ALOGD("channel '%s' ~ received invalid message", mName.string());
21246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
213cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        return BAD_VALUE;
21446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
21546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
216cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown#if DEBUG_CHANNEL_MESSAGES
217cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    ALOGD("channel '%s' ~ received message of type %d", mName.string(), msg->header.type);
21846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
219cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return OK;
22046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
22146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputPublisher ---
22446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputPublisher::InputPublisher(const sp<InputChannel>& channel) :
226cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        mChannel(channel) {
22746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
22846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputPublisher::~InputPublisher() {
23046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
23146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatus_t InputPublisher::publishKeyEvent(
233072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        uint32_t seq,
23446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t deviceId,
235c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        int32_t source,
23646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t action,
23746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t flags,
23846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t keyCode,
23946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t scanCode,
24046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t metaState,
24146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t repeatCount,
24246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t downTime,
24346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t eventTime) {
24446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_TRANSPORT_ACTIONS
245072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    ALOGD("channel '%s' publisher ~ publishKeyEvent: seq=%u, deviceId=%d, source=0x%x, "
24685a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
24746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "downTime=%lld, eventTime=%lld",
248072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            mChannel->getName().string(), seq,
249c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
25046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            downTime, eventTime);
25146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
25246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
253072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    if (!seq) {
254072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        ALOGE("Attempted to publish a key event with sequence number 0.");
255072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        return BAD_VALUE;
256072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
257072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
258cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    InputMessage msg;
259cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.header.type = InputMessage::TYPE_KEY;
260072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    msg.body.key.seq = seq;
261cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.deviceId = deviceId;
262cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.source = source;
263cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.action = action;
264cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.flags = flags;
265cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.keyCode = keyCode;
266cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.scanCode = scanCode;
267cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.metaState = metaState;
268cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.repeatCount = repeatCount;
269cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.downTime = downTime;
270cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.key.eventTime = eventTime;
271cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return mChannel->sendMessage(&msg);
27246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
27346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
27446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatus_t InputPublisher::publishMotionEvent(
275072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        uint32_t seq,
27646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t deviceId,
277c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        int32_t source,
27846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t action,
27985a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown        int32_t flags,
28046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t edgeFlags,
28146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        int32_t metaState,
282fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        int32_t buttonState,
28346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        float xOffset,
28446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        float yOffset,
28546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        float xPrecision,
28646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        float yPrecision,
28746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t downTime,
28846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        nsecs_t eventTime,
28946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        size_t pointerCount,
290fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties* pointerProperties,
29146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        const PointerCoords* pointerCoords) {
29246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_TRANSPORT_ACTIONS
293072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    ALOGD("channel '%s' publisher ~ publishMotionEvent: seq=%u, deviceId=%d, source=0x%x, "
294fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
295fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "xOffset=%f, yOffset=%f, "
29646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
29746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "pointerCount=%d",
298072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            mChannel->getName().string(), seq,
299fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            deviceId, source, action, flags, edgeFlags, metaState, buttonState,
300fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
30146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
30246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
303072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    if (!seq) {
304072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        ALOGE("Attempted to publish a motion event with sequence number 0.");
305072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        return BAD_VALUE;
306072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
307072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
30846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
3093762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
31046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                mChannel->getName().string(), pointerCount);
31146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return BAD_VALUE;
31246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
31346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
314cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    InputMessage msg;
315cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.header.type = InputMessage::TYPE_MOTION;
316072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    msg.body.motion.seq = seq;
317cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.deviceId = deviceId;
318cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.source = source;
319cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.action = action;
320cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.flags = flags;
321cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.edgeFlags = edgeFlags;
322cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.metaState = metaState;
323cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.buttonState = buttonState;
324cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.xOffset = xOffset;
325cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.yOffset = yOffset;
326cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.xPrecision = xPrecision;
327cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.yPrecision = yPrecision;
328cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.downTime = downTime;
329cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.eventTime = eventTime;
330cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.motion.pointerCount = pointerCount;
33146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
332cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
333cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
33446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
335cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return mChannel->sendMessage(&msg);
33646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
33746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
338072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownstatus_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {
33946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_TRANSPORT_ACTIONS
3405baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("channel '%s' publisher ~ receiveFinishedSignal",
34146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            mChannel->getName().string());
34246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
34346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
344cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    InputMessage msg;
345cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    status_t result = mChannel->receiveMessage(&msg);
34646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (result) {
347072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        *outSeq = 0;
34849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        *outHandled = false;
34946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return result;
35046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
351cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    if (msg.header.type != InputMessage::TYPE_FINISHED) {
352cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        ALOGE("channel '%s' publisher ~ Received unexpected message of type %d from consumer",
353cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown                mChannel->getName().string(), msg.header.type);
35446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return UNKNOWN_ERROR;
35546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
356072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    *outSeq = msg.body.finished.seq;
357cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    *outHandled = msg.body.finished.handled;
35846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return OK;
35946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
36046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
36146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputConsumer ---
36246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
36346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputConsumer::InputConsumer(const sp<InputChannel>& channel) :
3647174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        mResampleTouch(isTouchResamplingEnabled()),
36590fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown        mChannel(channel), mMsgDeferred(false) {
36646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
36746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
36846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputConsumer::~InputConsumer() {
36946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
37046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3717174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brownbool InputConsumer::isTouchResamplingEnabled() {
3727174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    char value[PROPERTY_VALUE_MAX];
3737174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    int length = property_get("debug.inputconsumer.resample", value, NULL);
3747174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    if (length > 0) {
3757174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (!strcmp("0", value)) {
3767174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            return false;
3777174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
3787174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (strcmp("1", value)) {
3797174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            ALOGD("Unrecognized property value for 'debug.inputconsumer.resample'.  "
3807174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    "Use '1' or '0'.");
3817174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
3827174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    }
3837174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    return true;
3847174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown}
3857174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
386072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownstatus_t InputConsumer::consume(InputEventFactoryInterface* factory,
387771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
38846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_TRANSPORT_ACTIONS
389771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    ALOGD("channel '%s' consumer ~ consume: consumeBatches=%s, frameTime=%lld",
390771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            mChannel->getName().string(), consumeBatches ? "true" : "false", frameTime);
39146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
39246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
393072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    *outSeq = 0;
3945c225b1680e696ae8bbf505a1997d6f720672f74Jeff Brown    *outEvent = NULL;
39546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
396072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    // Fetch the next input message.
397072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    // Loop until an event can be returned or no additional events are received.
398072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    while (!*outEvent) {
39990fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown        if (mMsgDeferred) {
40090fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            // mMsg contains a valid input message from the previous call to consume
40190fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            // that has not yet been processed.
40290fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            mMsgDeferred = false;
40390fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown        } else {
40490fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            // Receive a fresh message.
40590fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            status_t result = mChannel->receiveMessage(&mMsg);
40690fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            if (result) {
40790fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown                // Consume the next batched event unless batches are being held for later.
408771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                if (consumeBatches || result != WOULD_BLOCK) {
409771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    result = consumeBatch(factory, frameTime, outSeq, outEvent);
410771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    if (*outEvent) {
411072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_TRANSPORT_ACTIONS
412771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                        ALOGD("channel '%s' consumer ~ consumed batch event, seq=%u",
413771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                                mChannel->getName().string(), *outSeq);
414072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif
415771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                        break;
416771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    }
41790fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown                }
41890fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown                return result;
419072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            }
420072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        }
42146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
42290fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown        switch (mMsg.header.type) {
423072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        case InputMessage::TYPE_KEY: {
424072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            KeyEvent* keyEvent = factory->createKeyEvent();
425072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            if (!keyEvent) return NO_MEMORY;
426072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
42790fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            initializeKeyEvent(keyEvent, &mMsg);
42890fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            *outSeq = mMsg.body.key.seq;
429072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            *outEvent = keyEvent;
430072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_TRANSPORT_ACTIONS
431072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            ALOGD("channel '%s' consumer ~ consumed key event, seq=%u",
432072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    mChannel->getName().string(), *outSeq);
433072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif
434072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            break;
435cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown        }
43646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
437072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        case AINPUT_EVENT_TYPE_MOTION: {
43890fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            ssize_t batchIndex = findBatch(mMsg.body.motion.deviceId, mMsg.body.motion.source);
439072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            if (batchIndex >= 0) {
440072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                Batch& batch = mBatches.editItemAt(batchIndex);
441771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                if (canAddSample(batch, &mMsg)) {
442771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    batch.samples.push(mMsg);
443072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_TRANSPORT_ACTIONS
444072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    ALOGD("channel '%s' consumer ~ appended to batch event",
445072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                            mChannel->getName().string());
446072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif
447072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    break;
448072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                } else {
449072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    // We cannot append to the batch in progress, so we need to consume
45090fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown                    // the previous batch right now and defer the new message until later.
45190fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown                    mMsgDeferred = true;
452771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    status_t result = consumeSamples(factory,
453771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                            batch, batch.samples.size(), outSeq, outEvent);
454072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    mBatches.removeAt(batchIndex);
455771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    if (result) {
456771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                        return result;
457771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    }
458072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_TRANSPORT_ACTIONS
459072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    ALOGD("channel '%s' consumer ~ consumed batch event and "
460072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                            "deferred current event, seq=%u",
461072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                            mChannel->getName().string(), *outSeq);
462072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif
463072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    break;
464072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                }
465072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            }
466072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
467072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            // Start a new batch if needed.
46890fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            if (mMsg.body.motion.action == AMOTION_EVENT_ACTION_MOVE
46990fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown                    || mMsg.body.motion.action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
470072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                mBatches.push();
471072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                Batch& batch = mBatches.editTop();
472771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                batch.samples.push(mMsg);
473072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_TRANSPORT_ACTIONS
474072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                ALOGD("channel '%s' consumer ~ started batch event",
475072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                        mChannel->getName().string());
476072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif
477072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                break;
478072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            }
47946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
480072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            MotionEvent* motionEvent = factory->createMotionEvent();
481072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            if (! motionEvent) return NO_MEMORY;
48246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
483771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            updateTouchState(&mMsg);
48490fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            initializeMotionEvent(motionEvent, &mMsg);
48590fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown            *outSeq = mMsg.body.motion.seq;
486072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            *outEvent = motionEvent;
487072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_TRANSPORT_ACTIONS
488072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            ALOGD("channel '%s' consumer ~ consumed motion event, seq=%u",
489072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown                    mChannel->getName().string(), *outSeq);
490072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif
491072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            break;
492072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        }
493072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
494072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        default:
495072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            ALOGE("channel '%s' consumer ~ Received unexpected message of type %d",
49690fde93c473aca5a33dc41c989bb2fdc5f2b1485Jeff Brown                    mChannel->getName().string(), mMsg.header.type);
497072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            return UNKNOWN_ERROR;
498072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        }
499072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
50046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return OK;
50146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
50246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
503771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownstatus_t InputConsumer::consumeBatch(InputEventFactoryInterface* factory,
504771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
505771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    status_t result;
506771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    for (size_t i = mBatches.size(); i-- > 0; ) {
507771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        Batch& batch = mBatches.editItemAt(i);
508771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (frameTime < 0) {
509771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            result = consumeSamples(factory, batch, batch.samples.size(),
510771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    outSeq, outEvent);
511771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            mBatches.removeAt(i);
512771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            return result;
513771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
514771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
515771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY;
516771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        ssize_t split = findSampleNoLaterThan(batch, sampleTime);
517771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (split < 0) {
518771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            continue;
519771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
520771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
521771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        result = consumeSamples(factory, batch, split + 1, outSeq, outEvent);
522771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        const InputMessage* next;
523771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (batch.samples.isEmpty()) {
524771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            mBatches.removeAt(i);
525771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            next = NULL;
526771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        } else {
527771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            next = &batch.samples.itemAt(0);
528771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
529771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (!result) {
530771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
531771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
532771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return result;
533771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
534771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
535771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    return WOULD_BLOCK;
536771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown}
537771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
538771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownstatus_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
539771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent) {
540771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    MotionEvent* motionEvent = factory->createMotionEvent();
541771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    if (! motionEvent) return NO_MEMORY;
542771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
543771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    uint32_t chain = 0;
544771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    for (size_t i = 0; i < count; i++) {
545771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        InputMessage& msg = batch.samples.editItemAt(i);
546771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        updateTouchState(&msg);
547771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (i) {
548771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            SeqChain seqChain;
549771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            seqChain.seq = msg.body.motion.seq;
550771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            seqChain.chain = chain;
551771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            mSeqChains.push(seqChain);
552771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            addSample(motionEvent, &msg);
553771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        } else {
554771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            initializeMotionEvent(motionEvent, &msg);
555771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
556771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        chain = msg.body.motion.seq;
557771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
558771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    batch.samples.removeItemsAt(0, count);
559771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
560771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    *outSeq = chain;
561771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    *outEvent = motionEvent;
562771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    return OK;
563771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown}
564771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
565771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownvoid InputConsumer::updateTouchState(InputMessage* msg) {
5667174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    if (!mResampleTouch ||
5677174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
568771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return;
569771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
570771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
571771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    int32_t deviceId = msg->body.motion.deviceId;
572771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    int32_t source = msg->body.motion.source;
5737174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    nsecs_t eventTime = msg->body.motion.eventTime;
574771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
5757174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    // Update the touch state history to incorporate the new input message.
5767174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    // If the message is in the past relative to the most recently produced resampled
5777174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    // touch, then use the resampled time and coordinates instead.
5787174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) {
579771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    case AMOTION_EVENT_ACTION_DOWN: {
580771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        ssize_t index = findTouchState(deviceId, source);
581771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (index < 0) {
582771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            mTouchStates.push();
583771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            index = mTouchStates.size() - 1;
584771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
585771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        TouchState& touchState = mTouchStates.editItemAt(index);
586771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        touchState.initialize(deviceId, source);
587771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        touchState.addHistory(msg);
588771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        break;
589771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
590771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
591771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    case AMOTION_EVENT_ACTION_MOVE: {
592771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        ssize_t index = findTouchState(deviceId, source);
593771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (index >= 0) {
594771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            TouchState& touchState = mTouchStates.editItemAt(index);
595771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            touchState.addHistory(msg);
5967174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            if (eventTime < touchState.lastResample.eventTime) {
5977174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                rewriteMessage(touchState, msg);
5987174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            } else {
5997174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                touchState.lastResample.idBits.clear();
6007174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            }
6017174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
6027174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        break;
6037174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    }
6047174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
6057174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
6067174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        ssize_t index = findTouchState(deviceId, source);
6077174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (index >= 0) {
6087174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            TouchState& touchState = mTouchStates.editItemAt(index);
6097174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
6107174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            rewriteMessage(touchState, msg);
6117174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
6127174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        break;
6137174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    }
6147174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
6157174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    case AMOTION_EVENT_ACTION_POINTER_UP: {
6167174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        ssize_t index = findTouchState(deviceId, source);
6177174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (index >= 0) {
6187174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            TouchState& touchState = mTouchStates.editItemAt(index);
6197174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            rewriteMessage(touchState, msg);
6207174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
6217174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
6227174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        break;
6237174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    }
6247174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
6257174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    case AMOTION_EVENT_ACTION_SCROLL: {
6267174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        ssize_t index = findTouchState(deviceId, source);
6277174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (index >= 0) {
6287174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            const TouchState& touchState = mTouchStates.itemAt(index);
6297174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            rewriteMessage(touchState, msg);
630771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
631771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        break;
632771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
633771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
634771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    case AMOTION_EVENT_ACTION_UP:
635771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    case AMOTION_EVENT_ACTION_CANCEL: {
636771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        ssize_t index = findTouchState(deviceId, source);
637771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (index >= 0) {
6387174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            const TouchState& touchState = mTouchStates.itemAt(index);
6397174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            rewriteMessage(touchState, msg);
640771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            mTouchStates.removeAt(index);
641771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
642771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        break;
643771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
644771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
645771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown}
646771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
6477174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brownvoid InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
6487174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    for (size_t i = 0; i < msg->body.motion.pointerCount; i++) {
6497174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        uint32_t id = msg->body.motion.pointers[i].properties.id;
6507174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (state.lastResample.idBits.hasBit(id)) {
6517174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
6527174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
653771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
6547174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
6557174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
6567174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y),
6577174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
6587174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
659771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
6607174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
6617174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
6627174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
6637174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    }
6647174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown}
6657174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
6667174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brownvoid InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
6677174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    const InputMessage* next) {
6687174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    if (!mResampleTouch
6697174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            || !(event->getSource() & AINPUT_SOURCE_CLASS_POINTER)
6707174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            || event->getAction() != AMOTION_EVENT_ACTION_MOVE) {
671771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return;
672771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
673771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
674771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    ssize_t index = findTouchState(event->getDeviceId(), event->getSource());
675771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    if (index < 0) {
676771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
677771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        ALOGD("Not resampled, no touch state for device.");
678771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
679771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return;
680771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
681771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
682771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    TouchState& touchState = mTouchStates.editItemAt(index);
683771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    if (touchState.historySize < 1) {
684771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
685771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        ALOGD("Not resampled, no history for device.");
686771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
687771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return;
688771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
689771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
6907174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    // Ensure that the current sample has all of the pointers that need to be reported.
691771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    const History* current = touchState.getHistory(0);
6927174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    size_t pointerCount = event->getPointerCount();
6937174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
6947174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        uint32_t id = event->getPointerId(i);
6957174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (!current->idBits.hasBit(id)) {
6967174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown#if DEBUG_RESAMPLING
6977174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            ALOGD("Not resampled, missing id %d", id);
6987174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown#endif
6997174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            return;
7007174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
7017174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    }
7027174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown
7037174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    // Find the data to use for resampling.
704771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    const History* other;
705771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    History future;
7067174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    float alpha;
707771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    if (next) {
7087174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        // Interpolate between current sample and future sample.
7097174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        // So current->eventTime <= sampleTime <= future.eventTime.
710771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        future.initializeFrom(next);
711771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        other = &future;
7127174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        nsecs_t delta = future.eventTime - current->eventTime;
7137174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (delta < RESAMPLE_MIN_DELTA) {
7147174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown#if DEBUG_RESAMPLING
7157174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            ALOGD("Not resampled, delta time is %lld ns.", delta);
7167174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown#endif
7177174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            return;
7187174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
7197174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        alpha = float(sampleTime - current->eventTime) / delta;
720771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    } else if (touchState.historySize >= 2) {
7217174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        // Extrapolate future sample using current sample and past sample.
7227174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        // So other->eventTime <= current->eventTime <= sampleTime.
723771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        other = touchState.getHistory(1);
7247174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        nsecs_t delta = current->eventTime - other->eventTime;
7257174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (delta < RESAMPLE_MIN_DELTA) {
726771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
7277174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            ALOGD("Not resampled, delta time is %lld ns.", delta);
728771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
7297174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            return;
7307174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
7317174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        nsecs_t maxPredict = current->eventTime + min(delta / 2, RESAMPLE_MAX_PREDICTION);
7327174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        if (sampleTime > maxPredict) {
733771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
7347174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            ALOGD("Sample time is too far in the future, adjusting prediction "
7357174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    "from %lld to %lld ns.",
7367174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    sampleTime - current->eventTime, maxPredict - current->eventTime);
737771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
7387174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            sampleTime = maxPredict;
7397174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        }
7407174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        alpha = float(current->eventTime - sampleTime) / delta;
7417174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    } else {
742771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
7437174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        ALOGD("Not resampled, insufficient data.");
744771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
745771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        return;
746771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
747771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
7487174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    // Resample touch coordinates.
7497174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    touchState.lastResample.eventTime = sampleTime;
7507174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    touchState.lastResample.idBits.clear();
751771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
752771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        uint32_t id = event->getPointerId(i);
7537174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        touchState.lastResample.idToIndex[id] = i;
7547174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        touchState.lastResample.idBits.markBit(id);
7557174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        PointerCoords& resampledCoords = touchState.lastResample.pointers[i];
7567174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown        const PointerCoords& currentCoords = current->getPointerById(id);
757771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (other->idBits.hasBit(id)
758771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                && shouldResampleTool(event->getToolType(i))) {
7597174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            const PointerCoords& otherCoords = other->getPointerById(id);
7607174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            resampledCoords.copyFrom(currentCoords);
7617174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_X,
7627174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    lerp(currentCoords.getX(), otherCoords.getX(), alpha));
7637174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            resampledCoords.setAxisValue(AMOTION_EVENT_AXIS_Y,
7647174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    lerp(currentCoords.getY(), otherCoords.getY(), alpha));
765771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
766771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f), "
767771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    "other (%0.3f, %0.3f), alpha %0.3f",
7687174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    id, resampledCoords.getX(), resampledCoords.getY(),
769771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    currentCoords.getX(), currentCoords.getY(),
770771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    otherCoords.getX(), otherCoords.getY(),
771771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    alpha);
772771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
773771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        } else {
7747174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown            resampledCoords.copyFrom(currentCoords);
775771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#if DEBUG_RESAMPLING
776771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            ALOGD("[%d] - out (%0.3f, %0.3f), cur (%0.3f, %0.3f)",
7777174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown                    id, resampledCoords.getX(), resampledCoords.getY(),
778771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                    currentCoords.getX(), currentCoords.getY());
779771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown#endif
780771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
781771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
782771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
7837174a491bc1f89da65eaef3be25f3ea3f3e3bab5Jeff Brown    event->addSample(sampleTime, touchState.lastResample.pointers);
784771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown}
785771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
786771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownbool InputConsumer::shouldResampleTool(int32_t toolType) {
787771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    return toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
788771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            || toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
789771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown}
790771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
791072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownstatus_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
79246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_TRANSPORT_ACTIONS
793072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    ALOGD("channel '%s' consumer ~ sendFinishedSignal: seq=%u, handled=%s",
794072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            mChannel->getName().string(), seq, handled ? "true" : "false");
79546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
79646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
797072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    if (!seq) {
798072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        ALOGE("Attempted to send a finished signal with sequence number 0.");
799072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        return BAD_VALUE;
800072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
801072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
8022d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    // Send finished signals for the batch sequence chain first.
8032d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    size_t seqChainCount = mSeqChains.size();
8042d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    if (seqChainCount) {
8052d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        uint32_t currentSeq = seq;
8062d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        uint32_t chainSeqs[seqChainCount];
8072d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        size_t chainIndex = 0;
8082d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        for (size_t i = seqChainCount; i-- > 0; ) {
8092d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown             const SeqChain& seqChain = mSeqChains.itemAt(i);
8102d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown             if (seqChain.seq == currentSeq) {
8112d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown                 currentSeq = seqChain.chain;
8122d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown                 chainSeqs[chainIndex++] = currentSeq;
8132d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown                 mSeqChains.removeAt(i);
8142d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown             }
8152d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        }
8162d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        status_t status = OK;
8172d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        while (!status && chainIndex-- > 0) {
8182d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown            status = sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);
8192d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        }
8202d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        if (status) {
8212d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown            // An error occurred so at least one signal was not sent, reconstruct the chain.
8222d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown            do {
8232d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown                SeqChain seqChain;
8242d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown                seqChain.seq = chainIndex != 0 ? chainSeqs[chainIndex - 1] : seq;
8252d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown                seqChain.chain = chainSeqs[chainIndex];
8262d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown                mSeqChains.push(seqChain);
8272d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown            } while (chainIndex-- > 0);
8282d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown            return status;
8292d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown        }
8302d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    }
8312d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown
8322d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    // Send finished signal for the last message in the batch.
8332d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown    return sendUnchainedFinishedSignal(seq, handled);
8342d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown}
8352d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brown
8362d34e0cfe7e2586b75a6f2c6646dd2e1e52c973fJeff Brownstatus_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {
837cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    InputMessage msg;
838cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.header.type = InputMessage::TYPE_FINISHED;
839072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    msg.body.finished.seq = seq;
840cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    msg.body.finished.handled = handled;
841cbee6d6ede0499fb4a2c00bfc00d5db8d9ed5139Jeff Brown    return mChannel->sendMessage(&msg);
84246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
84346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
8442b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brownbool InputConsumer::hasDeferredEvent() const {
8452b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown    return mMsgDeferred;
8462b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown}
8472b6c32ca4177f1a97307f9cbd81ca485df28762cJeff Brown
848072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownbool InputConsumer::hasPendingBatch() const {
849072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    return !mBatches.isEmpty();
850072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown}
851072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
852072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
853072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    for (size_t i = 0; i < mBatches.size(); i++) {
854072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        const Batch& batch = mBatches.itemAt(i);
855771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        const InputMessage& head = batch.samples.itemAt(0);
856771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (head.body.motion.deviceId == deviceId && head.body.motion.source == source) {
857771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            return i;
858771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        }
859771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
860771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    return -1;
861771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown}
862771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
863771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownssize_t InputConsumer::findTouchState(int32_t deviceId, int32_t source) const {
864771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    for (size_t i = 0; i < mTouchStates.size(); i++) {
865771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        const TouchState& touchState = mTouchStates.itemAt(i);
866771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (touchState.deviceId == deviceId && touchState.source == source) {
867072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            return i;
868072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        }
869072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
870072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    return -1;
871072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown}
872072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
873072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownvoid InputConsumer::initializeKeyEvent(KeyEvent* event, const InputMessage* msg) {
874072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    event->initialize(
875072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.deviceId,
876072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.source,
877072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.action,
878072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.flags,
879072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.keyCode,
880072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.scanCode,
881072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.metaState,
882072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.repeatCount,
883072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.downTime,
884072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.key.eventTime);
885072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown}
886072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
887072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownvoid InputConsumer::initializeMotionEvent(MotionEvent* event, const InputMessage* msg) {
888072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    size_t pointerCount = msg->body.motion.pointerCount;
889072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    PointerProperties pointerProperties[pointerCount];
890072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    PointerCoords pointerCoords[pointerCount];
891072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
892072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        pointerProperties[i].copyFrom(msg->body.motion.pointers[i].properties);
893072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
894072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
895072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
896072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    event->initialize(
897072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.deviceId,
898072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.source,
899072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.action,
900072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.flags,
901072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.edgeFlags,
902072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.metaState,
903072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.buttonState,
904072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.xOffset,
905072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.yOffset,
906072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.xPrecision,
907072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.yPrecision,
908072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.downTime,
909072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            msg->body.motion.eventTime,
910072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            pointerCount,
911072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            pointerProperties,
912072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            pointerCoords);
913072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown}
914072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
915771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownvoid InputConsumer::addSample(MotionEvent* event, const InputMessage* msg) {
916771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    size_t pointerCount = msg->body.motion.pointerCount;
917771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    PointerCoords pointerCoords[pointerCount];
918771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    for (size_t i = 0; i < pointerCount; i++) {
919771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        pointerCoords[i].copyFrom(msg->body.motion.pointers[i].coords);
920771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    }
921771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
922771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    event->setMetaState(event->getMetaState() | msg->body.motion.metaState);
923771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    event->addSample(msg->body.motion.eventTime, pointerCoords);
924771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown}
925771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown
926771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownbool InputConsumer::canAddSample(const Batch& batch, const InputMessage *msg) {
927771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    const InputMessage& head = batch.samples.itemAt(0);
928072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    size_t pointerCount = msg->body.motion.pointerCount;
929771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    if (head.body.motion.pointerCount != pointerCount
930771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            || head.body.motion.action != msg->body.motion.action) {
931072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        return false;
932072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
933072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
934771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        if (head.body.motion.pointers[i].properties
935771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown                != msg->body.motion.pointers[i].properties) {
936072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown            return false;
937072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown        }
938072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
939072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    return true;
940072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown}
941072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
942771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownssize_t InputConsumer::findSampleNoLaterThan(const Batch& batch, nsecs_t time) {
943771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    size_t numSamples = batch.samples.size();
944771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    size_t index = 0;
945771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    while (index < numSamples
946771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown            && batch.samples.itemAt(index).body.motion.eventTime <= time) {
947771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown        index += 1;
948072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown    }
949771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown    return ssize_t(index) - 1;
950072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown}
951072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown
95246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
953