summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-01-16 18:57:15 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-01-16 18:57:15 +0000
commita884591117246f2821faddc05f5e5c0d4c5cbdb6 (patch)
treebe8fcf9e5e79e023583b57cbc9cb09b444d04e23
parent0a91c46726431874f254b01645814485be1b8b18 (diff)
parent81973118791ebdfa5fd2be811e1bfdebfc9324ab (diff)
downloadnative-oreo-m8-release.tar.gz
Merge cherrypicks of [6072696, 6072074, 6072757, 6072120, 6072121, 6072122, 6072123, 6072575, 6072576, 6072577, 6072578, 6072579, 6072193, 6072131, 6072194, 6072076, 6072210, 6072759, 6072760, 6072698, 6072699, 6072700, 6072701, 6072702, 6072703, 6072704, 6072905, 6072906, 6072907, 6072761] into oc-m8-releaseandroid-8.1.0_r67android-8.1.0_r65android-8.1.0_r64android-8.1.0_r63android-8.1.0_r62oreo-m8-release
Change-Id: I62ea33011cde9be9d5ab9163d57b4be2c9b4e9a2
-rw-r--r--include/input/InputTransport.h13
-rw-r--r--libs/input/InputTransport.cpp106
-rw-r--r--libs/input/tests/StructLayout_test.cpp3
3 files changed, 120 insertions, 2 deletions
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index ea1d2aa41f..9f3d45a3bc 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;
@@ -72,6 +80,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 {
@@ -81,6 +90,7 @@ struct InputMessage {
struct Motion {
uint32_t seq;
+ uint32_t empty1;
nsecs_t eventTime __attribute__((aligned(8)));
int32_t deviceId;
int32_t source;
@@ -91,12 +101,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;
@@ -127,6 +139,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 3e8b67931a..1918379777 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 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 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