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