diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-01-16 18:58:15 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-01-16 18:58:15 +0000 |
commit | 3ce2b66f92ea8c50005b38595bb1aed4c80135ed (patch) | |
tree | bea8d2b9269680ee1742166e2820b9df075b7db5 | |
parent | cb5531e3576fec2be6e366f16dd85696a20552b3 (diff) | |
parent | 86c2985b0be7590aa979d25a7e5fb927cc1d2dcc (diff) | |
download | native-3ce2b66f92ea8c50005b38595bb1aed4c80135ed.tar.gz |
Merge cherrypicks of [6072697, 6072075, 6072758, 6072124, 6072885, 6072886, 6072887, 6072580, 6072581, 6072582, 6072583, 6072584, 6072132, 6072195, 6072133, 6072077, 6072134, 6072078, 6072211, 6072762, 6072763, 6072908, 6072909, 6072910, 6072911, 6072912, 6072913, 6072914, 6072930, 6072212, 6072743] into pi-qpr2-releaseandroid-9.0.0_r35android-9.0.0_r34pie-qpr2-release
Change-Id: I3c17079c9ff111716f48ff62f452de6e4af1fe4e
-rw-r--r-- | include/input/InputTransport.h | 13 | ||||
-rw-r--r-- | libs/input/InputTransport.cpp | 106 | ||||
-rw-r--r-- | libs/input/tests/StructLayout_test.cpp | 3 |
3 files changed, 120 insertions, 2 deletions
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index 1ea2c2cc07..ecdc075ac8 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -41,6 +41,13 @@ namespace android { * * Note that this structure is used for IPCs so its layout must be identical * on 64 and 32 bit processes. This is tested in StructLayout_test.cpp. + * + * Since the struct must be aligned to an 8-byte boundary, there could be uninitialized bytes + * in-between the defined fields. This padding data should be explicitly accounted for by adding + * "empty" fields into the struct. This data is memset to zero before sending the struct across + * the socket. Adding the explicit fields ensures that the memset is not optimized away by the + * compiler. When a new field is added to the struct, the corresponding change + * in StructLayout_test should be made. */ struct InputMessage { enum { @@ -61,6 +68,7 @@ struct InputMessage { union Body { struct Key { uint32_t seq; + uint32_t empty1; nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; @@ -71,6 +79,7 @@ struct InputMessage { int32_t scanCode; int32_t metaState; int32_t repeatCount; + uint32_t empty2; nsecs_t downTime __attribute__((aligned(8))); inline size_t size() const { @@ -80,6 +89,7 @@ struct InputMessage { struct Motion { uint32_t seq; + uint32_t empty1; nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; @@ -90,12 +100,14 @@ struct InputMessage { int32_t metaState; int32_t buttonState; int32_t edgeFlags; + uint32_t empty2; nsecs_t downTime __attribute__((aligned(8))); float xOffset; float yOffset; float xPrecision; float yPrecision; uint32_t pointerCount; + uint32_t empty3; // Note that PointerCoords requires 8 byte alignment. struct Pointer { PointerProperties properties; @@ -126,6 +138,7 @@ struct InputMessage { bool isValid(size_t actualSize) const; size_t size() const; + void getSanitizedCopy(InputMessage* msg) const; }; /* diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index aa0bf17ca3..03f593f8b2 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -96,6 +96,106 @@ size_t InputMessage::size() const { return sizeof(Header); } +/** + * There could be non-zero bytes in-between InputMessage fields. Force-initialize the entire + * memory to zero, then only copy the valid bytes on a per-field basis. + */ +void InputMessage::getSanitizedCopy(InputMessage* msg) const { + memset(msg, 0, sizeof(*msg)); + + // Write the header + msg->header.type = header.type; + + // Write the body + switch(header.type) { + case InputMessage::TYPE_KEY: { + // uint32_t seq + msg->body.key.seq = body.key.seq; + // nsecs_t eventTime + msg->body.key.eventTime = body.key.eventTime; + // int32_t deviceId + msg->body.key.deviceId = body.key.deviceId; + // int32_t source + msg->body.key.source = body.key.source; + // int32_t displayId + msg->body.key.displayId = body.key.displayId; + // int32_t action + msg->body.key.action = body.key.action; + // int32_t flags + msg->body.key.flags = body.key.flags; + // int32_t keyCode + msg->body.key.keyCode = body.key.keyCode; + // int32_t scanCode + msg->body.key.scanCode = body.key.scanCode; + // int32_t metaState + msg->body.key.metaState = body.key.metaState; + // int32_t repeatCount + msg->body.key.repeatCount = body.key.repeatCount; + // nsecs_t downTime + msg->body.key.downTime = body.key.downTime; + break; + } + case InputMessage::TYPE_MOTION: { + // uint32_t seq + msg->body.motion.seq = body.motion.seq; + // nsecs_t eventTime + msg->body.motion.eventTime = body.motion.eventTime; + // int32_t deviceId + msg->body.motion.deviceId = body.motion.deviceId; + // int32_t source + msg->body.motion.source = body.motion.source; + // int32_t displayId + msg->body.motion.displayId = body.motion.displayId; + // int32_t action + msg->body.motion.action = body.motion.action; + // int32_t actionButton + msg->body.motion.actionButton = body.motion.actionButton; + // int32_t flags + msg->body.motion.flags = body.motion.flags; + // int32_t metaState + msg->body.motion.metaState = body.motion.metaState; + // int32_t buttonState + msg->body.motion.buttonState = body.motion.buttonState; + // int32_t edgeFlags + msg->body.motion.edgeFlags = body.motion.edgeFlags; + // nsecs_t downTime + msg->body.motion.downTime = body.motion.downTime; + // float xOffset + msg->body.motion.xOffset = body.motion.xOffset; + // float yOffset + msg->body.motion.yOffset = body.motion.yOffset; + // float xPrecision + msg->body.motion.xPrecision = body.motion.xPrecision; + // float yPrecision + msg->body.motion.yPrecision = body.motion.yPrecision; + // uint32_t pointerCount + msg->body.motion.pointerCount = body.motion.pointerCount; + //struct Pointer pointers[MAX_POINTERS] + for (size_t i = 0; i < body.motion.pointerCount; i++) { + // PointerProperties properties + msg->body.motion.pointers[i].properties.id = body.motion.pointers[i].properties.id; + msg->body.motion.pointers[i].properties.toolType = + body.motion.pointers[i].properties.toolType, + // PointerCoords coords + msg->body.motion.pointers[i].coords.bits = body.motion.pointers[i].coords.bits; + const uint32_t count = BitSet64::count(body.motion.pointers[i].coords.bits); + memcpy(&msg->body.motion.pointers[i].coords.values[0], + &body.motion.pointers[i].coords.values[0], + count * (sizeof(body.motion.pointers[i].coords.values[0]))); + } + break; + } + case InputMessage::TYPE_FINISHED: { + msg->body.finished.seq = body.finished.seq; + msg->body.finished.handled = body.finished.handled; + break; + } + default: { + LOG_FATAL("Unexpected message type %i", header.type); + break; + } + } +} // --- InputChannel --- @@ -149,10 +249,12 @@ status_t InputChannel::openInputChannelPair(const std::string& name, } status_t InputChannel::sendMessage(const InputMessage* msg) { - size_t msgLength = msg->size(); + const size_t msgLength = msg->size(); + InputMessage cleanMsg; + msg->getSanitizedCopy(&cleanMsg); ssize_t nWrite; do { - nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); + nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); } while (nWrite == -1 && errno == EINTR); if (nWrite < 0) { diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp index d19f3b8066..12a67828ac 100644 --- a/libs/input/tests/StructLayout_test.cpp +++ b/libs/input/tests/StructLayout_test.cpp @@ -65,6 +65,9 @@ void TestInputMessageAlignment() { CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 76); CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 80); CHECK_OFFSET(InputMessage::Body::Motion, pointers, 88); + + CHECK_OFFSET(InputMessage::Body::Finished, seq, 0); + CHECK_OFFSET(InputMessage::Body::Finished, handled, 4); } } // namespace android |