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