1 /*
2 * Copyright 2023 Google LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/input/input.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/device.h>
10
11 static const struct device fake_dev;
12 static int message_count_filtered;
13 static int message_count_unfiltered;
14
15 #if CONFIG_INPUT_MODE_THREAD
16
17 static K_SEM_DEFINE(cb_start, 1, 1);
18 static K_SEM_DEFINE(cb_done, 1, 1);
19
input_cb_filtered(struct input_event * evt,void * user_data)20 static void input_cb_filtered(struct input_event *evt, void *user_data)
21 {
22 TC_PRINT("%s: %d\n", __func__, message_count_filtered);
23
24 k_sem_take(&cb_start, K_FOREVER);
25
26 if (evt->dev == &fake_dev && evt->code == message_count_filtered) {
27 message_count_filtered++;
28 }
29
30 k_sem_give(&cb_start);
31 }
32 INPUT_CALLBACK_DEFINE(&fake_dev, input_cb_filtered, NULL);
33
input_cb_unfiltered(struct input_event * evt,void * user_data)34 static void input_cb_unfiltered(struct input_event *evt, void *user_data)
35 {
36 TC_PRINT("%s: %d\n", __func__, message_count_unfiltered);
37
38 message_count_unfiltered++;
39
40 if (message_count_unfiltered == CONFIG_INPUT_QUEUE_MAX_MSGS + 1) {
41 TC_PRINT("cb: done\n");
42 k_sem_give(&cb_done);
43 }
44 }
45 INPUT_CALLBACK_DEFINE_NAMED(NULL, input_cb_unfiltered, NULL,
46 input_cb_unfiltered_custom_name);
47
ZTEST(input_api,test_sequence_thread)48 ZTEST(input_api, test_sequence_thread)
49 {
50 int i;
51 int ret;
52
53 message_count_filtered = 0;
54 message_count_unfiltered = 0;
55
56 k_sem_take(&cb_start, K_FOREVER);
57 k_sem_take(&cb_done, K_FOREVER);
58
59 /* fill the queue */
60 for (i = 0; i < CONFIG_INPUT_QUEUE_MAX_MSGS; i++) {
61 TC_PRINT("report: %d\n", i);
62 ret = input_report_key(&fake_dev, i, 1, false, K_FOREVER);
63 zassert_equal(ret, 0, "ret: %d", ret);
64 }
65
66 /* one extra with no dev to acconut for the message pending in the
67 * locked cb
68 */
69 ret = input_report_key(NULL, 0, 1, false, K_FOREVER);
70 zassert_equal(ret, 0, "ret: %d", ret);
71
72 zassert_false(input_queue_empty());
73
74 /* next message finds the queue full */
75 ret = input_report_key(&fake_dev, 0, 1, false, K_NO_WAIT);
76 zassert_equal(ret, -ENOMSG, "ret: %d", ret);
77
78 k_sem_give(&cb_start);
79
80 /* wait for cb to get all the messages */
81 k_sem_take(&cb_done, K_FOREVER);
82
83 zassert_equal(message_count_filtered, CONFIG_INPUT_QUEUE_MAX_MSGS);
84 zassert_equal(message_count_unfiltered, CONFIG_INPUT_QUEUE_MAX_MSGS + 1);
85 }
86
87 #else /* CONFIG_INPUT_MODE_THREAD */
88
input_cb_filtered(struct input_event * evt,void * user_data)89 static void input_cb_filtered(struct input_event *evt, void *user_data)
90 {
91 if (evt->dev == &fake_dev) {
92 message_count_filtered++;
93 }
94 }
95 INPUT_CALLBACK_DEFINE(&fake_dev, input_cb_filtered, NULL);
96
input_cb_unfiltered(struct input_event * evt,void * user_data)97 static void input_cb_unfiltered(struct input_event *evt, void *user_data)
98 {
99 message_count_unfiltered++;
100 }
101 INPUT_CALLBACK_DEFINE(NULL, input_cb_unfiltered, NULL);
102
ZTEST(input_api,test_synchronous)103 ZTEST(input_api, test_synchronous)
104 {
105 int ret;
106
107 message_count_filtered = 0;
108 message_count_unfiltered = 0;
109
110 ret = input_report_key(&fake_dev, 0, 1, false, K_FOREVER);
111 zassert_equal(ret, 0, "ret: %d", ret);
112
113 ret = input_report_key(NULL, 0, 1, false, K_FOREVER);
114 zassert_equal(ret, 0, "ret: %d", ret);
115
116 zassert_equal(message_count_filtered, 1);
117 zassert_equal(message_count_unfiltered, 2);
118 }
119
120 static struct input_event last_event;
121
input_cb_last_event(struct input_event * evt,void * user_data)122 static void input_cb_last_event(struct input_event *evt, void *user_data)
123 {
124 memcpy(&last_event, evt, sizeof(last_event));
125 }
126 INPUT_CALLBACK_DEFINE(NULL, input_cb_last_event, NULL);
127
ZTEST(input_api,test_report_apis)128 ZTEST(input_api, test_report_apis)
129 {
130 int ret;
131
132 ret = input_report_key(&fake_dev, INPUT_KEY_A, 1, false, K_FOREVER);
133 zassert_equal(ret, 0);
134 zassert_equal(last_event.dev, &fake_dev);
135 zassert_equal(last_event.type, INPUT_EV_KEY);
136 zassert_equal(last_event.code, INPUT_KEY_A);
137 zassert_equal(last_event.value, 1);
138 zassert_equal(last_event.sync, 0);
139
140 ret = input_report_key(&fake_dev, INPUT_KEY_B, 1234, true, K_FOREVER);
141 zassert_equal(ret, 0);
142 zassert_equal(last_event.dev, &fake_dev);
143 zassert_equal(last_event.type, INPUT_EV_KEY);
144 zassert_equal(last_event.code, INPUT_KEY_B);
145 zassert_equal(last_event.value, 1); /* key events are always 0 or 1 */
146 zassert_equal(last_event.sync, 1);
147
148 ret = input_report_abs(&fake_dev, INPUT_ABS_X, 100, false, K_FOREVER);
149 zassert_equal(ret, 0);
150 zassert_equal(last_event.dev, &fake_dev);
151 zassert_equal(last_event.type, INPUT_EV_ABS);
152 zassert_equal(last_event.code, INPUT_ABS_X);
153 zassert_equal(last_event.value, 100);
154 zassert_equal(last_event.sync, 0);
155
156 ret = input_report_rel(&fake_dev, INPUT_REL_Y, -100, true, K_FOREVER);
157 zassert_equal(ret, 0);
158 zassert_equal(last_event.dev, &fake_dev);
159 zassert_equal(last_event.type, INPUT_EV_REL);
160 zassert_equal(last_event.code, INPUT_REL_Y);
161 zassert_equal(last_event.value, -100);
162 zassert_equal(last_event.sync, 1);
163
164 ret = input_report(&fake_dev, INPUT_EV_MSC, INPUT_MSC_SCAN, 0x12341234, true, K_FOREVER);
165 zassert_equal(ret, 0);
166 zassert_equal(last_event.dev, &fake_dev);
167 zassert_equal(last_event.type, INPUT_EV_MSC);
168 zassert_equal(last_event.code, INPUT_MSC_SCAN);
169 zassert_equal(last_event.value, 0x12341234);
170 zassert_equal(last_event.sync, 1);
171
172 ret = input_report(&fake_dev, INPUT_EV_VENDOR_START, 0xaaaa, 0xaaaaaaaa, true, K_FOREVER);
173 zassert_equal(ret, 0);
174 zassert_equal(last_event.dev, &fake_dev);
175 zassert_equal(last_event.type, INPUT_EV_VENDOR_START);
176 zassert_equal(last_event.code, 0xaaaa);
177 zassert_equal(last_event.value, 0xaaaaaaaa);
178 zassert_equal(last_event.sync, 1);
179
180 ret = input_report(&fake_dev, INPUT_EV_VENDOR_STOP, 0x5555, 0x55555555, true, K_FOREVER);
181 zassert_equal(ret, 0);
182 zassert_equal(last_event.dev, &fake_dev);
183 zassert_equal(last_event.type, INPUT_EV_VENDOR_STOP);
184 zassert_equal(last_event.code, 0x5555);
185 zassert_equal(last_event.value, 0x55555555);
186 zassert_equal(last_event.sync, 1);
187 }
188
189 #endif /* CONFIG_INPUT_MODE_THREAD */
190
191 ZTEST_SUITE(input_api, NULL, NULL, NULL, NULL, NULL);
192