frameworks/native
Revisión | 9d54afa38b1dc93937513ef429b7fe639c2880e2 (tree) |
---|---|
Tiempo | 2019-05-20 18:26:31 |
Autor | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
Merge tag 'android-8.1.0_r64' into oreo-x86
Android 8.1.0 Release 64 (OPM8.190505.001)
@@ -42,6 +42,13 @@ namespace android { | ||
42 | 42 | * |
43 | 43 | * Note that this structure is used for IPCs so its layout must be identical |
44 | 44 | * on 64 and 32 bit processes. This is tested in StructLayout_test.cpp. |
45 | + * | |
46 | + * Since the struct must be aligned to an 8-byte boundary, there could be uninitialized bytes | |
47 | + * in-between the defined fields. This padding data should be explicitly accounted for by adding | |
48 | + * "empty" fields into the struct. This data is memset to zero before sending the struct across | |
49 | + * the socket. Adding the explicit fields ensures that the memset is not optimized away by the | |
50 | + * compiler. When a new field is added to the struct, the corresponding change | |
51 | + * in StructLayout_test should be made. | |
45 | 52 | */ |
46 | 53 | struct InputMessage { |
47 | 54 | enum { |
@@ -62,6 +69,7 @@ struct InputMessage { | ||
62 | 69 | union Body { |
63 | 70 | struct Key { |
64 | 71 | uint32_t seq; |
72 | + uint32_t empty1; | |
65 | 73 | nsecs_t eventTime __attribute__((aligned(8))); |
66 | 74 | int32_t deviceId; |
67 | 75 | int32_t source; |
@@ -72,6 +80,7 @@ struct InputMessage { | ||
72 | 80 | int32_t scanCode; |
73 | 81 | int32_t metaState; |
74 | 82 | int32_t repeatCount; |
83 | + uint32_t empty2; | |
75 | 84 | nsecs_t downTime __attribute__((aligned(8))); |
76 | 85 | |
77 | 86 | inline size_t size() const { |
@@ -81,6 +90,7 @@ struct InputMessage { | ||
81 | 90 | |
82 | 91 | struct Motion { |
83 | 92 | uint32_t seq; |
93 | + uint32_t empty1; | |
84 | 94 | nsecs_t eventTime __attribute__((aligned(8))); |
85 | 95 | int32_t deviceId; |
86 | 96 | int32_t source; |
@@ -91,12 +101,14 @@ struct InputMessage { | ||
91 | 101 | int32_t metaState; |
92 | 102 | int32_t buttonState; |
93 | 103 | int32_t edgeFlags; |
104 | + uint32_t empty2; | |
94 | 105 | nsecs_t downTime __attribute__((aligned(8))); |
95 | 106 | float xOffset; |
96 | 107 | float yOffset; |
97 | 108 | float xPrecision; |
98 | 109 | float yPrecision; |
99 | 110 | uint32_t pointerCount; |
111 | + uint32_t empty3; | |
100 | 112 | // Note that PointerCoords requires 8 byte alignment. |
101 | 113 | struct Pointer { |
102 | 114 | PointerProperties properties; |
@@ -127,6 +139,7 @@ struct InputMessage { | ||
127 | 139 | |
128 | 140 | bool isValid(size_t actualSize) const; |
129 | 141 | size_t size() const; |
142 | + void getSanitizedCopy(InputMessage* msg) const; | |
130 | 143 | }; |
131 | 144 | |
132 | 145 | /* |
@@ -96,6 +96,106 @@ size_t InputMessage::size() const { | ||
96 | 96 | return sizeof(Header); |
97 | 97 | } |
98 | 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 | + */ | |
103 | +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 | +} | |
99 | 199 | |
100 | 200 | // --- InputChannel --- |
101 | 201 |
@@ -149,10 +249,12 @@ status_t InputChannel::openInputChannelPair(const String8& name, | ||
149 | 249 | } |
150 | 250 | |
151 | 251 | status_t InputChannel::sendMessage(const InputMessage* msg) { |
152 | - size_t msgLength = msg->size(); | |
252 | + const size_t msgLength = msg->size(); | |
253 | + InputMessage cleanMsg; | |
254 | + msg->getSanitizedCopy(&cleanMsg); | |
153 | 255 | ssize_t nWrite; |
154 | 256 | do { |
155 | - nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); | |
257 | + nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); | |
156 | 258 | } while (nWrite == -1 && errno == EINTR); |
157 | 259 | |
158 | 260 | if (nWrite < 0) { |
@@ -65,6 +65,9 @@ void TestInputMessageAlignment() { | ||
65 | 65 | CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 76); |
66 | 66 | CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 80); |
67 | 67 | CHECK_OFFSET(InputMessage::Body::Motion, pointers, 88); |
68 | + | |
69 | + CHECK_OFFSET(InputMessage::Body::Finished, seq, 0); | |
70 | + CHECK_OFFSET(InputMessage::Body::Finished, handled, 4); | |
68 | 71 | } |
69 | 72 | |
70 | 73 | } // namespace android |