diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-03-15 23:16:03 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-03-15 23:16:03 +0000 |
commit | ba67302b13d41f9c4dd1b36c0cc6355b5d3902e1 (patch) | |
tree | b03abed3ed936e7b6aed66b6a608eeb781e7b582 | |
parent | 2c6b16a2621e0dea02728d152ec96259e087a689 (diff) | |
parent | dada6ad382f52da1b526fbeb6aebeae3cbb4197c (diff) | |
download | native-ba67302b13d41f9c4dd1b36c0cc6355b5d3902e1.tar.gz |
Merge cherrypicks of [6738238, 6739193, 6738335, 6738239, 6739470, 6739471, 6738201, 6738202, 6738203, 6738204, 6738205, 6738206, 6738207, 6738208, 6738209, 6739510, 6739511, 6739512, 6739513, 6739514, 6739515, 6739516, 6738336, 6739517, 6739518, 6738416, 6738417, 6739472, 6739473, 6739519, 6739520, 6739071, 6739072, 6738695, 6738696, 6738697, 6738698, 6738699, 6738243, 6739521, 6738244, 6738153, 6738154, 6738155, 6738156, 6738157, 6738158, 6738159, 6738160, 6739522, 6739523] into nyc-bugfix-releaseandroid-7.0.0_r36nougat-mr0.5-release
Change-Id: I7fc6a6e480ffdc7cc7f174db8947ad47d9a14a31
-rw-r--r-- | include/input/InputTransport.h | 11 | ||||
-rw-r--r-- | libs/input/InputTransport.cpp | 102 | ||||
-rw-r--r-- | libs/input/tests/StructLayout_test.cpp | 3 |
3 files changed, 114 insertions, 2 deletions
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index f31bceabd7..7d56bf5b46 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -42,6 +42,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 { @@ -62,6 +69,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; @@ -80,6 +88,7 @@ struct InputMessage { struct Motion { uint32_t seq; + uint32_t empty1; nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; @@ -95,6 +104,7 @@ struct InputMessage { float xPrecision; float yPrecision; uint32_t pointerCount; + uint32_t empty2; // Note that PointerCoords requires 8 byte alignment. struct Pointer { PointerProperties properties; @@ -125,6 +135,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 2dff4e0918..f6d2c15633 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -97,6 +97,102 @@ 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 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 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 --- @@ -150,10 +246,12 @@ status_t InputChannel::openInputChannelPair(const String8& 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 8d73f453e0..5172681e3b 100644 --- a/libs/input/tests/StructLayout_test.cpp +++ b/libs/input/tests/StructLayout_test.cpp @@ -63,6 +63,9 @@ void TestInputMessageAlignment() { CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 68); CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 72); CHECK_OFFSET(InputMessage::Body::Motion, pointers, 80); + + CHECK_OFFSET(InputMessage::Body::Finished, seq, 0); + CHECK_OFFSET(InputMessage::Body::Finished, handled, 4); } } // namespace android |