Merge lp:~mir-team/mir/android-input-transport-scatter-send-event into lp:mir
- android-input-transport-scatter-send-event
- Merge into development-branch
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 |
Related bugs: |
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).
- 3160. By Brandon Schaefer
-
* Merge trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3160
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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.
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.
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...
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
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.
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.
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?
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)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3161
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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.
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).
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!
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.
Alberto Aguirre (albaguirre) wrote : | # |
Comments inline.
- 3162. By Brandon Schaefer
-
* Address reviewer
- 3163. By Brandon Schaefer
-
* Rework the using of the empty_mac so we set the correct size
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3162
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:3163
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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.
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".
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.
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:
mir::protobuf:
Otherwise we'll accept connections from older libmirclient binaries but send input events they cannot parse and (if we don't bump MIR_CLIENT_
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.
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:
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.
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.
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.
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3163
https:/
Executed test runs:
None: https:/
Click here to trigger a rebuild:
https:/
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
1 | === modified file '3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h' | |||
2 | --- 3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h 2015-08-17 18:33:38 +0000 | |||
3 | +++ 3rd_party/android-input/android/frameworks/base/include/androidfw/InputTransport.h 2015-12-11 21:17:18 +0000 | |||
4 | @@ -45,6 +45,8 @@ | |||
5 | 45 | * Intermediate representation used to send input events and related signals. | 45 | * Intermediate representation used to send input events and related signals. |
6 | 46 | */ | 46 | */ |
7 | 47 | struct InputMessage { | 47 | struct InputMessage { |
8 | 48 | static uint32_t const MAC_PADDING = 1000; | ||
9 | 49 | |||
10 | 48 | InputMessage(); | 50 | InputMessage(); |
11 | 49 | 51 | ||
12 | 50 | enum { | 52 | enum { |
13 | @@ -62,7 +64,6 @@ | |||
14 | 62 | struct Key { | 64 | struct Key { |
15 | 63 | uint32_t seq; | 65 | uint32_t seq; |
16 | 64 | int64_t eventTime; | 66 | int64_t eventTime; |
17 | 65 | uint64_t mac; | ||
18 | 66 | int32_t deviceId; | 67 | int32_t deviceId; |
19 | 67 | int32_t source; | 68 | int32_t source; |
20 | 68 | int32_t action; | 69 | int32_t action; |
21 | @@ -72,6 +73,8 @@ | |||
22 | 72 | int32_t metaState; | 73 | int32_t metaState; |
23 | 73 | int32_t repeatCount; | 74 | int32_t repeatCount; |
24 | 74 | int64_t downTime; | 75 | int64_t downTime; |
25 | 76 | uint32_t mac_size; | ||
26 | 77 | uint8_t* mac; | ||
27 | 75 | 78 | ||
28 | 76 | inline size_t size() const { | 79 | inline size_t size() const { |
29 | 77 | return sizeof(Key); | 80 | return sizeof(Key); |
30 | @@ -81,7 +84,6 @@ | |||
31 | 81 | struct Motion { | 84 | struct Motion { |
32 | 82 | uint32_t seq; | 85 | uint32_t seq; |
33 | 83 | int64_t eventTime; | 86 | int64_t eventTime; |
34 | 84 | uint64_t mac; | ||
35 | 85 | int32_t deviceId; | 87 | int32_t deviceId; |
36 | 86 | int32_t source; | 88 | int32_t source; |
37 | 87 | int32_t action; | 89 | int32_t action; |
38 | @@ -95,10 +97,20 @@ | |||
39 | 95 | float xPrecision; | 97 | float xPrecision; |
40 | 96 | float yPrecision; | 98 | float yPrecision; |
41 | 97 | size_t pointerCount; | 99 | size_t pointerCount; |
42 | 100 | uint32_t mac_size; | ||
43 | 101 | /* As an optimisation sendMessage() only sends the valid members of the pointers[] | ||
44 | 102 | * array. This is implemented by size() only counting pointerCount members of | ||
45 | 103 | * the pointers[] array. | ||
46 | 104 | * | ||
47 | 105 | * As a side effect, everything after the pointers[] array will NOT be reliably sent | ||
48 | 106 | * in sendMessage(). Any members placed after pointers[] will need to be reconstructed | ||
49 | 107 | * in recieveMessage(). | ||
50 | 108 | */ | ||
51 | 98 | struct Pointer { | 109 | struct Pointer { |
52 | 99 | PointerProperties properties; | 110 | PointerProperties properties; |
53 | 100 | PointerCoords coords; | 111 | PointerCoords coords; |
54 | 101 | } pointers[MAX_POINTERS]; | 112 | } pointers[MAX_POINTERS]; |
55 | 113 | uint8_t* mac; | ||
56 | 102 | 114 | ||
57 | 103 | int32_t getActionId() const { | 115 | int32_t getActionId() const { |
58 | 104 | uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) | 116 | uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) |
59 | @@ -120,6 +132,15 @@ | |||
60 | 120 | return sizeof(Finished); | 132 | return sizeof(Finished); |
61 | 121 | } | 133 | } |
62 | 122 | } finished; | 134 | } finished; |
63 | 135 | |||
64 | 136 | /* Use a 1KB padding for the MAC | ||
65 | 137 | * | ||
66 | 138 | * Reserve enough space to receive a MAC in | ||
67 | 139 | * receiveMessage(...) | ||
68 | 140 | */ | ||
69 | 141 | struct Padding { | ||
70 | 142 | uint8_t mac_padding[MAC_PADDING]; | ||
71 | 143 | }; | ||
72 | 123 | } body; | 144 | } body; |
73 | 124 | 145 | ||
74 | 125 | bool isValid(size_t actualSize) const; | 146 | bool isValid(size_t actualSize) const; |
75 | 126 | 147 | ||
76 | === modified file '3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp' | |||
77 | --- 3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp 2015-10-20 03:30:00 +0000 | |||
78 | +++ 3rd_party/android-input/android/frameworks/base/services/input/InputTransport.cpp 2015-12-11 21:17:18 +0000 | |||
79 | @@ -27,7 +27,9 @@ | |||
80 | 27 | #include <unistd.h> | 27 | #include <unistd.h> |
81 | 28 | #include <sys/types.h> | 28 | #include <sys/types.h> |
82 | 29 | #include <sys/socket.h> | 29 | #include <sys/socket.h> |
83 | 30 | #include <sys/uio.h> | ||
84 | 30 | #include <math.h> | 31 | #include <math.h> |
85 | 32 | #include <stdexcept> | ||
86 | 31 | 33 | ||
87 | 32 | 34 | ||
88 | 33 | namespace android { | 35 | namespace android { |
89 | @@ -38,6 +40,8 @@ | |||
90 | 38 | // behind processing touches. | 40 | // behind processing touches. |
91 | 39 | static const size_t SOCKET_BUFFER_SIZE = 32 * 1024; | 41 | static const size_t SOCKET_BUFFER_SIZE = 32 * 1024; |
92 | 40 | 42 | ||
93 | 43 | static const uint64_t EMPTY_MAC = 0; | ||
94 | 44 | |||
95 | 41 | // Nanoseconds per milliseconds. | 45 | // Nanoseconds per milliseconds. |
96 | 42 | static constexpr const std::chrono::nanoseconds NANOS_PER_MS = std::chrono::nanoseconds(1000000); | 46 | static constexpr const std::chrono::nanoseconds NANOS_PER_MS = std::chrono::nanoseconds(1000000); |
97 | 43 | 47 | ||
98 | @@ -61,6 +65,19 @@ | |||
99 | 61 | return a + alpha * (b - a); | 65 | return a + alpha * (b - a); |
100 | 62 | } | 66 | } |
101 | 63 | 67 | ||
102 | 68 | size_t getMacSizeForMessage(const InputMessage* msg) | ||
103 | 69 | { | ||
104 | 70 | switch(msg->header.type) | ||
105 | 71 | { | ||
106 | 72 | case InputMessage::TYPE_KEY: | ||
107 | 73 | return msg->body.key.mac_size; | ||
108 | 74 | case InputMessage::TYPE_MOTION: | ||
109 | 75 | return msg->body.motion.mac_size; | ||
110 | 76 | } | ||
111 | 77 | |||
112 | 78 | return 0; | ||
113 | 79 | } | ||
114 | 80 | |||
115 | 64 | // --- InputMessage --- | 81 | // --- InputMessage --- |
116 | 65 | 82 | ||
117 | 66 | InputMessage::InputMessage() | 83 | InputMessage::InputMessage() |
118 | @@ -69,7 +86,8 @@ | |||
119 | 69 | } | 86 | } |
120 | 70 | 87 | ||
121 | 71 | bool InputMessage::isValid(size_t actualSize) const { | 88 | bool InputMessage::isValid(size_t actualSize) const { |
123 | 72 | if (size() == actualSize) { | 89 | size_t const mac_size = getMacSizeForMessage(this); |
124 | 90 | if (size() + mac_size == actualSize) { | ||
125 | 73 | switch (header.type) { | 91 | switch (header.type) { |
126 | 74 | case TYPE_KEY: | 92 | case TYPE_KEY: |
127 | 75 | return true; | 93 | return true; |
128 | @@ -140,11 +158,74 @@ | |||
129 | 140 | return OK; | 158 | return OK; |
130 | 141 | } | 159 | } |
131 | 142 | 160 | ||
132 | 161 | bool messageHasMac(const InputMessage* msg) | ||
133 | 162 | { | ||
134 | 163 | switch(msg->header.type) { | ||
135 | 164 | case InputMessage::TYPE_KEY: | ||
136 | 165 | case InputMessage::TYPE_MOTION: | ||
137 | 166 | return true; | ||
138 | 167 | } | ||
139 | 168 | |||
140 | 169 | return false; | ||
141 | 170 | } | ||
142 | 171 | |||
143 | 172 | uint8_t* macFromMessage(const InputMessage* msg) | ||
144 | 173 | { | ||
145 | 174 | switch(msg->header.type) { | ||
146 | 175 | case InputMessage::TYPE_KEY: | ||
147 | 176 | return msg->body.key.mac; | ||
148 | 177 | case InputMessage::TYPE_MOTION: | ||
149 | 178 | return msg->body.motion.mac; | ||
150 | 179 | } | ||
151 | 180 | |||
152 | 181 | throw std::runtime_error("Invalid message type: " + msg->header.type); | ||
153 | 182 | } | ||
154 | 183 | |||
155 | 184 | size_t fillMac(const InputMessage* msg, iovec* vec) | ||
156 | 185 | { | ||
157 | 186 | auto const mac = static_cast<void*>(macFromMessage(msg)); | ||
158 | 187 | auto const size = getMacSizeForMessage(msg); | ||
159 | 188 | |||
160 | 189 | if (mac && size == sizeof(uint64_t)) | ||
161 | 190 | { | ||
162 | 191 | vec->iov_base = mac; | ||
163 | 192 | vec->iov_len = size; | ||
164 | 193 | } | ||
165 | 194 | else | ||
166 | 195 | { | ||
167 | 196 | vec->iov_base = static_cast<void*>(const_cast<uint64_t*>(&EMPTY_MAC)); | ||
168 | 197 | vec->iov_len = sizeof(EMPTY_MAC); | ||
169 | 198 | } | ||
170 | 199 | |||
171 | 200 | return vec->iov_len; | ||
172 | 201 | } | ||
173 | 202 | |||
174 | 143 | status_t InputChannel::sendMessage(const InputMessage* msg) { | 203 | status_t InputChannel::sendMessage(const InputMessage* msg) { |
175 | 204 | std::array<iovec, 2> msg_parts; | ||
176 | 144 | size_t msgLength = msg->size(); | 205 | size_t msgLength = msg->size(); |
177 | 206 | size_t msg_parts_size = 1; | ||
178 | 207 | |||
179 | 208 | msg_parts[0].iov_base = static_cast<void*>(const_cast<InputMessage*>(msg)); | ||
180 | 209 | msg_parts[0].iov_len = msgLength; | ||
181 | 210 | |||
182 | 211 | if (messageHasMac(msg)) { | ||
183 | 212 | msgLength += fillMac(msg, &msg_parts[1]); | ||
184 | 213 | msg_parts_size++; | ||
185 | 214 | } | ||
186 | 215 | |||
187 | 216 | msghdr const message = { | ||
188 | 217 | nullptr, | ||
189 | 218 | 0, | ||
190 | 219 | msg_parts.data(), | ||
191 | 220 | msg_parts_size, | ||
192 | 221 | nullptr, | ||
193 | 222 | 0, | ||
194 | 223 | 0 | ||
195 | 224 | }; | ||
196 | 225 | |||
197 | 145 | ssize_t nWrite; | 226 | ssize_t nWrite; |
198 | 146 | do { | 227 | do { |
200 | 147 | nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL); | 228 | nWrite = ::sendmsg(mFd, &message, MSG_DONTWAIT | MSG_NOSIGNAL); |
201 | 148 | } while (nWrite == -1 && errno == EINTR); | 229 | } while (nWrite == -1 && errno == EINTR); |
202 | 149 | 230 | ||
203 | 150 | if (nWrite < 0) { | 231 | if (nWrite < 0) { |
204 | @@ -176,12 +257,64 @@ | |||
205 | 176 | return OK; | 257 | return OK; |
206 | 177 | } | 258 | } |
207 | 178 | 259 | ||
208 | 260 | uint8_t* getMacArrayFromMessageOffset(const InputMessage* msg, uint32_t mac_size) | ||
209 | 261 | { | ||
210 | 262 | if (mac_size == sizeof(uint64_t)) { | ||
211 | 263 | return reinterpret_cast<uint8_t*>(const_cast<InputMessage*>(msg)) + msg->size(); | ||
212 | 264 | } | ||
213 | 265 | |||
214 | 266 | return reinterpret_cast<uint8_t*>(const_cast<uint64_t*>(&EMPTY_MAC)); | ||
215 | 267 | } | ||
216 | 268 | |||
217 | 269 | void setMacAddressFromMessage(InputMessage* msg) | ||
218 | 270 | { | ||
219 | 271 | switch (msg->header.type) | ||
220 | 272 | { | ||
221 | 273 | case InputMessage::TYPE_KEY: | ||
222 | 274 | { | ||
223 | 275 | msg->body.key.mac = getMacArrayFromMessageOffset(msg, msg->body.key.mac_size); | ||
224 | 276 | break; | ||
225 | 277 | } | ||
226 | 278 | case InputMessage::TYPE_MOTION: | ||
227 | 279 | { | ||
228 | 280 | msg->body.motion.mac = getMacArrayFromMessageOffset(msg, msg->body.motion.mac_size); | ||
229 | 281 | break; | ||
230 | 282 | } | ||
231 | 283 | } | ||
232 | 284 | } | ||
233 | 285 | |||
234 | 179 | status_t InputChannel::receiveMessage(InputMessage* msg) { | 286 | status_t InputChannel::receiveMessage(InputMessage* msg) { |
235 | 287 | iovec recv_msg; | ||
236 | 288 | |||
237 | 289 | recv_msg.iov_base = msg; | ||
238 | 290 | recv_msg.iov_len = sizeof(InputMessage); | ||
239 | 291 | |||
240 | 292 | msghdr message = { | ||
241 | 293 | nullptr, | ||
242 | 294 | 0, | ||
243 | 295 | &recv_msg, | ||
244 | 296 | 1, | ||
245 | 297 | nullptr, | ||
246 | 298 | 0, | ||
247 | 299 | 0 | ||
248 | 300 | }; | ||
249 | 301 | |||
250 | 180 | ssize_t nRead; | 302 | ssize_t nRead; |
251 | 181 | do { | 303 | do { |
253 | 182 | nRead = ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT); | 304 | nRead = ::recvmsg(mFd, &message, MSG_DONTWAIT); |
254 | 183 | } while (nRead == -1 && errno == EINTR); | 305 | } while (nRead == -1 && errno == EINTR); |
255 | 184 | 306 | ||
256 | 307 | if (messageHasMac(msg)) { | ||
257 | 308 | setMacAddressFromMessage(msg); | ||
258 | 309 | } | ||
259 | 310 | |||
260 | 311 | if (message.msg_flags & MSG_TRUNC) { | ||
261 | 312 | #if DEBUG_CHANNEL_MESSAGES | ||
262 | 313 | ALOGD("channel '%s' ~ received message was truncated undefined behaviour", c_str(mName)); | ||
263 | 314 | #endif | ||
264 | 315 | return BAD_VALUE; | ||
265 | 316 | } | ||
266 | 317 | |||
267 | 185 | if (nRead < 0) { | 318 | if (nRead < 0) { |
268 | 186 | int error = errno; | 319 | int error = errno; |
269 | 187 | #if DEBUG_CHANNEL_MESSAGES | 320 | #if DEBUG_CHANNEL_MESSAGES |
270 | @@ -264,9 +397,10 @@ | |||
271 | 264 | msg.body.key.scanCode = scanCode; | 397 | msg.body.key.scanCode = scanCode; |
272 | 265 | msg.body.key.metaState = metaState; | 398 | msg.body.key.metaState = metaState; |
273 | 266 | msg.body.key.repeatCount = repeatCount; | 399 | msg.body.key.repeatCount = repeatCount; |
274 | 267 | msg.body.key.mac = mac; | ||
275 | 268 | msg.body.key.downTime = downTime.count(); | 400 | msg.body.key.downTime = downTime.count(); |
276 | 269 | msg.body.key.eventTime = eventTime.count(); | 401 | msg.body.key.eventTime = eventTime.count(); |
277 | 402 | msg.body.key.mac = reinterpret_cast<uint8_t*>(&mac); | ||
278 | 403 | msg.body.key.mac_size = sizeof(uint64_t); | ||
279 | 270 | return mChannel->sendMessage(&msg); | 404 | return mChannel->sendMessage(&msg); |
280 | 271 | } | 405 | } |
281 | 272 | 406 | ||
282 | @@ -325,7 +459,6 @@ | |||
283 | 325 | msg.body.motion.yOffset = yOffset; | 459 | msg.body.motion.yOffset = yOffset; |
284 | 326 | msg.body.motion.xPrecision = xPrecision; | 460 | msg.body.motion.xPrecision = xPrecision; |
285 | 327 | msg.body.motion.yPrecision = yPrecision; | 461 | msg.body.motion.yPrecision = yPrecision; |
286 | 328 | msg.body.motion.mac = mac; | ||
287 | 329 | msg.body.motion.downTime = downTime.count(); | 462 | msg.body.motion.downTime = downTime.count(); |
288 | 330 | msg.body.motion.eventTime = eventTime.count(); | 463 | msg.body.motion.eventTime = eventTime.count(); |
289 | 331 | msg.body.motion.pointerCount = pointerCount; | 464 | msg.body.motion.pointerCount = pointerCount; |
290 | @@ -333,6 +466,8 @@ | |||
291 | 333 | msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]); | 466 | msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]); |
292 | 334 | msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]); | 467 | msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]); |
293 | 335 | } | 468 | } |
294 | 469 | msg.body.motion.mac = reinterpret_cast<uint8_t*>(&mac); | ||
295 | 470 | msg.body.motion.mac_size = sizeof(uint64_t); | ||
296 | 336 | return mChannel->sendMessage(&msg); | 471 | return mChannel->sendMessage(&msg); |
297 | 337 | } | 472 | } |
298 | 338 | 473 | ||
299 | @@ -882,7 +1017,7 @@ | |||
300 | 882 | msg->body.key.scanCode, | 1017 | msg->body.key.scanCode, |
301 | 883 | msg->body.key.metaState, | 1018 | msg->body.key.metaState, |
302 | 884 | msg->body.key.repeatCount, | 1019 | msg->body.key.repeatCount, |
304 | 885 | msg->body.key.mac, | 1020 | *(reinterpret_cast<uint64_t*>(msg->body.key.mac)), |
305 | 886 | std::chrono::nanoseconds(msg->body.key.downTime), | 1021 | std::chrono::nanoseconds(msg->body.key.downTime), |
306 | 887 | std::chrono::nanoseconds(msg->body.key.eventTime)); | 1022 | std::chrono::nanoseconds(msg->body.key.eventTime)); |
307 | 888 | } | 1023 | } |
308 | @@ -908,7 +1043,7 @@ | |||
309 | 908 | msg->body.motion.yOffset, | 1043 | msg->body.motion.yOffset, |
310 | 909 | msg->body.motion.xPrecision, | 1044 | msg->body.motion.xPrecision, |
311 | 910 | msg->body.motion.yPrecision, | 1045 | msg->body.motion.yPrecision, |
313 | 911 | msg->body.motion.mac, | 1046 | *(reinterpret_cast<uint64_t*>(msg->body.motion.mac)), |
314 | 912 | std::chrono::nanoseconds(msg->body.motion.downTime), | 1047 | std::chrono::nanoseconds(msg->body.motion.downTime), |
315 | 913 | std::chrono::nanoseconds(msg->body.motion.eventTime), | 1048 | std::chrono::nanoseconds(msg->body.motion.eventTime), |
316 | 914 | pointerCount, | 1049 | pointerCount, |
PASSED: Continuous integration, rev:3159 jenkins. qa.ubuntu. com/job/ mir-ci/ 5778/ jenkins. qa.ubuntu. com/job/ mir-android- vivid-i386- build/5209 jenkins. qa.ubuntu. com/job/ mir-clang- vivid-amd64- build/4115 jenkins. qa.ubuntu. com/job/ mir-mediumtests -vivid- touch/5157 jenkins. qa.ubuntu. com/job/ mir-mediumtests -xenial- touch/104/ console jenkins. qa.ubuntu. com/job/ mir-xenial- amd64-ci/ 107 jenkins. qa.ubuntu. com/job/ mir-xenial- amd64-ci/ 107/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-xenial- i386-ci/ 107 jenkins. qa.ubuntu. com/job/ mir-xenial- i386-ci/ 107/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 5157 jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 5157/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -runner- touch/7687 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 25823 jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- xenial- armhf/102/ console
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ci/5778/ rebuild
http://