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