1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com>
4 * Copyright (C) 2024 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
5 */
6
7 /*\
8 * [Description]
9 *
10 * Verify that auto-repeat is working on a virtual device, that in our case
11 * it's a keyboard.
12 */
13
14 #include <linux/uinput.h>
15
16 #include "input_common.h"
17
18 struct input_event events[64];
19 static int num_events;
20 static int ev_iter;
21 static int fd_send = -1;
22 static int fd_recv = -1;
23
send_events(void)24 static void send_events(void)
25 {
26 send_event(fd_send, EV_KEY, KEY_X, 1);
27 send_event(fd_send, EV_SYN, 0, 0);
28
29 /*
30 * Sleep long enough to keep the key pressed for some time
31 * (auto-repeat). Default kernel delay to start auto-repeat is 250ms
32 * and the period is 33ms. So, we wait for a generous 500ms to make
33 * sure we get the auto-repeated keys
34 */
35 usleep(500000);
36
37 send_event(fd_send, EV_KEY, KEY_X, 0);
38 send_event(fd_send, EV_SYN, 0, 0);
39 }
40
check_event(struct input_event * iev,int event,int code,int value)41 static int check_event(struct input_event *iev, int event, int code, int value)
42 {
43 return iev->type == event && iev->code == code && iev->value == value;
44 }
45
read_events(void)46 static void read_events(void)
47 {
48 int num_bytes = SAFE_READ(0, fd_recv, events, sizeof(events));
49
50 if (!num_bytes)
51 tst_brk(TBROK, "Failed to read events");
52
53 if (num_bytes % sizeof(struct input_event) != 0) {
54 tst_brk(TBROK, "Read size %i is not multiple of %zu",
55 num_bytes, sizeof(struct input_event));
56 }
57
58 ev_iter = 0;
59 num_events = num_bytes / sizeof(struct input_event);
60 }
61
have_events(void)62 static int have_events(void)
63 {
64 return num_events && ev_iter < num_events;
65 }
66
next_event(void)67 static struct input_event *next_event(void)
68 {
69 if (!have_events())
70 read_events();
71
72 return &events[ev_iter++];
73 }
74
check_event_code(struct input_event * iev,int event,int code)75 static int check_event_code(struct input_event *iev, int event, int code)
76 {
77 return iev->type == event && iev->code == code;
78 }
79
parse_autorepeat_config(struct input_event * iev)80 static int parse_autorepeat_config(struct input_event *iev)
81 {
82 if (!check_event_code(iev, EV_REP, REP_DELAY)) {
83 tst_res(TFAIL, "Didn't get EV_REP type with REP_DELAY code");
84 return 0;
85 }
86
87 if (!check_event_code(next_event(), EV_REP, REP_PERIOD)) {
88 tst_res(TFAIL, "Didn't get EV_REP type with REP_PERIOD code");
89 return 0;
90 }
91
92 return 1;
93 }
94
check_sync_event(struct input_event * iev)95 static int check_sync_event(struct input_event *iev)
96 {
97 return check_event_code(iev, EV_SYN, SYN_REPORT);
98 }
99
parse_key(struct input_event * iev)100 static int parse_key(struct input_event *iev)
101 {
102 int autorep_count = 0;
103
104 if (!check_event(iev, EV_KEY, KEY_X, 1) || !check_sync_event(next_event())) {
105 tst_res(TFAIL, "Didn't get expected key press for KEY_X");
106 return 0;
107 }
108
109 iev = next_event();
110 while (check_event(iev, EV_KEY, KEY_X, 2) && check_sync_event(next_event())) {
111 autorep_count++;
112 iev = next_event();
113 }
114
115 /* make sure we have at least one auto-repeated key event */
116 if (!autorep_count) {
117 tst_res(TFAIL, "Didn't get autorepeat events for the key - KEY_X");
118 return 0;
119 }
120
121 if (!check_event(iev, EV_KEY, KEY_X, 0) || !check_sync_event(next_event())) {
122 tst_res(TFAIL, "Didn't get expected key release for KEY_X");
123 return 0;
124 }
125
126 tst_res(TINFO, "Received %d repetitions for KEY_X", autorep_count);
127
128 return 1;
129 }
130
check_events(void)131 static int check_events(void)
132 {
133 struct input_event *iev;
134 int ret = 0;
135 int rep_config_done = 0;
136 int rep_keys_done = 0;
137
138 read_events();
139
140 while (have_events()) {
141 iev = next_event();
142 switch (iev->type) {
143 case EV_REP:
144 ret = parse_autorepeat_config(iev);
145 rep_config_done = 1;
146 break;
147 case EV_KEY:
148 ret = parse_key(iev);
149 rep_keys_done = 1;
150 break;
151 default:
152 tst_res(TFAIL, "Unexpected event type '0x%04x' received",
153 iev->type);
154 ret = 0;
155 break;
156 }
157
158 if (!ret || (rep_config_done && rep_keys_done))
159 break;
160 }
161
162 return ret;
163 }
164
run(void)165 static void run(void)
166 {
167 if (!SAFE_FORK()) {
168 send_events();
169 exit(0);
170 }
171
172 if (!check_events())
173 tst_res(TFAIL, "Wrong data received from input device");
174 else
175 tst_res(TPASS, "Data received from input device");
176 }
177
setup(void)178 static void setup(void)
179 {
180 fd_send = open_uinput();
181 if (fd_send == -1)
182 tst_brk(TCONF, "Virtual device is not available");
183
184 SAFE_IOCTL(fd_send, UI_SET_EVBIT, EV_KEY);
185 SAFE_IOCTL(fd_send, UI_SET_EVBIT, EV_REP);
186 SAFE_IOCTL(fd_send, UI_SET_KEYBIT, KEY_X);
187
188 create_input_device(fd_send);
189
190 fd_recv = open_event_device();
191 SAFE_IOCTL(fd_recv, EVIOCGRAB, 1);
192 }
193
cleanup(void)194 static void cleanup(void)
195 {
196 if (fd_send != -1)
197 destroy_input_device(fd_send);
198
199 if (fd_recv != -1)
200 SAFE_CLOSE(fd_recv);
201 }
202
203 static struct tst_test test = {
204 .test_all = run,
205 .setup = setup,
206 .cleanup = cleanup,
207 .needs_root = 1,
208 .forks_child = 1,
209 };
210