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)20 static void input_cb_filtered(struct input_event *evt)
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_LISTENER_CB_DEFINE(&fake_dev, input_cb_filtered);
33
input_cb_unfiltered(struct input_event * evt)34 static void input_cb_unfiltered(struct input_event *evt)
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_LISTENER_CB_DEFINE(NULL, input_cb_unfiltered);
46
ZTEST(input_api,test_sequence_thread)47 ZTEST(input_api, test_sequence_thread)
48 {
49 int i;
50 int ret;
51
52 message_count_filtered = 0;
53 message_count_unfiltered = 0;
54
55 k_sem_take(&cb_start, K_FOREVER);
56 k_sem_take(&cb_done, K_FOREVER);
57
58 /* fill the queue */
59 for (i = 0; i < CONFIG_INPUT_QUEUE_MAX_MSGS; i++) {
60 TC_PRINT("report: %d\n", i);
61 ret = input_report_key(&fake_dev, i, 1, false, K_FOREVER);
62 zassert_equal(ret, 0, "ret: %d", ret);
63 }
64
65 /* one extra with no dev to acconut for the message pending in the
66 * locked cb
67 */
68 ret = input_report_key(NULL, 0, 1, false, K_FOREVER);
69 zassert_equal(ret, 0, "ret: %d", ret);
70
71 zassert_false(input_queue_empty());
72
73 /* next message finds the queue full */
74 ret = input_report_key(&fake_dev, 0, 1, false, K_NO_WAIT);
75 zassert_equal(ret, -ENOMSG, "ret: %d", ret);
76
77 k_sem_give(&cb_start);
78
79 /* wait for cb to get all the messages */
80 k_sem_take(&cb_done, K_FOREVER);
81
82 zassert_equal(message_count_filtered, CONFIG_INPUT_QUEUE_MAX_MSGS);
83 zassert_equal(message_count_unfiltered, CONFIG_INPUT_QUEUE_MAX_MSGS + 1);
84 }
85
86 #else /* CONFIG_INPUT_MODE_THREAD */
87
input_cb_filtered(struct input_event * evt)88 static void input_cb_filtered(struct input_event *evt)
89 {
90 if (evt->dev == &fake_dev) {
91 message_count_filtered++;
92 }
93 }
94 INPUT_LISTENER_CB_DEFINE(&fake_dev, input_cb_filtered);
95
input_cb_unfiltered(struct input_event * evt)96 static void input_cb_unfiltered(struct input_event *evt)
97 {
98 message_count_unfiltered++;
99 }
100 INPUT_LISTENER_CB_DEFINE(NULL, input_cb_unfiltered);
101
ZTEST(input_api,test_synchronous)102 ZTEST(input_api, test_synchronous)
103 {
104 int ret;
105
106 message_count_filtered = 0;
107 message_count_unfiltered = 0;
108
109 ret = input_report_key(&fake_dev, 0, 1, false, K_FOREVER);
110 zassert_equal(ret, 0, "ret: %d", ret);
111
112 ret = input_report_key(NULL, 0, 1, false, K_FOREVER);
113 zassert_equal(ret, 0, "ret: %d", ret);
114
115 zassert_equal(message_count_filtered, 1);
116 zassert_equal(message_count_unfiltered, 2);
117 }
118
119 static struct input_event last_event;
120
input_cb_last_event(struct input_event * evt)121 static void input_cb_last_event(struct input_event *evt)
122 {
123 memcpy(&last_event, evt, sizeof(last_event));
124 }
125 INPUT_LISTENER_CB_DEFINE(NULL, input_cb_last_event);
126
ZTEST(input_api,test_report_apis)127 ZTEST(input_api, test_report_apis)
128 {
129 int ret;
130
131 ret = input_report_key(&fake_dev, INPUT_KEY_A, 1, false, K_FOREVER);
132 zassert_equal(ret, 0);
133 zassert_equal(last_event.dev, &fake_dev);
134 zassert_equal(last_event.type, INPUT_EV_KEY);
135 zassert_equal(last_event.code, INPUT_KEY_A);
136 zassert_equal(last_event.value, 1);
137 zassert_equal(last_event.sync, 0);
138
139 ret = input_report_key(&fake_dev, INPUT_KEY_B, 1234, true, K_FOREVER);
140 zassert_equal(ret, 0);
141 zassert_equal(last_event.dev, &fake_dev);
142 zassert_equal(last_event.type, INPUT_EV_KEY);
143 zassert_equal(last_event.code, INPUT_KEY_B);
144 zassert_equal(last_event.value, 1); /* key events are always 0 or 1 */
145 zassert_equal(last_event.sync, 1);
146
147 ret = input_report_abs(&fake_dev, INPUT_ABS_X, 100, false, K_FOREVER);
148 zassert_equal(ret, 0);
149 zassert_equal(last_event.dev, &fake_dev);
150 zassert_equal(last_event.type, INPUT_EV_ABS);
151 zassert_equal(last_event.code, INPUT_ABS_X);
152 zassert_equal(last_event.value, 100);
153 zassert_equal(last_event.sync, 0);
154
155 ret = input_report_rel(&fake_dev, INPUT_REL_Y, -100, true, K_FOREVER);
156 zassert_equal(ret, 0);
157 zassert_equal(last_event.dev, &fake_dev);
158 zassert_equal(last_event.type, INPUT_EV_REL);
159 zassert_equal(last_event.code, INPUT_REL_Y);
160 zassert_equal(last_event.value, -100);
161 zassert_equal(last_event.sync, 1);
162
163 ret = input_report(&fake_dev, INPUT_EV_MSC, INPUT_MSC_SCAN, 0x12341234, true, K_FOREVER);
164 zassert_equal(ret, 0);
165 zassert_equal(last_event.dev, &fake_dev);
166 zassert_equal(last_event.type, INPUT_EV_MSC);
167 zassert_equal(last_event.code, INPUT_MSC_SCAN);
168 zassert_equal(last_event.value, 0x12341234);
169 zassert_equal(last_event.sync, 1);
170
171 ret = input_report(&fake_dev, INPUT_EV_VENDOR_START, 0xaaaa, 0xaaaaaaaa, true, K_FOREVER);
172 zassert_equal(ret, 0);
173 zassert_equal(last_event.dev, &fake_dev);
174 zassert_equal(last_event.type, INPUT_EV_VENDOR_START);
175 zassert_equal(last_event.code, 0xaaaa);
176 zassert_equal(last_event.value, 0xaaaaaaaa);
177 zassert_equal(last_event.sync, 1);
178
179 ret = input_report(&fake_dev, INPUT_EV_VENDOR_STOP, 0x5555, 0x55555555, true, K_FOREVER);
180 zassert_equal(ret, 0);
181 zassert_equal(last_event.dev, &fake_dev);
182 zassert_equal(last_event.type, INPUT_EV_VENDOR_STOP);
183 zassert_equal(last_event.code, 0x5555);
184 zassert_equal(last_event.value, 0x55555555);
185 zassert_equal(last_event.sync, 1);
186 }
187
188 #endif /* CONFIG_INPUT_MODE_THREAD */
189
190 ZTEST_SUITE(input_api, NULL, NULL, NULL, NULL, NULL);
191