2 # SPDX-License-Identifier: GPL-2.0
3 # -*- coding: utf-8 -*-
5 # Copyright (c) 2019 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6 # Copyright (c) 2019 Red Hat, Inc.
9 from .test_keyboard
import ArrayKeyboard
, TestArrayKeyboard
10 from hidtools
.util
import BusType
15 logger
= logging
.getLogger("hidtools.test.apple-keyboard")
17 KERNEL_MODULE
= ("apple", "hid-apple")
20 class KbdData(object):
24 class AppleKeyboard(ArrayKeyboard
):
27 0x05, 0x01, # Usage Page (Generic Desktop)
28 0x09, 0x06, # Usage (Keyboard)
29 0xa1, 0x01, # Collection (Application)
30 0x85, 0x01, # .Report ID (1)
31 0x05, 0x07, # .Usage Page (Keyboard)
32 0x19, 0xe0, # .Usage Minimum (224)
33 0x29, 0xe7, # .Usage Maximum (231)
34 0x15, 0x00, # .Logical Minimum (0)
35 0x25, 0x01, # .Logical Maximum (1)
36 0x75, 0x01, # .Report Size (1)
37 0x95, 0x08, # .Report Count (8)
38 0x81, 0x02, # .Input (Data,Var,Abs)
39 0x75, 0x08, # .Report Size (8)
40 0x95, 0x01, # .Report Count (1)
41 0x81, 0x01, # .Input (Cnst,Arr,Abs)
42 0x75, 0x01, # .Report Size (1)
43 0x95, 0x05, # .Report Count (5)
44 0x05, 0x08, # .Usage Page (LEDs)
45 0x19, 0x01, # .Usage Minimum (1)
46 0x29, 0x05, # .Usage Maximum (5)
47 0x91, 0x02, # .Output (Data,Var,Abs)
48 0x75, 0x03, # .Report Size (3)
49 0x95, 0x01, # .Report Count (1)
50 0x91, 0x01, # .Output (Cnst,Arr,Abs)
51 0x75, 0x08, # .Report Size (8)
52 0x95, 0x06, # .Report Count (6)
53 0x15, 0x00, # .Logical Minimum (0)
54 0x26, 0xff, 0x00, # .Logical Maximum (255)
55 0x05, 0x07, # .Usage Page (Keyboard)
56 0x19, 0x00, # .Usage Minimum (0)
57 0x2a, 0xff, 0x00, # .Usage Maximum (255)
58 0x81, 0x00, # .Input (Data,Arr,Abs)
59 0xc0, # End Collection
60 0x05, 0x0c, # Usage Page (Consumer Devices)
61 0x09, 0x01, # Usage (Consumer Control)
62 0xa1, 0x01, # Collection (Application)
63 0x85, 0x47, # .Report ID (71)
64 0x05, 0x01, # .Usage Page (Generic Desktop)
65 0x09, 0x06, # .Usage (Keyboard)
66 0xa1, 0x02, # .Collection (Logical)
67 0x05, 0x06, # ..Usage Page (Generic Device Controls)
68 0x09, 0x20, # ..Usage (Battery Strength)
69 0x15, 0x00, # ..Logical Minimum (0)
70 0x26, 0xff, 0x00, # ..Logical Maximum (255)
71 0x75, 0x08, # ..Report Size (8)
72 0x95, 0x01, # ..Report Count (1)
73 0x81, 0x02, # ..Input (Data,Var,Abs)
74 0xc0, # .End Collection
75 0xc0, # End Collection
76 0x05, 0x0c, # Usage Page (Consumer Devices)
77 0x09, 0x01, # Usage (Consumer Control)
78 0xa1, 0x01, # Collection (Application)
79 0x85, 0x11, # .Report ID (17)
80 0x15, 0x00, # .Logical Minimum (0)
81 0x25, 0x01, # .Logical Maximum (1)
82 0x75, 0x01, # .Report Size (1)
83 0x95, 0x03, # .Report Count (3)
84 0x81, 0x01, # .Input (Cnst,Arr,Abs)
85 0x75, 0x01, # .Report Size (1)
86 0x95, 0x01, # .Report Count (1)
87 0x05, 0x0c, # .Usage Page (Consumer Devices)
88 0x09, 0xb8, # .Usage (Eject)
89 0x81, 0x02, # .Input (Data,Var,Abs)
90 0x06, 0xff, 0x00, # .Usage Page (Vendor Usage Page 0xff)
91 0x09, 0x03, # .Usage (Vendor Usage 0x03)
92 0x81, 0x02, # .Input (Data,Var,Abs)
93 0x75, 0x01, # .Report Size (1)
94 0x95, 0x03, # .Report Count (3)
95 0x81, 0x01, # .Input (Cnst,Arr,Abs)
96 0x05, 0x0c, # .Usage Page (Consumer Devices)
97 0x85, 0x12, # .Report ID (18)
98 0x15, 0x00, # .Logical Minimum (0)
99 0x25, 0x01, # .Logical Maximum (1)
100 0x75, 0x01, # .Report Size (1)
101 0x95, 0x01, # .Report Count (1)
102 0x09, 0xcd, # .Usage (Play/Pause)
103 0x81, 0x02, # .Input (Data,Var,Abs)
104 0x09, 0xb3, # .Usage (Fast Forward)
105 0x81, 0x02, # .Input (Data,Var,Abs)
106 0x09, 0xb4, # .Usage (Rewind)
107 0x81, 0x02, # .Input (Data,Var,Abs)
108 0x09, 0xb5, # .Usage (Scan Next Track)
109 0x81, 0x02, # .Input (Data,Var,Abs)
110 0x09, 0xb6, # .Usage (Scan Previous Track)
111 0x81, 0x02, # .Input (Data,Var,Abs)
112 0x81, 0x01, # .Input (Cnst,Arr,Abs)
113 0x81, 0x01, # .Input (Cnst,Arr,Abs)
114 0x81, 0x01, # .Input (Cnst,Arr,Abs)
115 0x85, 0x13, # .Report ID (19)
116 0x15, 0x00, # .Logical Minimum (0)
117 0x25, 0x01, # .Logical Maximum (1)
118 0x75, 0x01, # .Report Size (1)
119 0x95, 0x01, # .Report Count (1)
120 0x06, 0x01, 0xff, # .Usage Page (Vendor Usage Page 0xff01)
121 0x09, 0x0a, # .Usage (Vendor Usage 0x0a)
122 0x81, 0x02, # .Input (Data,Var,Abs)
123 0x06, 0x01, 0xff, # .Usage Page (Vendor Usage Page 0xff01)
124 0x09, 0x0c, # .Usage (Vendor Usage 0x0c)
125 0x81, 0x22, # .Input (Data,Var,Abs,NoPref)
126 0x75, 0x01, # .Report Size (1)
127 0x95, 0x06, # .Report Count (6)
128 0x81, 0x01, # .Input (Cnst,Arr,Abs)
129 0x85, 0x09, # .Report ID (9)
130 0x09, 0x0b, # .Usage (Vendor Usage 0x0b)
131 0x75, 0x08, # .Report Size (8)
132 0x95, 0x01, # .Report Count (1)
133 0xb1, 0x02, # .Feature (Data,Var,Abs)
134 0x75, 0x08, # .Report Size (8)
135 0x95, 0x02, # .Report Count (2)
136 0xb1, 0x01, # .Feature (Cnst,Arr,Abs)
137 0xc0, # End Collection
143 rdesc
=report_descriptor
,
144 name
="Apple Wireless Keyboard",
145 input_info
=(BusType
.BLUETOOTH
, 0x05AC, 0x0256),
147 super().__init
__(rdesc
, name
, input_info
)
148 self
.default_reportID
= 1
150 def send_fn_state(self
, state
):
152 setattr(data
, "0xff0003", state
)
153 r
= self
.create_report(data
, reportID
=17)
154 self
.call_input_event(r
)
158 class TestAppleKeyboard(TestArrayKeyboard
):
159 kernel_modules
= [KERNEL_MODULE
]
161 def create_device(self
):
162 return AppleKeyboard()
164 def test_single_function_key(self
):
165 """check for function key reliability."""
167 evdev
= uhdev
.get_evdev()
168 syn_event
= self
.syn_event
170 r
= uhdev
.event(["F4"])
171 expected
= [syn_event
]
172 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
, 1))
173 events
= uhdev
.next_sync_events()
174 self
.debug_reports(r
, uhdev
, events
)
175 self
.assertInputEventsIn(expected
, events
)
176 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 1
177 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 0
180 expected
= [syn_event
]
181 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
, 0))
182 events
= uhdev
.next_sync_events()
183 self
.debug_reports(r
, uhdev
, events
)
184 self
.assertInputEventsIn(expected
, events
)
185 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 0
187 def test_single_fn_function_key(self
):
188 """check for function key reliability with the fn key."""
190 evdev
= uhdev
.get_evdev()
191 syn_event
= self
.syn_event
193 r
= uhdev
.send_fn_state(1)
194 r
.extend(uhdev
.event(["F4"]))
195 expected
= [syn_event
]
196 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F4
, 1))
197 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 1))
198 events
= uhdev
.next_sync_events()
199 self
.debug_reports(r
, uhdev
, events
)
200 self
.assertInputEventsIn(expected
, events
)
201 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 1
204 expected
= [syn_event
]
205 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F4
, 0))
206 events
= uhdev
.next_sync_events()
207 self
.debug_reports(r
, uhdev
, events
)
208 self
.assertInputEventsIn(expected
, events
)
209 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
210 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
212 r
= uhdev
.send_fn_state(0)
213 expected
= [syn_event
]
214 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 0))
215 events
= uhdev
.next_sync_events()
216 self
.debug_reports(r
, uhdev
, events
)
217 self
.assertInputEventsIn(expected
, events
)
219 def test_single_fn_function_key_release_first(self
):
220 """check for function key reliability with the fn key."""
222 evdev
= uhdev
.get_evdev()
223 syn_event
= self
.syn_event
225 r
= uhdev
.send_fn_state(1)
226 r
.extend(uhdev
.event(["F4"]))
227 expected
= [syn_event
]
228 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F4
, 1))
229 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 1))
230 events
= uhdev
.next_sync_events()
231 self
.debug_reports(r
, uhdev
, events
)
232 self
.assertInputEventsIn(expected
, events
)
233 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 1
235 r
= uhdev
.send_fn_state(0)
236 expected
= [syn_event
]
237 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 0))
238 events
= uhdev
.next_sync_events()
239 self
.debug_reports(r
, uhdev
, events
)
240 self
.assertInputEventsIn(expected
, events
)
243 expected
= [syn_event
]
244 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F4
, 0))
245 events
= uhdev
.next_sync_events()
246 self
.debug_reports(r
, uhdev
, events
)
247 self
.assertInputEventsIn(expected
, events
)
248 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
250 def test_single_fn_function_key_inverted(self
):
251 """check for function key reliability with the fn key."""
253 evdev
= uhdev
.get_evdev()
254 syn_event
= self
.syn_event
256 r
= uhdev
.event(["F4"])
257 r
.extend(uhdev
.send_fn_state(1))
258 expected
= [syn_event
]
259 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
, 1))
260 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 1))
261 events
= uhdev
.next_sync_events()
262 self
.debug_reports(r
, uhdev
, events
)
263 self
.assertInputEventsIn(expected
, events
)
264 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 1
267 expected
= [syn_event
]
268 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
, 0))
269 events
= uhdev
.next_sync_events()
270 self
.debug_reports(r
, uhdev
, events
)
271 self
.assertInputEventsIn(expected
, events
)
272 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 0
273 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
275 r
= uhdev
.send_fn_state(0)
276 expected
= [syn_event
]
277 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 0))
278 events
= uhdev
.next_sync_events()
279 self
.debug_reports(r
, uhdev
, events
)
280 self
.assertInputEventsIn(expected
, events
)
282 def test_multiple_fn_function_key_release_first(self
):
283 """check for function key reliability with the fn key."""
285 evdev
= uhdev
.get_evdev()
286 syn_event
= self
.syn_event
288 r
= uhdev
.send_fn_state(1)
289 r
.extend(uhdev
.event(["F4"]))
290 r
.extend(uhdev
.event(["F4", "F6"]))
291 expected
= [syn_event
]
292 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F4
, 1))
293 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F6
, 1))
294 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 1))
295 events
= uhdev
.next_sync_events()
296 self
.debug_reports(r
, uhdev
, events
)
297 self
.assertInputEventsIn(expected
, events
)
298 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 1
299 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 1
300 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
302 r
= uhdev
.event(["F6"])
303 expected
= [syn_event
]
304 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F4
, 0))
305 events
= uhdev
.next_sync_events()
306 self
.debug_reports(r
, uhdev
, events
)
307 self
.assertInputEventsIn(expected
, events
)
308 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
309 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 1
310 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
312 r
= uhdev
.send_fn_state(0)
313 expected
= [syn_event
]
314 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 0))
315 events
= uhdev
.next_sync_events()
316 self
.debug_reports(r
, uhdev
, events
)
317 self
.assertInputEventsIn(expected
, events
)
318 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
319 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 1
320 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 0
323 expected
= [syn_event
]
324 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F6
, 0))
325 events
= uhdev
.next_sync_events()
326 self
.debug_reports(r
, uhdev
, events
)
327 self
.assertInputEventsIn(expected
, events
)
328 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
329 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 0
330 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 0
332 def test_multiple_fn_function_key_release_between(self
):
333 """check for function key reliability with the fn key."""
335 evdev
= uhdev
.get_evdev()
336 syn_event
= self
.syn_event
339 r
= uhdev
.event(["F4"])
340 expected
= [syn_event
]
341 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
, 1))
342 events
= uhdev
.next_sync_events()
343 self
.debug_reports(r
, uhdev
, events
)
344 self
.assertInputEventsIn(expected
, events
)
345 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
346 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 1
347 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 0
348 assert evdev
.value
[libevdev
.EV_KEY
.KEY_KBDILLUMUP
] == 0
349 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 0
352 r
= uhdev
.send_fn_state(1)
353 expected
= [syn_event
]
354 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 1))
355 events
= uhdev
.next_sync_events()
356 self
.debug_reports(r
, uhdev
, events
)
357 self
.assertInputEventsIn(expected
, events
)
358 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
359 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 1
360 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 0
361 assert evdev
.value
[libevdev
.EV_KEY
.KEY_KBDILLUMUP
] == 0
362 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
364 # keep F4 and press F6
365 r
= uhdev
.event(["F4", "F6"])
366 expected
= [syn_event
]
367 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F6
, 1))
368 events
= uhdev
.next_sync_events()
369 self
.debug_reports(r
, uhdev
, events
)
370 self
.assertInputEventsIn(expected
, events
)
371 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
372 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 1
373 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 1
374 assert evdev
.value
[libevdev
.EV_KEY
.KEY_KBDILLUMUP
] == 0
375 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
378 r
= uhdev
.event(["F4", "F6"])
380 events
= uhdev
.next_sync_events()
381 self
.debug_reports(r
, uhdev
, events
)
382 self
.assertInputEventsIn(expected
, events
)
383 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
384 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 1
385 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 1
386 assert evdev
.value
[libevdev
.EV_KEY
.KEY_KBDILLUMUP
] == 0
387 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
389 # release Fn key and all keys
390 r
= uhdev
.send_fn_state(0)
391 r
.extend(uhdev
.event([]))
392 expected
= [syn_event
]
393 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
, 0))
394 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_F6
, 0))
395 events
= uhdev
.next_sync_events()
396 self
.debug_reports(r
, uhdev
, events
)
397 self
.assertInputEventsIn(expected
, events
)
398 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F4
] == 0
399 assert evdev
.value
[libevdev
.EV_KEY
.KEY_ALL_APPLICATIONS
] == 0
400 assert evdev
.value
[libevdev
.EV_KEY
.KEY_F6
] == 0
401 assert evdev
.value
[libevdev
.EV_KEY
.KEY_KBDILLUMUP
] == 0
402 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 0
404 def test_single_pageup_key_release_first(self
):
405 """check for function key reliability with the [page] up key."""
407 evdev
= uhdev
.get_evdev()
408 syn_event
= self
.syn_event
410 r
= uhdev
.send_fn_state(1)
411 r
.extend(uhdev
.event(["UpArrow"]))
412 expected
= [syn_event
]
413 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_PAGEUP
, 1))
414 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 1))
415 events
= uhdev
.next_sync_events()
416 self
.debug_reports(r
, uhdev
, events
)
417 self
.assertInputEventsIn(expected
, events
)
418 assert evdev
.value
[libevdev
.EV_KEY
.KEY_PAGEUP
] == 1
419 assert evdev
.value
[libevdev
.EV_KEY
.KEY_UP
] == 0
420 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 1
422 r
= uhdev
.send_fn_state(0)
423 expected
= [syn_event
]
424 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_FN
, 0))
425 events
= uhdev
.next_sync_events()
426 self
.debug_reports(r
, uhdev
, events
)
427 self
.assertInputEventsIn(expected
, events
)
428 assert evdev
.value
[libevdev
.EV_KEY
.KEY_PAGEUP
] == 1
429 assert evdev
.value
[libevdev
.EV_KEY
.KEY_UP
] == 0
430 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 0
433 expected
= [syn_event
]
434 expected
.append(libevdev
.InputEvent(libevdev
.EV_KEY
.KEY_PAGEUP
, 0))
435 events
= uhdev
.next_sync_events()
436 self
.debug_reports(r
, uhdev
, events
)
437 self
.assertInputEventsIn(expected
, events
)
438 assert evdev
.value
[libevdev
.EV_KEY
.KEY_PAGEUP
] == 0
439 assert evdev
.value
[libevdev
.EV_KEY
.KEY_UP
] == 0
440 assert evdev
.value
[libevdev
.EV_KEY
.KEY_FN
] == 0