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_TESTnull52 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_TESTnull77 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_TESTnull105 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_TESTnull133 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_TESTnull158 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
START_TESTnull178 START_TEST(udev_added_seat_default)
179 {
180 struct libinput *li;
181 struct libinput_event *event;
182 struct udev *udev;
183 struct libinput_device *device;
184 struct libinput_seat *seat;
185 const char *seat_name;
186 struct litest_device *dev;
187
188 udev = udev_new();
189 ck_assert_notnull(udev);
190
191 li = libinput_udev_create_context(&simple_interface, NULL, udev);
192 ck_assert_notnull(li);
193 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
194 libinput_dispatch(li);
195
196 /* Drop any events from other devices */
197 litest_drain_events(li);
198
199 /* Now create our own device, it should be in the "default"
200 * logical seat. This test may fail if there is a local rule changing
201 * that, but it'll be fine for the 99% case. */
202 dev = litest_create(LITEST_MOUSE, NULL, NULL, NULL, NULL);
203 litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED, -1);
204 event = libinput_get_event(li);
205 device = libinput_event_get_device(event);
206 seat = libinput_device_get_seat(device);
207 ck_assert_notnull(seat);
208
209 seat_name = libinput_seat_get_logical_name(seat);
210 ck_assert_str_eq(seat_name, "default");
211 libinput_event_destroy(event);
212
213 libinput_unref(li);
214 udev_unref(udev);
215
216 litest_delete_device(dev);
217 }
218 END_TEST
219
START_TESTnull220 START_TEST(udev_change_seat)
221 {
222 struct libinput *li;
223 struct udev *udev;
224 struct libinput_event *event;
225 struct libinput_device *device;
226 struct libinput_seat *seat1, *seat2;
227 const char *seat1_name;
228 const char *seat2_name = "new seat";
229 int rc;
230 struct litest_device *dev;
231
232 udev = udev_new();
233 ck_assert_notnull(udev);
234
235 li = libinput_udev_create_context(&simple_interface, NULL, udev);
236 ck_assert_notnull(li);
237 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
238 libinput_dispatch(li);
239
240 /* Drop any events from other devices */
241 litest_drain_events(li);
242
243 /* Now create our own device, it should be in the "default"
244 * logical seat. This test may fail if there is a local rule changing
245 * that, but it'll be fine for the 99% case. */
246 dev = litest_create(LITEST_MOUSE, NULL, NULL, NULL, NULL);
247 litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED, -1);
248 event = libinput_get_event(li);
249 device = libinput_event_get_device(event);
250 libinput_device_ref(device);
251
252 seat1 = libinput_device_get_seat(device);
253 libinput_seat_ref(seat1);
254
255 seat1_name = libinput_seat_get_logical_name(seat1);
256 libinput_event_destroy(event);
257
258 litest_drain_events(li);
259
260 /* Changing the logical seat name will remove and re-add the device */
261 rc = libinput_device_set_seat_logical_name(device,
262 seat2_name);
263 ck_assert_int_eq(rc, 0);
264
265 libinput_dispatch(li);
266
267 event = libinput_get_event(li);
268 ck_assert_int_eq(libinput_event_get_type(event),
269 LIBINPUT_EVENT_DEVICE_REMOVED);
270
271 ck_assert(libinput_event_get_device(event) == device);
272 libinput_event_destroy(event);
273
274 event = libinput_get_event(li);
275 ck_assert_int_eq(libinput_event_get_type(event),
276 LIBINPUT_EVENT_DEVICE_ADDED);
277 ck_assert(libinput_event_get_device(event) != device);
278 libinput_device_unref(device);
279
280 device = libinput_event_get_device(event);
281 seat2 = libinput_device_get_seat(device);
282
283 ck_assert_str_ne(libinput_seat_get_logical_name(seat2),
284 seat1_name);
285 ck_assert_str_eq(libinput_seat_get_logical_name(seat2),
286 seat2_name);
287 libinput_event_destroy(event);
288
289 libinput_seat_unref(seat1);
290
291 libinput_unref(li);
292 udev_unref(udev);
293
294 litest_delete_device(dev);
295 }
296 END_TEST
297
START_TESTnull298 START_TEST(udev_double_suspend)
299 {
300 struct libinput *li;
301 struct libinput_event *event;
302 struct udev *udev;
303 int fd;
304
305 udev = udev_new();
306 ck_assert_notnull(udev);
307
308 li = libinput_udev_create_context(&simple_interface, NULL, udev);
309 ck_assert_notnull(li);
310 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
311
312 fd = libinput_get_fd(li);
313 ck_assert_int_ge(fd, 0);
314
315 /* expect at least one event */
316 ck_assert_int_ge(libinput_dispatch(li), 0);
317 event = libinput_get_event(li);
318 ck_assert_notnull(event);
319
320 libinput_suspend(li);
321 libinput_suspend(li);
322 libinput_resume(li);
323
324 libinput_event_destroy(event);
325 libinput_unref(li);
326 udev_unref(udev);
327 }
328 END_TEST
329
START_TESTnull330 START_TEST(udev_double_resume)
331 {
332 struct libinput *li;
333 struct libinput_event *event;
334 struct udev *udev;
335 int fd;
336
337 udev = udev_new();
338 ck_assert_notnull(udev);
339
340 li = libinput_udev_create_context(&simple_interface, NULL, udev);
341 ck_assert_notnull(li);
342 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
343
344 fd = libinput_get_fd(li);
345 ck_assert_int_ge(fd, 0);
346
347 /* expect at least one event */
348 ck_assert_int_ge(libinput_dispatch(li), 0);
349 event = libinput_get_event(li);
350 ck_assert_notnull(event);
351
352 libinput_suspend(li);
353 libinput_resume(li);
354 libinput_resume(li);
355
356 libinput_event_destroy(event);
357 libinput_unref(li);
358 udev_unref(udev);
359 }
360 END_TEST
361
362 static void
process_events_count_devices(struct libinput *li, int *device_count)363 process_events_count_devices(struct libinput *li, int *device_count)
364 {
365 struct libinput_event *event;
366
367 while ((event = libinput_get_event(li))) {
368 switch (libinput_event_get_type(event)) {
369 case LIBINPUT_EVENT_DEVICE_ADDED:
370 (*device_count)++;
371 break;
372 case LIBINPUT_EVENT_DEVICE_REMOVED:
373 (*device_count)--;
374 break;
375 default:
376 break;
377 }
378 libinput_event_destroy(event);
379 }
380 }
381
START_TESTnull382 START_TEST(udev_suspend_resume)
383 {
384 struct libinput *li;
385 struct udev *udev;
386 int fd;
387 int num_devices = 0;
388
389 udev = udev_new();
390 ck_assert_notnull(udev);
391
392 li = libinput_udev_create_context(&simple_interface, NULL, udev);
393 ck_assert_notnull(li);
394 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
395
396 fd = libinput_get_fd(li);
397 ck_assert_int_ge(fd, 0);
398
399 /* Check that at least one device was discovered after creation. */
400 ck_assert_int_ge(libinput_dispatch(li), 0);
401 process_events_count_devices(li, &num_devices);
402 ck_assert_int_gt(num_devices, 0);
403
404 /* Check that after a suspend, no devices are left. */
405 libinput_suspend(li);
406 ck_assert_int_ge(libinput_dispatch(li), 0);
407 process_events_count_devices(li, &num_devices);
408 ck_assert_int_eq(num_devices, 0);
409
410 /* Check that after a resume, at least one device is discovered. */
411 libinput_resume(li);
412 ck_assert_int_ge(libinput_dispatch(li), 0);
413 process_events_count_devices(li, &num_devices);
414 ck_assert_int_gt(num_devices, 0);
415
416 libinput_unref(li);
417 udev_unref(udev);
418 }
419 END_TEST
420
START_TESTnull421 START_TEST(udev_resume_before_seat)
422 {
423 struct libinput *li;
424 struct udev *udev;
425 int rc;
426
427 udev = udev_new();
428 ck_assert_notnull(udev);
429
430 li = libinput_udev_create_context(&simple_interface, NULL, udev);
431 ck_assert_notnull(li);
432
433 rc = libinput_resume(li);
434 ck_assert_int_eq(rc, 0);
435
436 libinput_unref(li);
437 udev_unref(udev);
438 }
439 END_TEST
440
START_TESTnull441 START_TEST(udev_suspend_resume_before_seat)
442 {
443 struct libinput *li;
444 struct udev *udev;
445 int rc;
446
447 udev = udev_new();
448 ck_assert_notnull(udev);
449
450 li = libinput_udev_create_context(&simple_interface, NULL, udev);
451 ck_assert_notnull(li);
452
453 libinput_suspend(li);
454 rc = libinput_resume(li);
455 ck_assert_int_eq(rc, 0);
456
457 libinput_unref(li);
458 udev_unref(udev);
459 }
460 END_TEST
461
START_TESTnull462 START_TEST(udev_device_sysname)
463 {
464 struct libinput *li;
465 struct libinput_event *ev;
466 struct libinput_device *device;
467 const char *sysname;
468 struct udev *udev;
469
470 udev = udev_new();
471 ck_assert_notnull(udev);
472
473 li = libinput_udev_create_context(&simple_interface, NULL, udev);
474 ck_assert_notnull(li);
475 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
476
477 libinput_dispatch(li);
478
479 while ((ev = libinput_get_event(li))) {
480 if (libinput_event_get_type(ev) !=
481 LIBINPUT_EVENT_DEVICE_ADDED) {
482 libinput_event_destroy(ev);
483 continue;
484 }
485
486 device = libinput_event_get_device(ev);
487 sysname = libinput_device_get_sysname(device);
488 ck_assert_notnull(sysname);
489 ck_assert_int_gt(strlen(sysname), 1);
490 ck_assert(strchr(sysname, '/') == NULL);
491 ck_assert(strneq(sysname, "event", 5));
492 libinput_event_destroy(ev);
493 }
494
495 libinput_unref(li);
496 udev_unref(udev);
497 }
498 END_TEST
499
START_TESTnull500 START_TEST(udev_seat_recycle)
501 {
502 struct udev *udev;
503 struct libinput *li;
504 struct libinput_event *ev;
505 struct libinput_device *device;
506 struct libinput_seat *saved_seat = NULL;
507 struct libinput_seat *seat;
508 int data = 0;
509 int found = 0;
510 void *user_data;
511
512 udev = udev_new();
513 ck_assert_notnull(udev);
514
515 li = libinput_udev_create_context(&simple_interface, NULL, udev);
516 ck_assert_notnull(li);
517 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
518
519 libinput_dispatch(li);
520 while ((ev = libinput_get_event(li))) {
521 switch (libinput_event_get_type(ev)) {
522 case LIBINPUT_EVENT_DEVICE_ADDED:
523 if (saved_seat)
524 break;
525
526 device = libinput_event_get_device(ev);
527 ck_assert_notnull(device);
528 saved_seat = libinput_device_get_seat(device);
529 libinput_seat_set_user_data(saved_seat, &data);
530 libinput_seat_ref(saved_seat);
531 break;
532 default:
533 break;
534 }
535
536 libinput_event_destroy(ev);
537 }
538
539 ck_assert_notnull(saved_seat);
540
541 libinput_suspend(li);
542
543 litest_drain_events(li);
544
545 libinput_resume(li);
546
547 libinput_dispatch(li);
548 while ((ev = libinput_get_event(li))) {
549 switch (libinput_event_get_type(ev)) {
550 case LIBINPUT_EVENT_DEVICE_ADDED:
551 device = libinput_event_get_device(ev);
552 ck_assert_notnull(device);
553
554 seat = libinput_device_get_seat(device);
555 user_data = libinput_seat_get_user_data(seat);
556 if (user_data == &data) {
557 found = 1;
558 ck_assert(seat == saved_seat);
559 }
560 break;
561 default:
562 break;
563 }
564
565 libinput_event_destroy(ev);
566 }
567
568 ck_assert(found == 1);
569
570 libinput_unref(li);
571 udev_unref(udev);
572 }
573 END_TEST
574
START_TESTnull575 START_TEST(udev_path_add_device)
576 {
577 struct udev *udev;
578 struct libinput *li;
579 struct libinput_device *device;
580
581 udev = udev_new();
582 ck_assert_notnull(udev);
583
584 li = libinput_udev_create_context(&simple_interface, NULL, udev);
585 ck_assert_notnull(li);
586 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
587
588 litest_set_log_handler_bug(li);
589 device = libinput_path_add_device(li, "/dev/input/event0");
590 ck_assert(device == NULL);
591 litest_restore_log_handler(li);
592
593 libinput_unref(li);
594 udev_unref(udev);
595 }
596 END_TEST
597
START_TESTnull598 START_TEST(udev_path_remove_device)
599 {
600 struct udev *udev;
601 struct libinput *li;
602 struct libinput_device *device;
603 struct libinput_event *event;
604
605 udev = udev_new();
606 ck_assert_notnull(udev);
607
608 li = libinput_udev_create_context(&simple_interface, NULL, udev);
609 ck_assert_notnull(li);
610 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
611 libinput_dispatch(li);
612
613 litest_wait_for_event_of_type(li, LIBINPUT_EVENT_DEVICE_ADDED, -1);
614 event = libinput_get_event(li);
615 device = libinput_event_get_device(event);
616 ck_assert_notnull(device);
617
618 /* no effect bug a bug log msg */
619 litest_set_log_handler_bug(li);
620 libinput_path_remove_device(device);
621 litest_restore_log_handler(li);
622
623 libinput_event_destroy(event);
624 libinput_unref(li);
625 udev_unref(udev);
626 }
627 END_TEST
628
START_TESTnull629 START_TEST(udev_ignore_device)
630 {
631 struct udev *udev;
632 struct libinput *li;
633 struct libinput_device *device;
634 struct libinput_event *event;
635 struct litest_device *dev;
636 const char *devname;
637
638 dev = litest_create(LITEST_IGNORED_MOUSE, NULL, NULL, NULL, NULL);
639 devname = libevdev_get_name(dev->evdev);
640
641 udev = udev_new();
642 ck_assert_notnull(udev);
643
644 li = libinput_udev_create_context(&simple_interface, NULL, udev);
645 ck_assert_notnull(li);
646 litest_restore_log_handler(li);
647
648 ck_assert_int_eq(libinput_udev_assign_seat(li, "seat0"), 0);
649 libinput_dispatch(li);
650
651 event = libinput_get_event(li);
652 ck_assert_notnull(event);
653 while (event) {
654 if (libinput_event_get_type(event) ==
655 LIBINPUT_EVENT_DEVICE_ADDED) {
656 const char *name;
657
658 device = libinput_event_get_device(event);
659 name = libinput_device_get_name(device);
660 ck_assert_str_ne(devname, name);
661 }
662 libinput_event_destroy(event);
663 libinput_dispatch(li);
664 event = libinput_get_event(li);
665 }
666
667 libinput_unref(li);
668 udev_unref(udev);
669
670 litest_delete_device(dev);
671 }
672 END_TEST
673
TEST_COLLECTIONnull674 TEST_COLLECTION(udev)
675 {
676 litest_add_no_device(udev_create_NULL);
677 litest_add_no_device(udev_create_seat0);
678 litest_add_no_device(udev_create_empty_seat);
679 litest_add_no_device(udev_create_seat_too_long);
680 litest_add_no_device(udev_set_user_data);
681
682 litest_add_no_device(udev_added_seat_default);
683 litest_add_no_device(udev_change_seat);
684
685 litest_add_for_device(udev_double_suspend, LITEST_SYNAPTICS_CLICKPAD_X220);
686 litest_add_for_device(udev_double_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
687 litest_add_for_device(udev_suspend_resume, LITEST_SYNAPTICS_CLICKPAD_X220);
688 litest_add_for_device(udev_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
689 litest_add_for_device(udev_suspend_resume_before_seat, LITEST_SYNAPTICS_CLICKPAD_X220);
690 litest_add_for_device(udev_device_sysname, LITEST_SYNAPTICS_CLICKPAD_X220);
691 litest_add_for_device(udev_seat_recycle, LITEST_SYNAPTICS_CLICKPAD_X220);
692
693 litest_add_no_device(udev_path_add_device);
694 litest_add_for_device(udev_path_remove_device, LITEST_SYNAPTICS_CLICKPAD_X220);
695
696 litest_add_no_device(udev_ignore_device);
697 }
698