Path: blob/master/tools/testing/selftests/hid/tests/test_apple_keyboard.py
26308 views
#!/bin/env python31# SPDX-License-Identifier: GPL-2.02# -*- coding: utf-8 -*-3#4# Copyright (c) 2019 Benjamin Tissoires <[email protected]>5# Copyright (c) 2019 Red Hat, Inc.6#78from .test_keyboard import ArrayKeyboard, TestArrayKeyboard9from hidtools.util import BusType10from . import base1112import libevdev13import logging1415logger = logging.getLogger("hidtools.test.apple-keyboard")1617KERNEL_MODULE = base.KernelModule("apple", "hid-apple")181920class KbdData(object):21pass222324class AppleKeyboard(ArrayKeyboard):25# fmt: off26report_descriptor = [270x05, 0x01, # Usage Page (Generic Desktop)280x09, 0x06, # Usage (Keyboard)290xa1, 0x01, # Collection (Application)300x85, 0x01, # .Report ID (1)310x05, 0x07, # .Usage Page (Keyboard)320x19, 0xe0, # .Usage Minimum (224)330x29, 0xe7, # .Usage Maximum (231)340x15, 0x00, # .Logical Minimum (0)350x25, 0x01, # .Logical Maximum (1)360x75, 0x01, # .Report Size (1)370x95, 0x08, # .Report Count (8)380x81, 0x02, # .Input (Data,Var,Abs)390x75, 0x08, # .Report Size (8)400x95, 0x01, # .Report Count (1)410x81, 0x01, # .Input (Cnst,Arr,Abs)420x75, 0x01, # .Report Size (1)430x95, 0x05, # .Report Count (5)440x05, 0x08, # .Usage Page (LEDs)450x19, 0x01, # .Usage Minimum (1)460x29, 0x05, # .Usage Maximum (5)470x91, 0x02, # .Output (Data,Var,Abs)480x75, 0x03, # .Report Size (3)490x95, 0x01, # .Report Count (1)500x91, 0x01, # .Output (Cnst,Arr,Abs)510x75, 0x08, # .Report Size (8)520x95, 0x06, # .Report Count (6)530x15, 0x00, # .Logical Minimum (0)540x26, 0xff, 0x00, # .Logical Maximum (255)550x05, 0x07, # .Usage Page (Keyboard)560x19, 0x00, # .Usage Minimum (0)570x2a, 0xff, 0x00, # .Usage Maximum (255)580x81, 0x00, # .Input (Data,Arr,Abs)590xc0, # End Collection600x05, 0x0c, # Usage Page (Consumer Devices)610x09, 0x01, # Usage (Consumer Control)620xa1, 0x01, # Collection (Application)630x85, 0x47, # .Report ID (71)640x05, 0x01, # .Usage Page (Generic Desktop)650x09, 0x06, # .Usage (Keyboard)660xa1, 0x02, # .Collection (Logical)670x05, 0x06, # ..Usage Page (Generic Device Controls)680x09, 0x20, # ..Usage (Battery Strength)690x15, 0x00, # ..Logical Minimum (0)700x26, 0xff, 0x00, # ..Logical Maximum (255)710x75, 0x08, # ..Report Size (8)720x95, 0x01, # ..Report Count (1)730x81, 0x02, # ..Input (Data,Var,Abs)740xc0, # .End Collection750xc0, # End Collection760x05, 0x0c, # Usage Page (Consumer Devices)770x09, 0x01, # Usage (Consumer Control)780xa1, 0x01, # Collection (Application)790x85, 0x11, # .Report ID (17)800x15, 0x00, # .Logical Minimum (0)810x25, 0x01, # .Logical Maximum (1)820x75, 0x01, # .Report Size (1)830x95, 0x03, # .Report Count (3)840x81, 0x01, # .Input (Cnst,Arr,Abs)850x75, 0x01, # .Report Size (1)860x95, 0x01, # .Report Count (1)870x05, 0x0c, # .Usage Page (Consumer Devices)880x09, 0xb8, # .Usage (Eject)890x81, 0x02, # .Input (Data,Var,Abs)900x06, 0xff, 0x00, # .Usage Page (Vendor Usage Page 0xff)910x09, 0x03, # .Usage (Vendor Usage 0x03)920x81, 0x02, # .Input (Data,Var,Abs)930x75, 0x01, # .Report Size (1)940x95, 0x03, # .Report Count (3)950x81, 0x01, # .Input (Cnst,Arr,Abs)960x05, 0x0c, # .Usage Page (Consumer Devices)970x85, 0x12, # .Report ID (18)980x15, 0x00, # .Logical Minimum (0)990x25, 0x01, # .Logical Maximum (1)1000x75, 0x01, # .Report Size (1)1010x95, 0x01, # .Report Count (1)1020x09, 0xcd, # .Usage (Play/Pause)1030x81, 0x02, # .Input (Data,Var,Abs)1040x09, 0xb3, # .Usage (Fast Forward)1050x81, 0x02, # .Input (Data,Var,Abs)1060x09, 0xb4, # .Usage (Rewind)1070x81, 0x02, # .Input (Data,Var,Abs)1080x09, 0xb5, # .Usage (Scan Next Track)1090x81, 0x02, # .Input (Data,Var,Abs)1100x09, 0xb6, # .Usage (Scan Previous Track)1110x81, 0x02, # .Input (Data,Var,Abs)1120x81, 0x01, # .Input (Cnst,Arr,Abs)1130x81, 0x01, # .Input (Cnst,Arr,Abs)1140x81, 0x01, # .Input (Cnst,Arr,Abs)1150x85, 0x13, # .Report ID (19)1160x15, 0x00, # .Logical Minimum (0)1170x25, 0x01, # .Logical Maximum (1)1180x75, 0x01, # .Report Size (1)1190x95, 0x01, # .Report Count (1)1200x06, 0x01, 0xff, # .Usage Page (Vendor Usage Page 0xff01)1210x09, 0x0a, # .Usage (Vendor Usage 0x0a)1220x81, 0x02, # .Input (Data,Var,Abs)1230x06, 0x01, 0xff, # .Usage Page (Vendor Usage Page 0xff01)1240x09, 0x0c, # .Usage (Vendor Usage 0x0c)1250x81, 0x22, # .Input (Data,Var,Abs,NoPref)1260x75, 0x01, # .Report Size (1)1270x95, 0x06, # .Report Count (6)1280x81, 0x01, # .Input (Cnst,Arr,Abs)1290x85, 0x09, # .Report ID (9)1300x09, 0x0b, # .Usage (Vendor Usage 0x0b)1310x75, 0x08, # .Report Size (8)1320x95, 0x01, # .Report Count (1)1330xb1, 0x02, # .Feature (Data,Var,Abs)1340x75, 0x08, # .Report Size (8)1350x95, 0x02, # .Report Count (2)1360xb1, 0x01, # .Feature (Cnst,Arr,Abs)1370xc0, # End Collection138]139# fmt: on140141def __init__(142self,143rdesc=report_descriptor,144name="Apple Wireless Keyboard",145input_info=(BusType.BLUETOOTH, 0x05AC, 0x0256),146):147super().__init__(rdesc, name, input_info)148self.default_reportID = 1149150def send_fn_state(self, state):151data = KbdData()152setattr(data, "0xff0003", state)153r = self.create_report(data, reportID=17)154self.call_input_event(r)155return [r]156157158class TestAppleKeyboard(TestArrayKeyboard):159kernel_modules = [KERNEL_MODULE]160161def create_device(self):162return AppleKeyboard()163164def test_single_function_key(self):165"""check for function key reliability."""166uhdev = self.uhdev167evdev = uhdev.get_evdev()168syn_event = self.syn_event169170r = uhdev.event(["F4"])171expected = [syn_event]172expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_ALL_APPLICATIONS, 1))173events = uhdev.next_sync_events()174self.debug_reports(r, uhdev, events)175self.assertInputEventsIn(expected, events)176assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 1177assert evdev.value[libevdev.EV_KEY.KEY_FN] == 0178179r = uhdev.event([])180expected = [syn_event]181expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_ALL_APPLICATIONS, 0))182events = uhdev.next_sync_events()183self.debug_reports(r, uhdev, events)184self.assertInputEventsIn(expected, events)185assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 0186187def test_single_fn_function_key(self):188"""check for function key reliability with the fn key."""189uhdev = self.uhdev190evdev = uhdev.get_evdev()191syn_event = self.syn_event192193r = uhdev.send_fn_state(1)194r.extend(uhdev.event(["F4"]))195expected = [syn_event]196expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F4, 1))197expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 1))198events = uhdev.next_sync_events()199self.debug_reports(r, uhdev, events)200self.assertInputEventsIn(expected, events)201assert evdev.value[libevdev.EV_KEY.KEY_F4] == 1202203r = uhdev.event([])204expected = [syn_event]205expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F4, 0))206events = uhdev.next_sync_events()207self.debug_reports(r, uhdev, events)208self.assertInputEventsIn(expected, events)209assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0210assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1211212r = uhdev.send_fn_state(0)213expected = [syn_event]214expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 0))215events = uhdev.next_sync_events()216self.debug_reports(r, uhdev, events)217self.assertInputEventsIn(expected, events)218219def test_single_fn_function_key_release_first(self):220"""check for function key reliability with the fn key."""221uhdev = self.uhdev222evdev = uhdev.get_evdev()223syn_event = self.syn_event224225r = uhdev.send_fn_state(1)226r.extend(uhdev.event(["F4"]))227expected = [syn_event]228expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F4, 1))229expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 1))230events = uhdev.next_sync_events()231self.debug_reports(r, uhdev, events)232self.assertInputEventsIn(expected, events)233assert evdev.value[libevdev.EV_KEY.KEY_F4] == 1234235r = uhdev.send_fn_state(0)236expected = [syn_event]237expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 0))238events = uhdev.next_sync_events()239self.debug_reports(r, uhdev, events)240self.assertInputEventsIn(expected, events)241242r = uhdev.event([])243expected = [syn_event]244expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F4, 0))245events = uhdev.next_sync_events()246self.debug_reports(r, uhdev, events)247self.assertInputEventsIn(expected, events)248assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0249250def test_single_fn_function_key_inverted(self):251"""check for function key reliability with the fn key."""252uhdev = self.uhdev253evdev = uhdev.get_evdev()254syn_event = self.syn_event255256r = uhdev.event(["F4"])257r.extend(uhdev.send_fn_state(1))258expected = [syn_event]259expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_ALL_APPLICATIONS, 1))260expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 1))261events = uhdev.next_sync_events()262self.debug_reports(r, uhdev, events)263self.assertInputEventsIn(expected, events)264assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 1265266r = uhdev.event([])267expected = [syn_event]268expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_ALL_APPLICATIONS, 0))269events = uhdev.next_sync_events()270self.debug_reports(r, uhdev, events)271self.assertInputEventsIn(expected, events)272assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 0273assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1274275r = uhdev.send_fn_state(0)276expected = [syn_event]277expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 0))278events = uhdev.next_sync_events()279self.debug_reports(r, uhdev, events)280self.assertInputEventsIn(expected, events)281282def test_multiple_fn_function_key_release_first(self):283"""check for function key reliability with the fn key."""284uhdev = self.uhdev285evdev = uhdev.get_evdev()286syn_event = self.syn_event287288r = uhdev.send_fn_state(1)289r.extend(uhdev.event(["F4"]))290r.extend(uhdev.event(["F4", "F6"]))291expected = [syn_event]292expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F4, 1))293expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F6, 1))294expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 1))295events = uhdev.next_sync_events()296self.debug_reports(r, uhdev, events)297self.assertInputEventsIn(expected, events)298assert evdev.value[libevdev.EV_KEY.KEY_F4] == 1299assert evdev.value[libevdev.EV_KEY.KEY_F6] == 1300assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1301302r = uhdev.event(["F6"])303expected = [syn_event]304expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F4, 0))305events = uhdev.next_sync_events()306self.debug_reports(r, uhdev, events)307self.assertInputEventsIn(expected, events)308assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0309assert evdev.value[libevdev.EV_KEY.KEY_F6] == 1310assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1311312r = uhdev.send_fn_state(0)313expected = [syn_event]314expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 0))315events = uhdev.next_sync_events()316self.debug_reports(r, uhdev, events)317self.assertInputEventsIn(expected, events)318assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0319assert evdev.value[libevdev.EV_KEY.KEY_F6] == 1320assert evdev.value[libevdev.EV_KEY.KEY_FN] == 0321322r = uhdev.event([])323expected = [syn_event]324expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F6, 0))325events = uhdev.next_sync_events()326self.debug_reports(r, uhdev, events)327self.assertInputEventsIn(expected, events)328assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0329assert evdev.value[libevdev.EV_KEY.KEY_F6] == 0330assert evdev.value[libevdev.EV_KEY.KEY_FN] == 0331332def test_multiple_fn_function_key_release_between(self):333"""check for function key reliability with the fn key."""334uhdev = self.uhdev335evdev = uhdev.get_evdev()336syn_event = self.syn_event337338# press F4339r = uhdev.event(["F4"])340expected = [syn_event]341expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_ALL_APPLICATIONS, 1))342events = uhdev.next_sync_events()343self.debug_reports(r, uhdev, events)344self.assertInputEventsIn(expected, events)345assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0346assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 1347assert evdev.value[libevdev.EV_KEY.KEY_F6] == 0348assert evdev.value[libevdev.EV_KEY.KEY_KBDILLUMUP] == 0349assert evdev.value[libevdev.EV_KEY.KEY_FN] == 0350351# press Fn key352r = uhdev.send_fn_state(1)353expected = [syn_event]354expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 1))355events = uhdev.next_sync_events()356self.debug_reports(r, uhdev, events)357self.assertInputEventsIn(expected, events)358assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0359assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 1360assert evdev.value[libevdev.EV_KEY.KEY_F6] == 0361assert evdev.value[libevdev.EV_KEY.KEY_KBDILLUMUP] == 0362assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1363364# keep F4 and press F6365r = uhdev.event(["F4", "F6"])366expected = [syn_event]367expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F6, 1))368events = uhdev.next_sync_events()369self.debug_reports(r, uhdev, events)370self.assertInputEventsIn(expected, events)371assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0372assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 1373assert evdev.value[libevdev.EV_KEY.KEY_F6] == 1374assert evdev.value[libevdev.EV_KEY.KEY_KBDILLUMUP] == 0375assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1376377# keep F4 and F6378r = uhdev.event(["F4", "F6"])379expected = []380events = uhdev.next_sync_events()381self.debug_reports(r, uhdev, events)382self.assertInputEventsIn(expected, events)383assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0384assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 1385assert evdev.value[libevdev.EV_KEY.KEY_F6] == 1386assert evdev.value[libevdev.EV_KEY.KEY_KBDILLUMUP] == 0387assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1388389# release Fn key and all keys390r = uhdev.send_fn_state(0)391r.extend(uhdev.event([]))392expected = [syn_event]393expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_ALL_APPLICATIONS, 0))394expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_F6, 0))395events = uhdev.next_sync_events()396self.debug_reports(r, uhdev, events)397self.assertInputEventsIn(expected, events)398assert evdev.value[libevdev.EV_KEY.KEY_F4] == 0399assert evdev.value[libevdev.EV_KEY.KEY_ALL_APPLICATIONS] == 0400assert evdev.value[libevdev.EV_KEY.KEY_F6] == 0401assert evdev.value[libevdev.EV_KEY.KEY_KBDILLUMUP] == 0402assert evdev.value[libevdev.EV_KEY.KEY_FN] == 0403404def test_single_pageup_key_release_first(self):405"""check for function key reliability with the [page] up key."""406uhdev = self.uhdev407evdev = uhdev.get_evdev()408syn_event = self.syn_event409410r = uhdev.send_fn_state(1)411r.extend(uhdev.event(["UpArrow"]))412expected = [syn_event]413expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_PAGEUP, 1))414expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 1))415events = uhdev.next_sync_events()416self.debug_reports(r, uhdev, events)417self.assertInputEventsIn(expected, events)418assert evdev.value[libevdev.EV_KEY.KEY_PAGEUP] == 1419assert evdev.value[libevdev.EV_KEY.KEY_UP] == 0420assert evdev.value[libevdev.EV_KEY.KEY_FN] == 1421422r = uhdev.send_fn_state(0)423expected = [syn_event]424expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_FN, 0))425events = uhdev.next_sync_events()426self.debug_reports(r, uhdev, events)427self.assertInputEventsIn(expected, events)428assert evdev.value[libevdev.EV_KEY.KEY_PAGEUP] == 1429assert evdev.value[libevdev.EV_KEY.KEY_UP] == 0430assert evdev.value[libevdev.EV_KEY.KEY_FN] == 0431432r = uhdev.event([])433expected = [syn_event]434expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_PAGEUP, 0))435events = uhdev.next_sync_events()436self.debug_reports(r, uhdev, events)437self.assertInputEventsIn(expected, events)438assert evdev.value[libevdev.EV_KEY.KEY_PAGEUP] == 0439assert evdev.value[libevdev.EV_KEY.KEY_UP] == 0440assert evdev.value[libevdev.EV_KEY.KEY_FN] == 0441442443