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