• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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