1a46c0ec8Sopenharmony_ci/* 2a46c0ec8Sopenharmony_ci * Copyright © 2014 Red Hat, Inc. 3a46c0ec8Sopenharmony_ci * 4a46c0ec8Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5a46c0ec8Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6a46c0ec8Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7a46c0ec8Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8a46c0ec8Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9a46c0ec8Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10a46c0ec8Sopenharmony_ci * 11a46c0ec8Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12a46c0ec8Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13a46c0ec8Sopenharmony_ci * Software. 14a46c0ec8Sopenharmony_ci * 15a46c0ec8Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16a46c0ec8Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17a46c0ec8Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18a46c0ec8Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19a46c0ec8Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20a46c0ec8Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21a46c0ec8Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22a46c0ec8Sopenharmony_ci */ 23a46c0ec8Sopenharmony_ci 24a46c0ec8Sopenharmony_ci#include <config.h> 25a46c0ec8Sopenharmony_ci 26a46c0ec8Sopenharmony_ci#include <check.h> 27a46c0ec8Sopenharmony_ci#include <errno.h> 28a46c0ec8Sopenharmony_ci#include <fcntl.h> 29a46c0ec8Sopenharmony_ci#include <libinput.h> 30a46c0ec8Sopenharmony_ci#include <unistd.h> 31a46c0ec8Sopenharmony_ci#include <stdarg.h> 32a46c0ec8Sopenharmony_ci 33a46c0ec8Sopenharmony_ci#include "litest.h" 34a46c0ec8Sopenharmony_ci 35a46c0ec8Sopenharmony_cistatic int log_handler_called; 36a46c0ec8Sopenharmony_cistatic struct libinput *log_handler_context; 37a46c0ec8Sopenharmony_ci 38a46c0ec8Sopenharmony_cistatic void 39a46c0ec8Sopenharmony_cisimple_log_handler(struct libinput *libinput, 40a46c0ec8Sopenharmony_ci enum libinput_log_priority priority, 41a46c0ec8Sopenharmony_ci const char *format, 42a46c0ec8Sopenharmony_ci va_list args) 43a46c0ec8Sopenharmony_ci{ 44a46c0ec8Sopenharmony_ci log_handler_called++; 45a46c0ec8Sopenharmony_ci if (log_handler_context) 46a46c0ec8Sopenharmony_ci litest_assert_ptr_eq(libinput, log_handler_context); 47a46c0ec8Sopenharmony_ci litest_assert_notnull(format); 48a46c0ec8Sopenharmony_ci} 49a46c0ec8Sopenharmony_ci 50a46c0ec8Sopenharmony_ci 51a46c0ec8Sopenharmony_cistatic int open_restricted(const char *path, int flags, void *data) 52a46c0ec8Sopenharmony_ci{ 53a46c0ec8Sopenharmony_ci int fd; 54a46c0ec8Sopenharmony_ci fd = open(path, flags); 55a46c0ec8Sopenharmony_ci return fd < 0 ? -errno : fd; 56a46c0ec8Sopenharmony_ci} 57a46c0ec8Sopenharmony_cistatic void close_restricted(int fd, void *data) 58a46c0ec8Sopenharmony_ci{ 59a46c0ec8Sopenharmony_ci close(fd); 60a46c0ec8Sopenharmony_ci} 61a46c0ec8Sopenharmony_ci 62a46c0ec8Sopenharmony_cistatic const struct libinput_interface simple_interface = { 63a46c0ec8Sopenharmony_ci .open_restricted = open_restricted, 64a46c0ec8Sopenharmony_ci .close_restricted = close_restricted, 65a46c0ec8Sopenharmony_ci}; 66a46c0ec8Sopenharmony_ci 67a46c0ec8Sopenharmony_ciSTART_TEST(log_default_priority) 68a46c0ec8Sopenharmony_ci{ 69a46c0ec8Sopenharmony_ci enum libinput_log_priority pri; 70a46c0ec8Sopenharmony_ci struct libinput *li; 71a46c0ec8Sopenharmony_ci 72a46c0ec8Sopenharmony_ci li = libinput_path_create_context(&simple_interface, NULL); 73a46c0ec8Sopenharmony_ci pri = libinput_log_get_priority(li); 74a46c0ec8Sopenharmony_ci 75a46c0ec8Sopenharmony_ci ck_assert_int_eq(pri, LIBINPUT_LOG_PRIORITY_ERROR); 76a46c0ec8Sopenharmony_ci 77a46c0ec8Sopenharmony_ci libinput_unref(li); 78a46c0ec8Sopenharmony_ci} 79a46c0ec8Sopenharmony_ciEND_TEST 80a46c0ec8Sopenharmony_ci 81a46c0ec8Sopenharmony_ciSTART_TEST(log_handler_invoked) 82a46c0ec8Sopenharmony_ci{ 83a46c0ec8Sopenharmony_ci struct libinput *li; 84a46c0ec8Sopenharmony_ci 85a46c0ec8Sopenharmony_ci log_handler_context = NULL; 86a46c0ec8Sopenharmony_ci log_handler_called = 0; 87a46c0ec8Sopenharmony_ci 88a46c0ec8Sopenharmony_ci li = litest_create_context(); 89a46c0ec8Sopenharmony_ci 90a46c0ec8Sopenharmony_ci libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); 91a46c0ec8Sopenharmony_ci libinput_log_set_handler(li, simple_log_handler); 92a46c0ec8Sopenharmony_ci log_handler_context = li; 93a46c0ec8Sopenharmony_ci 94a46c0ec8Sopenharmony_ci libinput_path_add_device(li, "/tmp"); 95a46c0ec8Sopenharmony_ci 96a46c0ec8Sopenharmony_ci ck_assert_int_gt(log_handler_called, 0); 97a46c0ec8Sopenharmony_ci 98a46c0ec8Sopenharmony_ci litest_destroy_context(li); 99a46c0ec8Sopenharmony_ci 100a46c0ec8Sopenharmony_ci log_handler_context = NULL; 101a46c0ec8Sopenharmony_ci log_handler_called = 0; 102a46c0ec8Sopenharmony_ci} 103a46c0ec8Sopenharmony_ciEND_TEST 104a46c0ec8Sopenharmony_ci 105a46c0ec8Sopenharmony_ciSTART_TEST(log_handler_NULL) 106a46c0ec8Sopenharmony_ci{ 107a46c0ec8Sopenharmony_ci struct libinput *li; 108a46c0ec8Sopenharmony_ci 109a46c0ec8Sopenharmony_ci log_handler_called = 0; 110a46c0ec8Sopenharmony_ci 111a46c0ec8Sopenharmony_ci li = litest_create_context(); 112a46c0ec8Sopenharmony_ci libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); 113a46c0ec8Sopenharmony_ci libinput_log_set_handler(li, NULL); 114a46c0ec8Sopenharmony_ci 115a46c0ec8Sopenharmony_ci libinput_path_add_device(li, "/tmp"); 116a46c0ec8Sopenharmony_ci 117a46c0ec8Sopenharmony_ci ck_assert_int_eq(log_handler_called, 0); 118a46c0ec8Sopenharmony_ci 119a46c0ec8Sopenharmony_ci litest_destroy_context(li); 120a46c0ec8Sopenharmony_ci 121a46c0ec8Sopenharmony_ci log_handler_called = 0; 122a46c0ec8Sopenharmony_ci} 123a46c0ec8Sopenharmony_ciEND_TEST 124a46c0ec8Sopenharmony_ci 125a46c0ec8Sopenharmony_ciSTART_TEST(log_priority) 126a46c0ec8Sopenharmony_ci{ 127a46c0ec8Sopenharmony_ci struct libinput *li; 128a46c0ec8Sopenharmony_ci 129a46c0ec8Sopenharmony_ci log_handler_context = NULL; 130a46c0ec8Sopenharmony_ci log_handler_called = 0; 131a46c0ec8Sopenharmony_ci 132a46c0ec8Sopenharmony_ci li = litest_create_context(); 133a46c0ec8Sopenharmony_ci libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR); 134a46c0ec8Sopenharmony_ci libinput_log_set_handler(li, simple_log_handler); 135a46c0ec8Sopenharmony_ci log_handler_context = li; 136a46c0ec8Sopenharmony_ci 137a46c0ec8Sopenharmony_ci libinput_path_add_device(li, "/tmp"); 138a46c0ec8Sopenharmony_ci 139a46c0ec8Sopenharmony_ci ck_assert_int_eq(log_handler_called, 1); 140a46c0ec8Sopenharmony_ci 141a46c0ec8Sopenharmony_ci libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO); 142a46c0ec8Sopenharmony_ci /* event0 exists on any box we care to run the test suite on and we 143a46c0ec8Sopenharmony_ci * currently prints *something* for each device */ 144a46c0ec8Sopenharmony_ci libinput_path_add_device(li, "/dev/input/event0"); 145a46c0ec8Sopenharmony_ci ck_assert_int_gt(log_handler_called, 1); 146a46c0ec8Sopenharmony_ci 147a46c0ec8Sopenharmony_ci litest_destroy_context(li); 148a46c0ec8Sopenharmony_ci 149a46c0ec8Sopenharmony_ci log_handler_context = NULL; 150a46c0ec8Sopenharmony_ci log_handler_called = 0; 151a46c0ec8Sopenharmony_ci} 152a46c0ec8Sopenharmony_ciEND_TEST 153a46c0ec8Sopenharmony_ci 154a46c0ec8Sopenharmony_cistatic int axisrange_log_handler_called = 0; 155a46c0ec8Sopenharmony_ci 156a46c0ec8Sopenharmony_cistatic void 157a46c0ec8Sopenharmony_ciaxisrange_warning_log_handler(struct libinput *libinput, 158a46c0ec8Sopenharmony_ci enum libinput_log_priority priority, 159a46c0ec8Sopenharmony_ci const char *format, 160a46c0ec8Sopenharmony_ci va_list args) 161a46c0ec8Sopenharmony_ci{ 162a46c0ec8Sopenharmony_ci const char *substr; 163a46c0ec8Sopenharmony_ci 164a46c0ec8Sopenharmony_ci axisrange_log_handler_called++; 165a46c0ec8Sopenharmony_ci litest_assert_notnull(format); 166a46c0ec8Sopenharmony_ci 167a46c0ec8Sopenharmony_ci substr = strstr(format, "is outside expected range"); 168a46c0ec8Sopenharmony_ci litest_assert_notnull(substr); 169a46c0ec8Sopenharmony_ci} 170a46c0ec8Sopenharmony_ci 171a46c0ec8Sopenharmony_ciSTART_TEST(log_axisrange_warning) 172a46c0ec8Sopenharmony_ci{ 173a46c0ec8Sopenharmony_ci struct litest_device *dev = litest_current_device(); 174a46c0ec8Sopenharmony_ci struct libinput *li = dev->libinput; 175a46c0ec8Sopenharmony_ci const struct input_absinfo *abs; 176a46c0ec8Sopenharmony_ci int axis = _i; /* looped test */ 177a46c0ec8Sopenharmony_ci 178a46c0ec8Sopenharmony_ci litest_touch_down(dev, 0, 90, 100); 179a46c0ec8Sopenharmony_ci litest_drain_events(li); 180a46c0ec8Sopenharmony_ci 181a46c0ec8Sopenharmony_ci libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO); 182a46c0ec8Sopenharmony_ci libinput_log_set_handler(li, axisrange_warning_log_handler); 183a46c0ec8Sopenharmony_ci 184a46c0ec8Sopenharmony_ci abs = libevdev_get_abs_info(dev->evdev, axis); 185a46c0ec8Sopenharmony_ci 186a46c0ec8Sopenharmony_ci for (int i = 0; i < 100; i++) { 187a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, 188a46c0ec8Sopenharmony_ci ABS_MT_POSITION_X + axis, 189a46c0ec8Sopenharmony_ci abs->maximum * 2 + i); 190a46c0ec8Sopenharmony_ci litest_event(dev, EV_ABS, axis, abs->maximum * 2); 191a46c0ec8Sopenharmony_ci litest_event(dev, EV_SYN, SYN_REPORT, 0); 192a46c0ec8Sopenharmony_ci libinput_dispatch(li); 193a46c0ec8Sopenharmony_ci } 194a46c0ec8Sopenharmony_ci 195a46c0ec8Sopenharmony_ci /* Expect only one message per 5 min */ 196a46c0ec8Sopenharmony_ci ck_assert_int_eq(axisrange_log_handler_called, 1); 197a46c0ec8Sopenharmony_ci 198a46c0ec8Sopenharmony_ci libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR); 199a46c0ec8Sopenharmony_ci litest_restore_log_handler(li); 200a46c0ec8Sopenharmony_ci axisrange_log_handler_called = 0; 201a46c0ec8Sopenharmony_ci} 202a46c0ec8Sopenharmony_ciEND_TEST 203a46c0ec8Sopenharmony_ci 204a46c0ec8Sopenharmony_ciTEST_COLLECTION(log) 205a46c0ec8Sopenharmony_ci{ 206a46c0ec8Sopenharmony_ci struct range axes = { ABS_X, ABS_Y + 1}; 207a46c0ec8Sopenharmony_ci 208a46c0ec8Sopenharmony_ci litest_add_deviceless(log_default_priority); 209a46c0ec8Sopenharmony_ci litest_add_deviceless(log_handler_invoked); 210a46c0ec8Sopenharmony_ci litest_add_deviceless(log_handler_NULL); 211a46c0ec8Sopenharmony_ci litest_add_no_device(log_priority); 212a46c0ec8Sopenharmony_ci 213a46c0ec8Sopenharmony_ci /* mtdev clips to axis ranges */ 214a46c0ec8Sopenharmony_ci litest_add_ranged(log_axisrange_warning, LITEST_TOUCH, LITEST_PROTOCOL_A, &axes); 215a46c0ec8Sopenharmony_ci litest_add_ranged(log_axisrange_warning, LITEST_TOUCHPAD, LITEST_ANY, &axes); 216a46c0ec8Sopenharmony_ci} 217