Mir

Merge lp:~mir-team/mir/android-input-transport-scatter-send-event into lp:mir

Proposed by Brandon Schaefer
Status: Rejected
Rejected by: Brandon Schaefer
Proposed branch: lp:~mir-team/mir/android-input-transport-scatter-send-event
Merge into: lp:mir
Diff against target: 316 lines (+165/-9)
2 files modified
3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h (+23/-2)
3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp (+142/-7)
To merge this branch: bzr merge lp:~mir-team/mir/android-input-transport-scatter-send-event
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Alan Griffiths Needs Fixing
Daniel van Vugt Needs Fixing
PS Jenkins bot (community) continuous-integration Approve
Alberto Aguirre (community) Approve
Chris Halse Rogers Approve
Review via email: mp+279387@code.launchpad.net

Commit message

Move to using a scatter/gather when sending input message. This will make sending a uint8_t* mac + uint32_t mac_size much simpler (and better).

Description of the change

Move to using a scatter/gather when sending input message. This will make sending a uint8_t* mac + uint32_t mac_size much simpler (and better).

This is the beginning stages. All the casting to unit8_t* from a uint64_t location will be removed and replaced with a std::vector.data() call. Makes the core changes seen (with out bloating to much).

To post a comment you must log in.
3160. By Brandon Schaefer

* Merge trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Chris Halse Rogers (raof) wrote :

+ /* Anything after the Pointer struct WILL BE CUT OFF if you send the entire
+ * struct. As the size() function returns only valid mouse pointers (leaving the rest off)
+ * So if you add to the struct insert before or manually re-construct the extra bits.
+ */

Could probably be reworded to be a bit clearer?

Maybe:
/* As an optimisation sendMessage() only sends the valid members of the pointers[]
 * array. This is implemented by size() only counting pointerCount members of
 * the pointers[] array.
 *
 * As a side effect, everything after the pointers[] array will NOT be reliably sent
 * in sendMessage(). Any members placed after pointers[] will need to be reconstructed
 * in recieveMessage().
 */

Otherwise seems fine.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

This is an input protocol break (remember last time you changed these?).

If we intentionally break part of the protocol then there are version macros that need updating. Although I would recommend not breaking it at all if you can help it.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Hmm, last time we changed these structures we had to ask app developers to rebuild re-release their click packages to match the new input protocol.

This needs a deep full-team discussion, if not deferring/rejecting for now...

Revision history for this message
Chris Halse Rogers (raof) wrote :

On Monday, 7 December 2015 7:35:59 PM AEDT, Daniel van Vugt wrote:
> Hmm, last time we changed these structures we had to ask app
> developers to rebuild re-release their click packages to match
> the new input protocol.
>
> This needs a deep full-team discussion, if not
> deferring/rejecting for now...

My memory of the outcome last time was “embedding libmirclient is not
supported; when we break it you get to keep both pieces”. Has anything
changrd to make it different this time?

--
Sent using Dekko from my Ubuntu device

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I'm not sure we have yet convinced/coerced app developers to stop shipping their own libmirclient.

Assuming we haven't, we should probably pause for a moment to consider the plan of attack. Because most things are better than breaking apps already in the store (again).

Disapproved for safety, till we're absolutely sure the same pain isn't going to happen all over again.

review: Disapprove
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I'm not familiar with the term "scatter/gather" in this context. What is the motivation here? If we're changing the serialization, then it might make sense to switch to the protobuf serialization we use elsewhere.

review: Needs Information
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

@duflu

From what I know we do not support the protocol. ie. We are free to break it, and make no guarantee it. From a public point of view.

Though if apps in the store are using it (against our guarantee). The yes we should approach a different plan of attack. Not sure the best one. As we *will* need to break the protocol again to support 160bit hash. How ever may it be.

@alan

The point of this scatter/gather is so we can send an arbitrary size hash over the protocol. As the 160bit hash is subject to being changed. We are looking at moving to a std::vector to hold the hash.

Issue being unions in InputMessage stop us from just using a vector. This is the approach around that. There will also be another issue in event_private, which we are moving MirEvent over to use boost::varaint so we can have a tagged union (which will then support std::vector!).

As far as moving to protobuf for serialization here... not sure. Im happy to do the best thing :). So Ill talk with RAOF. Though is protobuf the best for events? (Not really sure)

So right now the goal of this is:
1) Support sending a uint8_t* through the android socket to the client (this branch)
2) Move to using boost::variant in place of MirEvent (an attempt tagged union atm). This will allow us to store non-trivial objects in the MirEvent structs. As well as makes things type-safe (yay for us).
3) Move to using std::vector as a way to hold the MAC hash so we dont hard code 160bits. (subject to change)
4) Move to actually pushing the 160bit SHA-1 hash through to the vectors (which at this point will be support!)

Possibly best I write up a proposal?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> As far as moving to protobuf for serialization here... not sure. Im happy to
> do the best thing :). So Ill talk with RAOF. Though is protobuf the best for
> events? (Not really sure)

On the basis of our testing protobuf is unlikely to be "best" for performance, it would just be consistent (and does have, for example, some support for compatibility between versions). I'm sure RAOF will give you the background story.

3161. By Brandon Schaefer

* Change comment (reads much better)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Hey don't shoot the messenger. I'm just the poor bugger who untangled the problem last time so I remember it probably more than others.

That said, input protocol changes might be OK now providing (and we should verify) that the offending click packages:

1. use libmirclient9 (and only nine); and
2a. do not contain their own copy of libmirclient9; or
2b. will use the newer system version of libmirclient9 we provide instead of their own one.

Sounds feasible so we might be free to break the input protocol now.

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I don't have reason to block, but I've not the time to look closer (I'm on vacation the rest of this week).

review: Abstain
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Not trying to shoot :). So first thing first (before we look at approving this). Is to test if we would offend any click packages.

We also talked about rejecting click packages that bundle their own libmirclient. Which if that were the case, we can break away?

Ill try to talk with you later to try and figure out if this is OK to do atm, or figure out what will be needed to be done!

Thanks!

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I just had to find the history of the problem again. It's all in --> bug 1507982

Sounds like it probably won't happen again so long as no packages are using libmirclient8 or earlier. The affected apps of bug 1507982 have been rebuilt and re-released against libmirclient9. So that should be OK. The only remaining concern is that the problem could still happen in theory even if people don't package their own libmirclient, because bug 1498281 is still open.

In summary, it sounds like we are free to break the input protocol now. Just so long as we don't bump to libmirclient10 in the foreseeable future. This way all existing native apps that use libmirclient9 will just get the new libmirclient9 and protocol changes will be transparent.

review: Abstain
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Comments inline.

review: Needs Fixing
3162. By Brandon Schaefer

* Address reviewer

3163. By Brandon Schaefer

* Rework the using of the empty_mac so we set the correct size

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(1) Is 1000 a sensible number? That would allow up to 8000 bits which is a strange number. You might want something that is (2^n/8) bytes to avoid wastage.

(2) I just realized; having a (relative) pointer in an over-the-wire structure adds unnecessary complexity and risk:
+ uint8_t* mac;
The structure is meant to represent what goes over the wire, but it can't now and you have an unnecessary dance to support it.

Please just change it to a fixed size like "uint8_t mac[512]; // supports up to 4096 bits".

That will nicely restore clear over-the-wire opaque copy support, and so simplify the code a lot too.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

(2) Or if you really do need variable size support, make it clearer using "ptrdiff_t mac_offset" and add a getter method that is "uint8_t* mac() const".

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

> (2) I just realized; having a (relative) pointer in an over-the-wire structure
> adds unnecessary complexity and risk:
> + uint8_t* mac;
> The structure is meant to represent what goes over the wire, but it can't now
> and you have an unnecessary dance to support it.
>
> Please just change it to a fixed size like "uint8_t mac[512]; // supports up
> to 4096 bits".
>

Umm but that's the whole point of this MP, to use the scatter/gather support in the kernel so that you don't have to copy the mac into the structure when sending.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK codewise, but note this is a protocol break that isn't a client ABI bump.

Before release we need to update mir::protobuf::oldest_compatible_protocol_version() and possibly mir::protobuf::current_protocol_version() (the latter only if we don't add any client API functions and bump MIR_CLIENT_MINOR_VERSION).

mir::protobuf::oldest_compatible_protocol_version() should return protocol_version(MIR_CLIENT_MAJOR_VERSION, 3);

Otherwise we'll accept connections from older libmirclient binaries but send input events they cannot parse and (if we don't bump MIR_CLIENT_MINOR_VERSION) successfully connect new clients to 0.18 servers which do not supply the correct events.

We can either make these changes here, or accept a promise elsewhere but we need to be sure of the approach before landing this branch.

review: Needs Information
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> OK codewise, but note this is a protocol break that isn't a client ABI bump.

Actually, the easiest approach would be to bump the epoch default value in mir::protobuf::protocol_version() - and that can be done here very simply.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

> Umm but that's the whole point of this MP, to use the scatter/gather support
> in the kernel so that you don't have to copy the mac into the structure when
> sending.

Maybe so, but I think my suggestion is significantly simpler. Smaller code and easier to follow and maintain.

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Im fine for using either. If we using a uint8_t[N] vs a uint8_t*. After all it looks we will want to replace with proper serialization anyway. So, the reason for supporting scatter/gather was with the idea that it would be useful for the future. If we want to rip this out, then maybe the simplest smallest way would be the best?

Though im not sure how long it would take to move to proper serialization :). It would be on my list of goals, and looking at it *shouldnt* be to hard.

Revision history for this message
Chris Halse Rogers (raof) wrote :

Ok. Since we apparently intend to do this correctly in the not-too-distant future, and we're capable of breaking protocol at this level at will, we might as well shove a simple
uint8_t mac[20];
into the relevant structures and preserve the blittability at the cost of mac size changes being a protocol break.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3163
https://mir-jenkins.ubuntu.com/job/mir-ci/19/
Executed test runs:
    None: https://mir-jenkins.ubuntu.com/job/generic-update-mp/19/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/19/rebuild

review: Approve (continuous-integration)

Unmerged revisions

3163. By Brandon Schaefer

* Rework the using of the empty_mac so we set the correct size

3162. By Brandon Schaefer

* Address reviewer

3161. By Brandon Schaefer

* Change comment (reads much better)

3160. By Brandon Schaefer

* Merge trunk

3159. By Brandon Schaefer

* Switch to using recvmsg so we can check if we get a truncated message! (We cant have those)
* Also added a comment to why we need to put values before the pointer[] if we want to copy those values.
  the mac* is handled in its own buffer (the address is copied) soo its fine after the pointer[]

3158. By Brandon Schaefer

* Move to using a unit8_t* for the mac + a uint32_t mac_size to pass a variable length mac hash
  through the fd

3157. By Brandon Schaefer

* Move to using a scatter/gather method for sending events.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h'
--- 3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h 2015-08-17 18:33:38 +0000
+++ 3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h 2015-12-11 21:17:18 +0000
@@ -45,6 +45,8 @@
45 * Intermediate representation used to send input events and related signals.45 * Intermediate representation used to send input events and related signals.
46 */46 */
47struct InputMessage {47struct InputMessage {
48 static uint32_t const MAC_PADDING = 1000;
49
48 InputMessage();50 InputMessage();
4951
50 enum {52 enum {
@@ -62,7 +64,6 @@
62 struct Key {64 struct Key {
63 uint32_t seq;65 uint32_t seq;
64 int64_t eventTime;66 int64_t eventTime;
65 uint64_t mac;
66 int32_t deviceId;67 int32_t deviceId;
67 int32_t source;68 int32_t source;
68 int32_t action;69 int32_t action;
@@ -72,6 +73,8 @@
72 int32_t metaState;73 int32_t metaState;
73 int32_t repeatCount;74 int32_t repeatCount;
74 int64_t downTime;75 int64_t downTime;
76 uint32_t mac_size;
77 uint8_t* mac;
7578
76 inline size_t size() const {79 inline size_t size() const {
77 return sizeof(Key);80 return sizeof(Key);
@@ -81,7 +84,6 @@
81 struct Motion {84 struct Motion {
82 uint32_t seq;85 uint32_t seq;
83 int64_t eventTime;86 int64_t eventTime;
84 uint64_t mac;
85 int32_t deviceId;87 int32_t deviceId;
86 int32_t source;88 int32_t source;
87 int32_t action;89 int32_t action;
@@ -95,10 +97,20 @@
95 float xPrecision;97 float xPrecision;
96 float yPrecision;98 float yPrecision;
97 size_t pointerCount;99 size_t pointerCount;
100 uint32_t mac_size;
101 /* As an optimisation sendMessage() only sends the valid members of the pointers[]
102 * array. This is implemented by size() only counting pointerCount members of
103 * the pointers[] array.
104 *
105 * As a side effect, everything after the pointers[] array will NOT be reliably sent
106 * in sendMessage(). Any members placed after pointers[] will need to be reconstructed
107 * in recieveMessage().
108 */
98 struct Pointer {109 struct Pointer {
99 PointerProperties properties;110 PointerProperties properties;
100 PointerCoords coords;111 PointerCoords coords;
101 } pointers[MAX_POINTERS];112 } pointers[MAX_POINTERS];
113 uint8_t* mac;
102114
103 int32_t getActionId() const {115 int32_t getActionId() const {
104 uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)116 uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
@@ -120,6 +132,15 @@
120 return sizeof(Finished);132 return sizeof(Finished);
121 }133 }
122 } finished;134 } finished;
135
136 /* Use a 1KB padding for the MAC
137 *
138 * Reserve enough space to receive a MAC in
139 * receiveMessage(...)
140 */
141 struct Padding {
142 uint8_t mac_padding[MAC_PADDING];
143 };
123 } body;144 } body;
124145
125 bool isValid(size_t actualSize) const;146 bool isValid(size_t actualSize) const;
126147
=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp'
--- 3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp 2015-10-20 03:30:00 +0000
+++ 3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp 2015-12-11 21:17:18 +0000
@@ -27,7 +27,9 @@
27#include <unistd.h>27#include <unistd.h>
28#include <sys/types.h>28#include <sys/types.h>
29#include <sys/socket.h>29#include <sys/socket.h>
30#include <sys/uio.h>
30#include <math.h>31#include <math.h>
32#include <stdexcept>
3133
3234
33namespace android {35namespace android {
@@ -38,6 +40,8 @@
38// behind processing touches.40// behind processing touches.
39static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;41static const size_t SOCKET_BUFFER_SIZE = 32 * 1024;
4042
43static const uint64_t EMPTY_MAC = 0;
44
41// Nanoseconds per milliseconds.45// Nanoseconds per milliseconds.
42static constexpr const std::chrono::nanoseconds NANOS_PER_MS = std::chrono::nanoseconds(1000000);46static constexpr const std::chrono::nanoseconds NANOS_PER_MS = std::chrono::nanoseconds(1000000);
4347
@@ -61,6 +65,19 @@
61 return a + alpha * (b - a);65 return a + alpha * (b - a);
62}66}
6367
68size_t getMacSizeForMessage(const InputMessage* msg)
69{
70 switch(msg->header.type)
71 {
72 case InputMessage::TYPE_KEY:
73 return msg->body.key.mac_size;
74 case InputMessage::TYPE_MOTION:
75 return msg->body.motion.mac_size;
76 }
77
78 return 0;
79}
80
64// --- InputMessage ---81// --- InputMessage ---
6582
66InputMessage::InputMessage()83InputMessage::InputMessage()
@@ -69,7 +86,8 @@
69}86}
7087
71bool InputMessage::isValid(size_t actualSize) const {88bool InputMessage::isValid(size_t actualSize) const {
72 if (size() == actualSize) {89 size_t const mac_size = getMacSizeForMessage(this);
90 if (size() + mac_size == actualSize) {
73 switch (header.type) {91 switch (header.type) {
74 case TYPE_KEY:92 case TYPE_KEY:
75 return true;93 return true;
@@ -140,11 +158,74 @@
140 return OK;158 return OK;
141}159}
142160
161bool messageHasMac(const InputMessage* msg)
162{
163 switch(msg->header.type) {
164 case InputMessage::TYPE_KEY:
165 case InputMessage::TYPE_MOTION:
166 return true;
167 }
168
169 return false;
170}
171
172uint8_t* macFromMessage(const InputMessage* msg)
173{
174 switch(msg->header.type) {
175 case InputMessage::TYPE_KEY:
176 return msg->body.key.mac;
177 case InputMessage::TYPE_MOTION:
178 return msg->body.motion.mac;
179 }
180
181 throw std::runtime_error("Invalid message type: " + msg->header.type);
182}
183
184size_t fillMac(const InputMessage* msg, iovec* vec)
185{
186 auto const mac = static_cast<void*>(macFromMessage(msg));
187 auto const size = getMacSizeForMessage(msg);
188
189 if (mac && size == sizeof(uint64_t))
190 {
191 vec->iov_base = mac;
192 vec->iov_len = size;
193 }
194 else
195 {
196 vec->iov_base = static_cast<void*>(const_cast<uint64_t*>(&EMPTY_MAC));
197 vec->iov_len = sizeof(EMPTY_MAC);
198 }
199
200 return vec->iov_len;
201}
202
143status_t InputChannel::sendMessage(const InputMessage* msg) {203status_t InputChannel::sendMessage(const InputMessage* msg) {
204 std::array<iovec, 2> msg_parts;
144 size_t msgLength = msg->size();205 size_t msgLength = msg->size();
206 size_t msg_parts_size = 1;
207
208 msg_parts[0].iov_base = static_cast<void*>(const_cast<InputMessage*>(msg));
209 msg_parts[0].iov_len = msgLength;
210
211 if (messageHasMac(msg)) {
212 msgLength += fillMac(msg, &msg_parts[1]);
213 msg_parts_size++;
214 }
215
216 msghdr const message = {
217 nullptr,
218 0,
219 msg_parts.data(),
220 msg_parts_size,
221 nullptr,
222 0,
223 0
224 };
225
145 ssize_t nWrite;226 ssize_t nWrite;
146 do {227 do {
147 nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);228 nWrite = ::sendmsg(mFd, &message, MSG_DONTWAIT | MSG_NOSIGNAL);
148 } while (nWrite == -1 && errno == EINTR);229 } while (nWrite == -1 && errno == EINTR);
149230
150 if (nWrite < 0) {231 if (nWrite < 0) {
@@ -176,12 +257,64 @@
176 return OK;257 return OK;
177}258}
178259
260uint8_t* getMacArrayFromMessageOffset(const InputMessage* msg, uint32_t mac_size)
261{
262 if (mac_size == sizeof(uint64_t)) {
263 return reinterpret_cast<uint8_t*>(const_cast<InputMessage*>(msg)) + msg->size();
264 }
265
266 return reinterpret_cast<uint8_t*>(const_cast<uint64_t*>(&EMPTY_MAC));
267}
268
269void setMacAddressFromMessage(InputMessage* msg)
270{
271 switch (msg->header.type)
272 {
273 case InputMessage::TYPE_KEY:
274 {
275 msg->body.key.mac = getMacArrayFromMessageOffset(msg, msg->body.key.mac_size);
276 break;
277 }
278 case InputMessage::TYPE_MOTION:
279 {
280 msg->body.motion.mac = getMacArrayFromMessageOffset(msg, msg->body.motion.mac_size);
281 break;
282 }
283 }
284}
285
179status_t InputChannel::receiveMessage(InputMessage* msg) {286status_t InputChannel::receiveMessage(InputMessage* msg) {
287 iovec recv_msg;
288
289 recv_msg.iov_base = msg;
290 recv_msg.iov_len = sizeof(InputMessage);
291
292 msghdr message = {
293 nullptr,
294 0,
295 &recv_msg,
296 1,
297 nullptr,
298 0,
299 0
300 };
301
180 ssize_t nRead;302 ssize_t nRead;
181 do {303 do {
182 nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);304 nRead = ::recvmsg(mFd, &message, MSG_DONTWAIT);
183 } while (nRead == -1 && errno == EINTR);305 } while (nRead == -1 && errno == EINTR);
184306
307 if (messageHasMac(msg)) {
308 setMacAddressFromMessage(msg);
309 }
310
311 if (message.msg_flags & MSG_TRUNC) {
312#if DEBUG_CHANNEL_MESSAGES
313 ALOGD("channel '%s' ~ received message was truncated undefined behaviour", c_str(mName));
314#endif
315 return BAD_VALUE;
316 }
317
185 if (nRead < 0) {318 if (nRead < 0) {
186 int error = errno;319 int error = errno;
187#if DEBUG_CHANNEL_MESSAGES320#if DEBUG_CHANNEL_MESSAGES
@@ -264,9 +397,10 @@
264 msg.body.key.scanCode = scanCode;397 msg.body.key.scanCode = scanCode;
265 msg.body.key.metaState = metaState;398 msg.body.key.metaState = metaState;
266 msg.body.key.repeatCount = repeatCount;399 msg.body.key.repeatCount = repeatCount;
267 msg.body.key.mac = mac;
268 msg.body.key.downTime = downTime.count();400 msg.body.key.downTime = downTime.count();
269 msg.body.key.eventTime = eventTime.count();401 msg.body.key.eventTime = eventTime.count();
402 msg.body.key.mac = reinterpret_cast<uint8_t*>(&mac);
403 msg.body.key.mac_size = sizeof(uint64_t);
270 return mChannel->sendMessage(&msg);404 return mChannel->sendMessage(&msg);
271}405}
272406
@@ -325,7 +459,6 @@
325 msg.body.motion.yOffset = yOffset;459 msg.body.motion.yOffset = yOffset;
326 msg.body.motion.xPrecision = xPrecision;460 msg.body.motion.xPrecision = xPrecision;
327 msg.body.motion.yPrecision = yPrecision;461 msg.body.motion.yPrecision = yPrecision;
328 msg.body.motion.mac = mac;
329 msg.body.motion.downTime = downTime.count();462 msg.body.motion.downTime = downTime.count();
330 msg.body.motion.eventTime = eventTime.count();463 msg.body.motion.eventTime = eventTime.count();
331 msg.body.motion.pointerCount = pointerCount;464 msg.body.motion.pointerCount = pointerCount;
@@ -333,6 +466,8 @@
333 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);466 msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
334 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);467 msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
335 }468 }
469 msg.body.motion.mac = reinterpret_cast<uint8_t*>(&mac);
470 msg.body.motion.mac_size = sizeof(uint64_t);
336 return mChannel->sendMessage(&msg);471 return mChannel->sendMessage(&msg);
337}472}
338473
@@ -882,7 +1017,7 @@
882 msg->body.key.scanCode,1017 msg->body.key.scanCode,
883 msg->body.key.metaState,1018 msg->body.key.metaState,
884 msg->body.key.repeatCount,1019 msg->body.key.repeatCount,
885 msg->body.key.mac,1020 *(reinterpret_cast<uint64_t*>(msg->body.key.mac)),
886 std::chrono::nanoseconds(msg->body.key.downTime),1021 std::chrono::nanoseconds(msg->body.key.downTime),
887 std::chrono::nanoseconds(msg->body.key.eventTime));1022 std::chrono::nanoseconds(msg->body.key.eventTime));
888}1023}
@@ -908,7 +1043,7 @@
908 msg->body.motion.yOffset,1043 msg->body.motion.yOffset,
909 msg->body.motion.xPrecision,1044 msg->body.motion.xPrecision,
910 msg->body.motion.yPrecision,1045 msg->body.motion.yPrecision,
911 msg->body.motion.mac,1046 *(reinterpret_cast<uint64_t*>(msg->body.motion.mac)),
912 std::chrono::nanoseconds(msg->body.motion.downTime),1047 std::chrono::nanoseconds(msg->body.motion.downTime),
913 std::chrono::nanoseconds(msg->body.motion.eventTime),1048 std::chrono::nanoseconds(msg->body.motion.eventTime),
914 pointerCount,1049 pointerCount,

Subscribers

People subscribed via source and target branches