1 /*
2 * Copyright © 2013 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <config.h>
25
26 #include <check.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <libinput.h>
30 #include <libinput-util.h>
31 #include <libudev.h>
32 #include <unistd.h>
33
34 #include "litest.h"
35
open_restricted(const char * path,int flags,void * data)36 static int open_restricted(const char *path, int flags, void *data)
37 {
38 int fd;
39 fd = open(path, flags);
40 return fd < 0 ? -errno : fd;
41 }
close_restricted(int fd,void * data)42 static void close_restricted(int fd, void *data)
43 {
44 close(fd);
45 }
46
47 static const struct libinput_interface simple_interface = {
48 .open_restricted = open_restricted,
49 .close_restricted = close_restricted,
50 };
51
START_TEST(udev_create_NULL)52 START_TEST(udev_create_NULL)
53 {
54 struct libinput *li;
55 struct udev *udev;
56
57 udev = udev_new();
58
59 li = libinput_udev_create_context(NULL, NULL, NULL);
60 ck_assert(li == NULL);
61
62 li = libinput_udev_create_context(&simple_interface, NULL, NULL);
63 ck_assert(li == NULL);
64
65 li = libinput_udev_create_context(NULL, NULL, udev);
66 ck_assert(li == NULL);
67
68 li = libinput_udev_create_context(&simple_interface, NULL, udev);
69 ck_assert_notnull(li);
70 ck_assert_int_eq(libinput_udev_assign_seat(li, NULL), -1);
71
72 libinput_unref(li);
73 udev_unref(udev);
74 }
75 END_TEST
76
START_TEST(udev_create_seat0)77 START_TEST(udev_create_seat0)
78 {
79 struct libinput *li;
80 struct libinput_event *event;
81 struct udev *udev;
82 int fd;
83
84 udev = udev_new();
85 ck_assert_notnull(udev);
86
87 li = libinput_udev_create_context(&simple_interface, NULL, udev);
88 ck_assert_notnull(li);
89 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
90
91 fd = libinput_get_fd(li);
92 ck_assert_int_ge(fd, 0);
93
94 /* expect at least one event */
95 libinput_dispatch(li);
96 event = libinput_get_event(li);
97 ck_assert_notnull(event);
98
99 libinput_event_destroy(event);
100 libinput_unref(li);
101 udev_unref(udev);
102 }
103 END_TEST
104
START_TEST(udev_create_empty_seat)105 START_TEST(udev_create_empty_seat)
106 {
107 struct libinput *li;
108 struct libinput_event *event;
109 struct udev *udev;
110 int fd;
111
112 udev = udev_new();
113 ck_assert_notnull(udev);
114
115 /* expect a libinput reference, but no events */
116 li = libinput_udev_create_context(&simple_interface, NULL, udev);
117 ck_assert_notnull(li);
118 ck_assert_int_eq(libinput_udev_assign_seat(li, "seatdoesntexist"), 0);
119
120 fd = libinput_get_fd(li);
121 ck_assert_int_ge(fd, 0);
122
123 libinput_dispatch(li);
124 event = libinput_get_event(li);
125 ck_assert(event == NULL);
126
127 libinput_event_destroy(event);
128 libinput_unref(li);
129 udev_unref(udev);
130 }
131 END_TEST
132
START_TEST(udev_create_seat_too_long)133 START_TEST(udev_create_seat_too_long)
134 {
135 struct libinput *li;
136 struct udev *udev;
137 char seatname[258];
138
139 memset(seatname, 'a', sizeof(seatname) - 1);
140 seatname[sizeof(seatname) - 1] = '\0';
141
142 udev = udev_new();
143 ck_assert_notnull(udev);
144
145 li = libinput_udev_create_context(&simple_interface, NULL, udev);
146 ck_assert_notnull(li);
147 litest_set_log_handler_bug(li);
148
149 ck_assert_int_eq(libinput_udev_assign_seat(li, seatname), -1);
150
151 litest_assert_empty_queue(li);
152
153 libinput_unref(li);
154 udev_unref(udev);
155 }
156 END_TEST
157
START_TEST(udev_set_user_data)158 START_TEST(udev_set_user_data)
159 {
160 struct libinput *li;
161 struct udev *udev;
162 int data1, data2;
163
164 udev = udev_new();
165 ck_assert_notnull(udev);
166
167 li = libinput_udev_create_context(&simple_interface, &data1, udev);
168 ck_assert_notnull(li);
169 ck_assert(libinput_get_user_data(li) == &data1);
170 libinput_set_user_data(li, &data2);
171 ck_assert(libinput_get_user_data(li) == &data2);
172
173 libinput_unref(li);
174 udev_unref(udev);
175 }
176 END_TEST
177
178 /**
179 * This test only works if there's at least one device in the system that is
180 * assigned the default seat. Should cover the 99% case.
181 */
START_TEST(udev_added_seat_default)182 START_TEST(udev_added_seat_default)
183 {
184 struct libinput *li;
185 struct libinput_event *event;
186 struct udev *udev;
187 struct libinput_device *device;
188 struct libinput_seat *seat;
189 const char *seat_name;
190 enum libinput_event_type type;
191 int default_seat_found = 0;
192
193 udev = udev_new();
194 ck_assert_notnull(udev);
195
196 li = libinput_udev_create_context(&simple_interface, NULL, udev);
197 ck_assert_notnull(li);
198 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
199 libinput_dispatch(li);
200
201 while (!default_seat_found && (event = libinput_get_event(li))) {
202 type = libinput_event_get_type(event);
203 if (type != LIBINPUT_EVENT_DEVICE_ADDED) {
204 libinput_event_destroy(event);
205 continue;
206 }
207
208 device = libinput_event_get_device(event);
209 seat = libinput_device_get_seat(device);
210 ck_assert_notnull(seat);
211
212 seat_name = libinput_seat_get_logical_name(seat);
213 default_seat_found = streq(seat_name, "default");
214 libinput_event_destroy(event);
215 }
216
217 ck_assert(default_seat_found);
218
219 libinput_unref(li);
220 udev_unref(udev);
221 }
222 END_TEST
223
224 /**
225 * This test only works if there's at least one device in the system that is
226 * assigned the default seat. Should cover the 99% case.
227 */
START_TEST(udev_change_seat)228 START_TEST(udev_change_seat)
229 {
230 struct libinput *li;
231 struct udev *udev;
232 struct libinput_event *event;
233 struct libinput_device *device;
234 struct libinput_seat *seat1, *seat2;
235 const char *seat1_name;
236 const char *seat2_name = "new seat";
237 int rc;
238
239 udev = udev_new();
240 ck_assert_notnull(udev);
241
242 li = libinput_udev_create_context(&simple_interface, NULL, udev);
243 ck_assert_notnull(li);
244 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
245 libinput_dispatch(li);
246
247 event = libinput_get_event(li);
248 ck_assert_notnull(event);
249
250 ck_assert_int_eq(libinput_event_get_type(event),
251 LIBINPUT_EVENT_DEVICE_ADDED);
252
253 device = libinput_event_get_device(event);
254 libinput_device_ref(device);
255
256 seat1 = libinput_device_get_seat(device);
257 libinput_seat_ref(seat1);
258
259 seat1_name = libinput_seat_get_logical_name(seat1);
260 libinput_event_destroy(event);
261
262 litest_drain_events(li);
263
264 rc = libinput_device_set_seat_logical_name(device,
265 seat2_name);
266 ck_assert_int_eq(rc, 0);
267
268 libinput_dispatch(li);
269
270 event = libinput_get_event(li);
271 ck_assert_int_eq(libinput_event_get_type(event),
272 LIBINPUT_EVENT_DEVICE_REMOVED);
273
274 ck_assert(libinput_event_get_device(event) == device);
275 libinput_event_destroy(event);
276
277 event = libinput_get_event(li);
278 ck_assert_int_eq(libinput_event_get_type(event),
279 LIBINPUT_EVENT_DEVICE_ADDED);
280 ck_assert(libinput_event_get_device(event) != device);
281 libinput_device_unref(device);
282
283 device = libinput_event_get_device(event);
284 seat2 = libinput_device_get_seat(device);
285
286 ck_assert_str_ne(libinput_seat_get_logical_name(seat2),
287 seat1_name);
288 ck_assert_str_eq(libinput_seat_get_logical_name(seat2),
289 seat2_name);
290 libinput_event_destroy(event);
291
292 libinput_seat_unref(seat1);
293
294 libinput_unref(li);
295 udev_unref(udev);
296 }
297 END_TEST
298
START_TEST(udev_double_suspend)299 START_TEST(udev_double_suspend)
300 {
301 struct libinput *li;
302 struct libinput_event *event;
303 struct udev *udev;
304 int fd;
305
306 udev = udev_new();
307 ck_assert_notnull(udev);
308
309 li = libinput_udev_create_context(&simple_interface, NULL, udev);
310 ck_assert_notnull(li);
311 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
312
313 fd = libinput_get_fd(li);
314 ck_assert_int_ge(fd, 0);
315
316 /* expect at least one event */
317 ck_assert_int_ge(libinput_dispatch(li), 0);
318 event = libinput_get_event(li);
319 ck_assert_notnull(event);
320
321 libinput_suspend(li);
322 libinput_suspend(li);
323 libinput_resume(li);
324
325 libinput_event_destroy(event);
326 libinput_unref(li);
327 udev_unref(udev);
328 }
329 END_TEST
330
START_TEST(udev_double_resume)331 START_TEST(udev_double_resume)
332 {
333 struct libinput *li;
334 struct libinput_event *event;
335 struct udev *udev;
336 int fd;
337
338 udev = udev_new();
339 ck_assert_notnull(udev);
340
341 li = libinput_udev_create_context(&simple_interface, NULL, udev);
342 ck_assert_notnull(li);
343 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
344
345 fd = libinput_get_fd(li);
346 ck_assert_int_ge(fd, 0);
347
348 /* expect at least one event */
349 ck_assert_int_ge(libinput_dispatch(li), 0);
350 event = libinput_get_event(li);
351 ck_assert_notnull(event);
352
353 libinput_suspend(li);
354 libinput_resume(li);
355 libinput_resume(li);
356
357 libinput_event_destroy(event);
358 libinput_unref(li);
359 udev_unref(udev);
360 }
361 END_TEST
362
363 static void
process_events_count_devices(struct libinput * li,int * device_count)364 process_events_count_devices(struct libinput *li, int *device_count)
365 {
366 struct libinput_event *event;
367
368 while ((event = libinput_get_event(li))) {
369 switch (libinput_event_get_type(event)) {
370 case LIBINPUT_EVENT_DEVICE_ADDED:
371 (*device_count)++;
372 break;
373 case LIBINPUT_EVENT_DEVICE_REMOVED:
374 (*device_count)--;
375 break;
376 default:
377 break;
378 }
379 libinput_event_destroy(event);
380 }
381 }
382
START_TEST(udev_suspend_resume)383 START_TEST(udev_suspend_resume)
384 {
385 struct libinput *li;
386 struct udev *udev;
387 int fd;
388 int num_devices = 0;
389
390 udev = udev_new();
391 ck_assert_notnull(udev);
392
393 li = libinput_udev_create_context(&simple_interface, NULL, udev);
394 ck_assert_notnull(li);
395 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
396
397 fd = libinput_get_fd(li);
398 ck_assert_int_ge(fd, 0);
399
400 /* Check that at least one device was discovered after creation. */
401 ck_assert_int_ge(libinput_dispatch(li), 0);
402 process_events_count_devices(li, &num_devices);
403 ck_assert_int_gt(num_devices, 0);
404
405 /* Check that after a suspend, no devices are left. */
406 libinput_suspend(li);
407 ck_assert_int_ge(libinput_dispatch(li), 0);
408 process_events_count_devices(li, &num_devices);
409 ck_assert_int_eq(num_devices, 0);
410
411 /* Check that after a resume, at least one device is discovered. */
412 libinput_resume(li);
413 ck_assert_int_ge(libinput_dispatch(li), 0);
414 process_events_count_devices(li, &num_devices);
415 ck_assert_int_gt(num_devices, 0);
416
417 libinput_unref(li);
418 udev_unref(udev);
419 }
420 END_TEST
421
START_TEST(udev_resume_before_seat)422 START_TEST(udev_resume_before_seat)
423 {
424 struct libinput *li;
425 struct udev *udev;
426 int rc;
427
428 udev = udev_new();
429 ck_assert_notnull(udev);
430
431 li = libinput_udev_create_context(&simple_interface, NULL, udev);
432 ck_assert_notnull(li);
433
434 rc = libinput_resume(li);
435 ck_assert_int_eq(rc, 0);
436
437 libinput_unref(li);
438 udev_unref(udev);
439 }
440 END_TEST
441
START_TEST(udev_suspend_resume_before_seat)442 START_TEST(udev_suspend_resume_before_seat)
443 {
444 struct libinput *li;
445 struct udev *udev;
446 int rc;
447
448 udev = udev_new();
449 ck_assert_notnull(udev);
450
451 li = libinput_udev_create_context(&simple_interface, NULL, udev);
452 ck_assert_notnull(li);
453
454 libinput_suspend(li);
455 rc = libinput_resume(li);
456 ck_assert_int_eq(rc, 0);
457
458 libinput_unref(li);
459 udev_unref(udev);
460 }
461 END_TEST
462
START_TEST(udev_device_sysname)463 START_TEST(udev_device_sysname)
464 {
465 struct libinput *li;
466 struct libinput_event *ev;
467 struct libinput_device *device;
468 const char *sysname;
469 struct udev *udev;
470
471 udev = udev_new();
472 ck_assert_notnull(udev);
473
474 li = libinput_udev_create_context(&simple_interface, NULL, udev);
475 ck_assert_notnull(li);
476 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
477
478 libinput_dispatch(li);
479
480 while ((ev = libinput_get_event(li))) {
481 if (libinput_event_get_type(ev) !=
482 LIBINPUT_EVENT_DEVICE_ADDED) {
483 libinput_event_destroy(ev);
484 continue;
485 }
486
487 device = libinput_event_get_device(ev);
488 sysname = libinput_device_get_sysname(device);
489 ck_assert_notnull(sysname);
490 ck_assert_int_gt(strlen(sysname), 1);
491 ck_assert(strchr(sysname, '/') == NULL);
492 ck_assert_int_eq(strncmp(sysname, "event", 5), 0);
493 libinput_event_destroy(ev);
494 }
495
496 libinput_unref(li);
497 udev_unref(udev);
498 }
499 END_TEST
500
START_TEST(udev_seat_recycle)501 START_TEST(udev_seat_recycle)
502 {
503 struct udev *udev;
504 struct libinput *li;
505 struct libinput_event *ev;
506 struct libinput_device *device;
507 struct libinput_seat *saved_seat = NULL;
508 struct libinput_seat *seat;
509 int data = 0;
510 int found = 0;
511 void *user_data;
512
513 udev = udev_new();
514 ck_assert_notnull(udev);
515
516 li = libinput_udev_create_context(&simple_interface, NULL, udev);
517 ck_assert_notnull(li);
518 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
519
520 libinput_dispatch(li);
521 while ((ev = libinput_get_event(li))) {
522 switch (libinput_event_get_type(ev)) {
523 case LIBINPUT_EVENT_DEVICE_ADDED:
524 if (saved_seat)
525 break;
526
527 device = libinput_event_get_device(ev);
528 ck_assert_notnull(device);
529 saved_seat = libinput_device_get_seat(device);
530 libinput_seat_set_user_data(saved_seat, &data);
531 libinput_seat_ref(saved_seat);
532 break;
533 default:
534 break;
535 }
536
537 libinput_event_destroy(ev);
538 }
539
540 ck_assert_notnull(saved_seat);
541
542 libinput_suspend(li);
543
544 litest_drain_events(li);
545
546 libinput_resume(li);
547
548 libinput_dispatch(li);
549 while ((ev = libinput_get_event(li))) {
550 switch (libinput_event_get_type(ev)) {
551 case LIBINPUT_EVENT_DEVICE_ADDED:
552 device = libinput_event_get_device(ev);
553 ck_assert_notnull(device);
554
555 seat = libinput_device_get_seat(device);
556 user_data = libinput_seat_get_user_data(seat);
557 if (user_data == &data) {
558 found = 1;
559 ck_assert(seat == saved_seat);
560 }
561 break;
562 default:
563 break;
564 }
565
566 libinput_event_destroy(ev);
567 }
568
569 ck_assert(found == 1);
570
571 libinput_unref(li);
572 udev_unref(udev);
573 }
574 END_TEST
575
START_TEST(udev_path_add_device)576 START_TEST(udev_path_add_device)
577 {
578 struct udev *udev;
579 struct libinput *li;
580 struct libinput_device *device;
581
582 udev = udev_new();
583 ck_assert_notnull(udev);
584
585 li = libinput_udev_create_context(&simple_interface, NULL, udev);
586 ck_assert_notnull(li);
587 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
588
589 litest_set_log_handler_bug(li);
590 device = libinput_path_add_device(li, "/dev/input/event0");
591 ck_assert(device == NULL);
592 litest_restore_log_handler(li);
593
594 libinput_unref(li);
595 udev_unref(udev);
596 }
597 END_TEST
598
START_TEST(udev_path_remove_device)599 START_TEST(udev_path_remove_device)
600 {
601 struct udev *udev;
602 struct libinput *li;
603 struct libinput_device *device;
604 struct libinput_event *event;
605
606 udev = udev_new();
607 ck_assert_notnull(udev);
608
609 li = libinput_udev_create_context(&simple_interface, NULL, udev);
610 ck_assert_notnull(li);
611 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
612 libinput_dispatch(li);
613
614 litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED, -1);
615 event = libinput_get_event(li);
616 device = libinput_event_get_device(event);
617 ck_assert_notnull(device);
618
619 /* no effect bug a bug log msg */
620 litest_set_log_handler_bug(li);
621 libinput_path_remove_device(device);
622 litest_restore_log_handler(li);
623
624 libinput_event_destroy(event);
625 libinput_unref(li);
626 udev_unref(udev);
627 }
628 END_TEST
629
START_TEST(udev_ignore_device)630 START_TEST(udev_ignore_device)
631 {
632 struct udev *udev;
633 struct libinput *li;
634 struct libinput_device *device;
635 struct libinput_event *event;
636 struct litest_device *dev;
637 const char *devname;
638
639 dev = litest_create(LITEST_IGNORED_MOUSE, NULL, NULL, NULL, NULL);
640 devname = libevdev_get_name(dev->evdev);
641
642 udev = udev_new();
643 ck_assert_notnull(udev);
644
645 li = libinput_udev_create_context(&simple_interface, NULL, udev);
646 ck_assert_notnull(li);
647 litest_restore_log_handler(li);
648
649 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
650 libinput_dispatch(li);
651
652 event = libinput_get_event(li);
653 ck_assert_notnull(event);
654 while (event) {
655 if (libinput_event_get_type(event) ==
656 LIBINPUT_EVENT_DEVICE_ADDED) {
657 const char *name;
658
659 device = libinput_event_get_device(event);
660 name = libinput_device_get_name(device);
661 ck_assert_str_ne(devname, name);
662 }
663 libinput_event_destroy(event);
664 libinput_dispatch(li);
665 event = libinput_get_event(li);
666 }
667
668 libinput_unref(li);
669 udev_unref(udev);
670
671 litest_delete_device(dev);
672 }
673 END_TEST
674
TEST_COLLECTION(udev)675 TEST_COLLECTION(udev)
676 {
677 litest_add_no_device("udev:create", udev_create_NULL);
678 litest_add_no_device("udev:create", udev_create_seat0);
679 litest_add_no_device("udev:create", udev_create_empty_seat);
680 litest_add_no_device("udev:create", udev_create_seat_too_long);
681 litest_add_no_device("udev:create", udev_set_user_data);
682
683 litest_add_no_device("udev:seat", udev_added_seat_default);
684 litest_add_no_device("udev:seat", udev_change_seat);
685
686 litest_add_for_device("udev:suspend", udev_double_suspend, LITEST_SYNAPTICS_CLICKPAD_X220);
687 litest_add_for_device("udev:suspend", udev_double_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
688 litest_add_for_device("udev:suspend", udev_suspend_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
689 litest_add_for_device("udev:suspend", udev_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
690 litest_add_for_device("udev:suspend", udev_suspend_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
691 litest_add_for_device("udev:device events", udev_device_sysname, LITEST_SYNAPTICS_CLICKPAD_X220);
692 litest_add_for_device("udev:seat", udev_seat_recycle, LITEST_SYNAPTICS_CLICKPAD_X220);
693
694 litest_add_no_device("udev:path", udev_path_add_device);
695 litest_add_for_device("udev:path", udev_path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
696
697 litest_add_no_device("udev:ignore", udev_ignore_device);
698 }
699