• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.commands.uinput.tests;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 
22 import static org.junit.Assert.fail;
23 
24 import android.platform.test.annotations.Postsubmit;
25 import android.util.SparseArray;
26 
27 import androidx.test.filters.SmallTest;
28 import androidx.test.runner.AndroidJUnit4;
29 
30 import com.android.commands.uinput.EvemuParser;
31 import com.android.commands.uinput.Event;
32 import com.android.commands.uinput.Event.UinputControlCode;
33 
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 
37 import java.io.IOException;
38 import java.io.StringReader;
39 
40 import src.com.android.commands.uinput.InputAbsInfo;
41 
42 @RunWith(AndroidJUnit4.class)
43 @SmallTest
44 @Postsubmit
45 public class EvemuParserTest {
46 
getRegistrationEvent(String fileContents)47     private Event getRegistrationEvent(String fileContents) throws IOException {
48         StringReader reader = new StringReader(fileContents);
49         EvemuParser parser = new EvemuParser(reader);
50         Event event = parser.getNextEvent();
51         assertThat(event.getCommand()).isEqualTo(Event.Command.REGISTER);
52         return event;
53     }
54 
55     @Test
testNameParsing()56     public void testNameParsing() throws IOException {
57         Event event = getRegistrationEvent("""
58                 N: ACME Pointing Widget #4
59                 I: 0001 1234 5678 9abc
60                 """);
61         assertThat(event.getName()).isEqualTo("ACME Pointing Widget #4");
62     }
63 
64     @Test
testIdParsing()65     public void testIdParsing() throws IOException {
66         Event event = getRegistrationEvent("""
67                 N: ACME Pointing Widget #4
68                 I: 0001 1234 5678 9abc
69                 """);
70         assertThat(event.getBus()).isEqualTo(0x0001);
71         assertThat(event.getVendorId()).isEqualTo(0x1234);
72         assertThat(event.getProductId()).isEqualTo(0x5678);
73         assertThat(event.getVersionId()).isEqualTo(0x9abc);
74     }
75 
76     @Test
testPropertyBitmapParsing()77     public void testPropertyBitmapParsing() throws IOException {
78         Event event = getRegistrationEvent("""
79                 N: ACME Pointing Widget #4
80                 I: 0001 1234 5678 9abc
81                 P: 05 00 00 00 00 00 00 00
82                 P: 01
83                 """);
84         assertThat(event.getConfiguration().get(UinputControlCode.UI_SET_PROPBIT.getValue()))
85                 .asList().containsExactly(0, 2, 64);
86     }
87 
88     @Test
testEventBitmapParsing()89     public void testEventBitmapParsing() throws IOException {
90         Event event = getRegistrationEvent("""
91                 N: ACME Pointing Widget #4
92                 I: 0001 1234 5678 9abc
93                 B: 00 0b 00 00 00 00 00 00 00  # SYN
94                 B: 01 00 00 03 00 00 00 00 00  # KEY
95                 B: 01 00 01 00 00 00 00 00 00
96                 B: 02 03 00 00 00 00 00 00 00  # REL
97                 B: 03 00 00                    # ABS
98                 """);
99         assertThat(event.getConfiguration().get(UinputControlCode.UI_SET_EVBIT.getValue()))
100                 .asList().containsExactly(Event.EV_KEY, Event.EV_REL);
101         assertThat(event.getConfiguration().get(UinputControlCode.UI_SET_KEYBIT.getValue()))
102                 .asList().containsExactly(16, 17, 72);
103         assertThat(event.getConfiguration().get(UinputControlCode.UI_SET_RELBIT.getValue()))
104                 .asList().containsExactly(0, 1);
105         assertThat(event.getConfiguration().contains(UinputControlCode.UI_SET_ABSBIT.getValue()))
106                 .isFalse();
107     }
108 
109     @Test
testEventBitmapParsing_WithForceFeedback()110     public void testEventBitmapParsing_WithForceFeedback() throws IOException {
111         Event event = getRegistrationEvent("""
112                 N: ACME Pointing Widget #4
113                 I: 0001 1234 5678 9abc
114                 B: 15 05  # FF
115                 """);
116         assertThat(event.getConfiguration().get(UinputControlCode.UI_SET_EVBIT.getValue()))
117                 .asList().containsExactly(Event.EV_FF);
118         assertThat(event.getConfiguration().get(UinputControlCode.UI_SET_FFBIT.getValue()))
119                 .asList().containsExactly(0, 2);
120         assertThat(event.getFfEffectsMax()).isEqualTo(2);
121     }
122 
assertAbsInfo(InputAbsInfo info, int minimum, int maximum, int fuzz, int flat, int resolution)123     private void assertAbsInfo(InputAbsInfo info, int minimum, int maximum, int fuzz, int flat,
124                                int resolution) {
125         assertThat(info).isNotNull();
126         assertWithMessage("Incorrect minimum").that(info.minimum).isEqualTo(minimum);
127         assertWithMessage("Incorrect maximum").that(info.maximum).isEqualTo(maximum);
128         assertWithMessage("Incorrect fuzz").that(info.fuzz).isEqualTo(fuzz);
129         assertWithMessage("Incorrect flat").that(info.flat).isEqualTo(flat);
130         assertWithMessage("Incorrect resolution").that(info.resolution).isEqualTo(resolution);
131     }
132 
133     @Test
testAbsInfoParsing_WithResolution()134     public void testAbsInfoParsing_WithResolution() throws IOException {
135         Event event = getRegistrationEvent("""
136                 N: ACME Weird Gamepad
137                 I: 0001 1234 5678 9abc
138                 A: 03 -128 128 4 4 0    # ABS_MT_RX
139                 A: 2f 0 9 0 0 0         # ABS_MT_SLOT
140                 A: 34 -4096 4096 0 0 0  # ABS_MT_ORIENTATION
141                 A: 35 0 1599 0 0 11     # ABS_MT_POSITION_X
142                 """);
143         SparseArray<InputAbsInfo> absInfos = event.getAbsInfo();
144         assertThat(absInfos.size()).isEqualTo(4);
145         assertAbsInfo(absInfos.get(0x03), -128, 128, 4, 4, 0);
146         assertAbsInfo(absInfos.get(0x2f), 0, 9, 0, 0, 0);
147         assertAbsInfo(absInfos.get(0x34), -4096, 4096, 0, 0, 0);
148         assertAbsInfo(absInfos.get(0x35), 0, 1599, 0, 0, 11);
149     }
150 
151     @Test
testAbsInfoParsing_WithoutResolution()152     public void testAbsInfoParsing_WithoutResolution() throws IOException {
153         Event event = getRegistrationEvent("""
154                 N: ACME Terrible Touchscreen
155                 I: 0001 1234 5678 9abc
156                 A: 2f 0 9 0 0         # ABS_MT_SLOT
157                 A: 35 0 1599 0 0      # ABS_MT_POSITION_X
158                 A: 36 0 2559 0 0      # ABS_MT_POSITION_X
159                 """);
160         SparseArray<InputAbsInfo> absInfos = event.getAbsInfo();
161         assertThat(absInfos.size()).isEqualTo(3);
162         assertAbsInfo(absInfos.get(0x2f), 0, 9, 0, 0, 0);
163         assertAbsInfo(absInfos.get(0x35), 0, 1599, 0, 0, 0);
164         assertAbsInfo(absInfos.get(0x36), 0, 2559, 0, 0, 0);
165     }
166 
167     @Test
testLedAndSwitchStatesIgnored()168     public void testLedAndSwitchStatesIgnored() throws IOException {
169         // We don't support L: and S: lines yet, so all we need to check here is that they don't
170         // prevent the other events from being parsed.
171         StringReader reader = new StringReader("""
172                 N: ACME Widget
173                 I: 0001 1234 5678 9abc
174                 L: 00 0
175                 L: 09 1
176                 S: 0a 1
177                 E: 0.000001 0 0 0  # SYN_REPORT
178                 """);
179         EvemuParser parser = new EvemuParser(reader);
180         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.REGISTER);
181         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.DELAY);
182         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.INJECT);
183     }
184 
assertInjectEvent(Event event, int eventType, int eventCode, int value)185     private void assertInjectEvent(Event event, int eventType, int eventCode, int value) {
186         assertInjectEvent(event, eventType, eventCode, value, 0);
187     }
188 
assertInjectEvent(Event event, int eventType, int eventCode, int value, long timestampOffsetMicros)189     private void assertInjectEvent(Event event, int eventType, int eventCode, int value,
190                                    long timestampOffsetMicros) {
191         assertThat(event).isNotNull();
192         assertThat(event.getCommand()).isEqualTo(Event.Command.INJECT);
193         assertThat(event.getInjections()).asList()
194                 .containsExactly(eventType, eventCode, value).inOrder();
195         assertThat(event.getTimestampOffsetMicros()).isEqualTo(timestampOffsetMicros);
196     }
197 
assertDelayEvent(Event event, int durationNanos)198     private void assertDelayEvent(Event event, int durationNanos) {
199         assertThat(event).isNotNull();
200         assertThat(event.getCommand()).isEqualTo(Event.Command.DELAY);
201         assertThat(event.getDurationNanos()).isEqualTo(durationNanos);
202     }
203 
204     @Test
testEventParsing_OneFrame()205     public void testEventParsing_OneFrame() throws IOException {
206         StringReader reader = new StringReader("""
207                 N: ACME Widget
208                 I: 0001 1234 5678 9abc
209                 E: 0.000001 0002 0000 0001   # REL_X +1
210                 E: 0.000001 0002 0001 -0002  # REL_Y -2
211                 E: 0.000001 0000 0000 0000   # SYN_REPORT
212                 """);
213         EvemuParser parser = new EvemuParser(reader);
214         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.REGISTER);
215         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.DELAY);
216         assertInjectEvent(parser.getNextEvent(), 0x2, 0x0, 1, -1);
217         assertInjectEvent(parser.getNextEvent(), 0x2, 0x1, -2);
218         assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0);
219     }
220 
221     @Test
testEventParsing_MultipleFrames()222     public void testEventParsing_MultipleFrames() throws IOException {
223         StringReader reader = new StringReader("""
224                 N: ACME YesBird Typing Aid
225                 I: 0001 1234 5678 9abc
226                 E: 0.000001 0001 0015 0001   # KEY_Y press
227                 E: 0.000001 0000 0000 0000   # SYN_REPORT
228                 E: 0.010001 0001 0015 0000   # KEY_Y release
229                 E: 0.010001 0000 0000 0000   # SYN_REPORT
230                 E: 1.010001 0001 0015 0001   # KEY_Y press
231                 E: 1.010001 0000 0000 0000   # SYN_REPORT
232                 """);
233         EvemuParser parser = new EvemuParser(reader);
234         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.REGISTER);
235         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.DELAY);
236 
237         assertInjectEvent(parser.getNextEvent(), 0x1, 0x15, 1, -1);
238         assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0);
239 
240         assertDelayEvent(parser.getNextEvent(), 10_000_000);
241 
242         assertInjectEvent(parser.getNextEvent(), 0x1, 0x15, 0, 10_000);
243         assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0);
244 
245         assertDelayEvent(parser.getNextEvent(), 1_000_000_000);
246 
247         assertInjectEvent(parser.getNextEvent(), 0x1, 0x15, 1, 1_000_000);
248         assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0);
249     }
250 
251     @Test
testErrorLineNumberReporting()252     public void testErrorLineNumberReporting() throws IOException {
253         StringReader reader = new StringReader("""
254                 # EVEMU 1.3
255                 N: ACME Widget
256                 # Comment to make sure they're taken into account when numbering lines
257                 I: 0001 1234 5678 9abc
258                 00 00 00 00 00 00 00 00  # Missing a type
259                 E: 0.000001 0001 0015 0001   # KEY_Y press
260                 E: 0.000001 0000 0000 0000   # SYN_REPORT
261                 """);
262         try {
263             new EvemuParser(reader);
264             fail("Parser should have thrown an error about the line with the missing type.");
265         } catch (EvemuParser.ParsingException ex) {
266             assertThat(ex.makeErrorMessage()).startsWith("Parsing error on line 5:");
267         }
268     }
269 
270     @Test
testFreeDesktopEvemuRecording()271     public void testFreeDesktopEvemuRecording() throws IOException {
272         // This is a real recording from FreeDesktop's evemu-record tool, as a basic compatibility
273         // check with the FreeDesktop tools.
274         // (CheckStyle objects to the long line here. It can be split up with escaped newlines once
275         // the fix for b/306423115 reaches Android.)
276         StringReader reader = new StringReader("""
277                 # EVEMU 1.3
278                 # Kernel: 6.5.6-1rodete4-amd64
279                 # DMI: dmi:bvnLENOVO:bvrXXXXXXXX(X.XX):bdXX/XX/XXXX:brX.XX:efrX.XX:svnLENOVO:pnXXXXXXXXXX:pvrThinkPadX1Carbon:rvnLENOVO:rnXXXXXXXXX:rvrXXXXX:cvnLENOVO:ctXX:cvrNone:skuLENOVO_MT_20KG_BU_Think_FM_ThinkPadX1Carbon:
280                 # Input device name: "Synaptics TM3289-021"
281                 # Input device ID: bus 0x1d vendor 0x6cb product 0000 version 0000
282                 # Size in mm: 96x52
283                 # Supported events:
284                 #   Event type 0 (EV_SYN)
285                 #     Event code 0 (SYN_REPORT)
286                 #     Event code 1 (SYN_CONFIG)
287                 #     Event code 2 (SYN_MT_REPORT)
288                 #     Event code 3 (SYN_DROPPED)
289                 #     Event code 4 ((null))
290                 #     Event code 5 ((null))
291                 #     Event code 6 ((null))
292                 #     Event code 7 ((null))
293                 #     Event code 8 ((null))
294                 #     Event code 9 ((null))
295                 #     Event code 10 ((null))
296                 #     Event code 11 ((null))
297                 #     Event code 12 ((null))
298                 #     Event code 13 ((null))
299                 #     Event code 14 ((null))
300                 #     Event code 15 (SYN_MAX)
301                 #   Event type 1 (EV_KEY)
302                 #     Event code 272 (BTN_LEFT)
303                 #     Event code 325 (BTN_TOOL_FINGER)
304                 #     Event code 328 (BTN_TOOL_QUINTTAP)
305                 #     Event code 330 (BTN_TOUCH)
306                 #     Event code 333 (BTN_TOOL_DOUBLETAP)
307                 #     Event code 334 (BTN_TOOL_TRIPLETAP)
308                 #     Event code 335 (BTN_TOOL_QUADTAP)
309                 #   Event type 3 (EV_ABS)
310                 #     Event code 0 (ABS_X)
311                 #       Value        0
312                 #       Min          0
313                 #       Max       1936
314                 #       Fuzz         0
315                 #       Flat         0
316                 #       Resolution  20
317                 #     Event code 1 (ABS_Y)
318                 #       Value        0
319                 #       Min          0
320                 #       Max       1057
321                 #       Fuzz         0
322                 #       Flat         0
323                 #       Resolution  20
324                 #     Event code 24 (ABS_PRESSURE)
325                 #       Value        0
326                 #       Min          0
327                 #       Max        255
328                 #       Fuzz         0
329                 #       Flat         0
330                 #       Resolution   0
331                 #     Event code 47 (ABS_MT_SLOT)
332                 #       Value        0
333                 #       Min          0
334                 #       Max          4
335                 #       Fuzz         0
336                 #       Flat         0
337                 #       Resolution   0
338                 #     Event code 48 (ABS_MT_TOUCH_MAJOR)
339                 #       Value        0
340                 #       Min          0
341                 #       Max         15
342                 #       Fuzz         0
343                 #       Flat         0
344                 #       Resolution   0
345                 #     Event code 49 (ABS_MT_TOUCH_MINOR)
346                 #       Value        0
347                 #       Min          0
348                 #       Max         15
349                 #       Fuzz         0
350                 #       Flat         0
351                 #       Resolution   0
352                 #     Event code 52 (ABS_MT_ORIENTATION)
353                 #       Value        0
354                 #       Min          0
355                 #       Max          1
356                 #       Fuzz         0
357                 #       Flat         0
358                 #       Resolution   0
359                 #     Event code 53 (ABS_MT_POSITION_X)
360                 #       Value        0
361                 #       Min          0
362                 #       Max       1936
363                 #       Fuzz         0
364                 #       Flat         0
365                 #       Resolution  20
366                 #     Event code 54 (ABS_MT_POSITION_Y)
367                 #       Value        0
368                 #       Min          0
369                 #       Max       1057
370                 #       Fuzz         0
371                 #       Flat         0
372                 #       Resolution  20
373                 #     Event code 55 (ABS_MT_TOOL_TYPE)
374                 #       Value        0
375                 #       Min          0
376                 #       Max         15
377                 #       Fuzz         0
378                 #       Flat         0
379                 #       Resolution   0
380                 #     Event code 57 (ABS_MT_TRACKING_ID)
381                 #       Value        0
382                 #       Min          0
383                 #       Max      65535
384                 #       Fuzz         0
385                 #       Flat         0
386                 #       Resolution   0
387                 #     Event code 58 (ABS_MT_PRESSURE)
388                 #       Value        0
389                 #       Min          0
390                 #       Max        255
391                 #       Fuzz         0
392                 #       Flat         0
393                 #       Resolution   0
394                 # Properties:
395                 #   Property  type 0 (INPUT_PROP_POINTER)
396                 #   Property  type 2 (INPUT_PROP_BUTTONPAD)
397                 N: Synaptics TM3289-021
398                 I: 001d 06cb 0000 0000
399                 P: 05 00 00 00 00 00 00 00
400                 B: 00 0b 00 00 00 00 00 00 00
401                 B: 01 00 00 00 00 00 00 00 00
402                 B: 01 00 00 00 00 00 00 00 00
403                 B: 01 00 00 00 00 00 00 00 00
404                 B: 01 00 00 00 00 00 00 00 00
405                 B: 01 00 00 01 00 00 00 00 00
406                 B: 01 20 e5 00 00 00 00 00 00
407                 B: 01 00 00 00 00 00 00 00 00
408                 B: 01 00 00 00 00 00 00 00 00
409                 B: 01 00 00 00 00 00 00 00 00
410                 B: 01 00 00 00 00 00 00 00 00
411                 B: 01 00 00 00 00 00 00 00 00
412                 B: 01 00 00 00 00 00 00 00 00
413                 B: 02 00 00 00 00 00 00 00 00
414                 B: 03 03 00 00 01 00 80 f3 06
415                 B: 04 00 00 00 00 00 00 00 00
416                 B: 05 00 00 00 00 00 00 00 00
417                 B: 11 00 00 00 00 00 00 00 00
418                 B: 12 00 00 00 00 00 00 00 00
419                 B: 14 00 00 00 00 00 00 00 00
420                 B: 15 00 00 00 00 00 00 00 00
421                 B: 15 00 00 00 00 00 00 00 00
422                 A: 00 0 1936 0 0 20
423                 A: 01 0 1057 0 0 20
424                 A: 18 0 255 0 0 0
425                 A: 2f 0 4 0 0 0
426                 A: 30 0 15 0 0 0
427                 A: 31 0 15 0 0 0
428                 A: 34 0 1 0 0 0
429                 A: 35 0 1936 0 0 20
430                 A: 36 0 1057 0 0 20
431                 A: 37 0 15 0 0 0
432                 A: 39 0 65535 0 0 0
433                 A: 3a 0 255 0 0 0
434                 ################################
435                 #      Waiting for events      #
436                 ################################
437                 E: 0.000001 0003 0039 0000\t# EV_ABS / ABS_MT_TRACKING_ID   0
438                 E: 0.000001 0003 0035 0891\t# EV_ABS / ABS_MT_POSITION_X    891
439                 E: 0.000001 0003 0036 0333\t# EV_ABS / ABS_MT_POSITION_Y    333
440                 E: 0.000001 0003 003a 0056\t# EV_ABS / ABS_MT_PRESSURE      56
441                 E: 0.000001 0003 0030 0001\t# EV_ABS / ABS_MT_TOUCH_MAJOR   1
442                 E: 0.000001 0003 0031 0001\t# EV_ABS / ABS_MT_TOUCH_MINOR   1
443                 E: 0.000001 0001 014a 0001\t# EV_KEY / BTN_TOUCH            1
444                 E: 0.000001 0001 0145 0001\t# EV_KEY / BTN_TOOL_FINGER      1
445                 E: 0.000001 0003 0000 0891\t# EV_ABS / ABS_X                891
446                 E: 0.000001 0003 0001 0333\t# EV_ABS / ABS_Y                333
447                 E: 0.000001 0003 0018 0056\t# EV_ABS / ABS_PRESSURE         56
448                 E: 0.000001 0000 0000 0000\t# ------------ SYN_REPORT (0) ---------- +0ms
449                 E: 0.006081 0003 0035 0888\t# EV_ABS / ABS_MT_POSITION_X    888
450                 """);
451         EvemuParser parser = new EvemuParser(reader);
452         Event regEvent = parser.getNextEvent();
453         assertThat(regEvent.getName()).isEqualTo("Synaptics TM3289-021");
454 
455         assertThat(regEvent.getBus()).isEqualTo(0x001d);
456         assertThat(regEvent.getVendorId()).isEqualTo(0x6cb);
457         assertThat(regEvent.getProductId()).isEqualTo(0x0000);
458         assertThat(regEvent.getVersionId()).isEqualTo(0x0000);
459 
460         assertThat(regEvent.getConfiguration().get(UinputControlCode.UI_SET_PROPBIT.getValue()))
461                 .asList().containsExactly(0, 2);
462 
463         assertThat(regEvent.getConfiguration().get(UinputControlCode.UI_SET_EVBIT.getValue()))
464                 .asList().containsExactly(Event.EV_KEY, Event.EV_ABS);
465         assertThat(regEvent.getConfiguration().get(UinputControlCode.UI_SET_KEYBIT.getValue()))
466                 .asList().containsExactly(272, 325, 328, 330, 333, 334, 335);
467         assertThat(regEvent.getConfiguration().get(UinputControlCode.UI_SET_ABSBIT.getValue()))
468                 .asList().containsExactly(0, 1, 24, 47, 48, 49, 52, 53, 54, 55, 57, 58);
469 
470         SparseArray<InputAbsInfo> absInfos = regEvent.getAbsInfo();
471         assertAbsInfo(absInfos.get(0), 0, 1936, 0, 0, 20);
472         assertAbsInfo(absInfos.get(1), 0, 1057, 0, 0, 20);
473         assertAbsInfo(absInfos.get(24), 0, 255, 0, 0, 0);
474         assertAbsInfo(absInfos.get(47), 0, 4, 0, 0, 0);
475         assertAbsInfo(absInfos.get(48), 0, 15, 0, 0, 0);
476         assertAbsInfo(absInfos.get(49), 0, 15, 0, 0, 0);
477         assertAbsInfo(absInfos.get(52), 0, 1, 0, 0, 0);
478         assertAbsInfo(absInfos.get(53), 0, 1936, 0, 0, 20);
479         assertAbsInfo(absInfos.get(54), 0, 1057, 0, 0, 20);
480         assertAbsInfo(absInfos.get(55), 0, 15, 0, 0, 0);
481         assertAbsInfo(absInfos.get(57), 0, 65535, 0, 0, 0);
482         assertAbsInfo(absInfos.get(58), 0, 255, 0, 0, 0);
483 
484         assertThat(parser.getNextEvent().getCommand()).isEqualTo(Event.Command.DELAY);
485 
486         assertInjectEvent(parser.getNextEvent(), 0x3, 0x39, 0, -1);
487         assertInjectEvent(parser.getNextEvent(), 0x3, 0x35, 891);
488         assertInjectEvent(parser.getNextEvent(), 0x3, 0x36, 333);
489         assertInjectEvent(parser.getNextEvent(), 0x3, 0x3a, 56);
490         assertInjectEvent(parser.getNextEvent(), 0x3, 0x30, 1);
491         assertInjectEvent(parser.getNextEvent(), 0x3, 0x31, 1);
492         assertInjectEvent(parser.getNextEvent(), 0x1, 0x14a, 1);
493         assertInjectEvent(parser.getNextEvent(), 0x1, 0x145, 1);
494         assertInjectEvent(parser.getNextEvent(), 0x3, 0x0, 891);
495         assertInjectEvent(parser.getNextEvent(), 0x3, 0x1, 333);
496         assertInjectEvent(parser.getNextEvent(), 0x3, 0x18, 56);
497         assertInjectEvent(parser.getNextEvent(), 0x0, 0x0, 0);
498 
499         assertDelayEvent(parser.getNextEvent(), 6_080_000);
500 
501         assertInjectEvent(parser.getNextEvent(), 0x3, 0x0035, 888, 6_080);
502     }
503 }
504