Skip to content

tests/tablet: add GXTP reporting quirk tests

наб requested to merge nabijaczleweli/hid-tools:goodixpsko into master

In Re: my 4/4 from March, now that !115 (merged) landed

Fails on clean mainline (well, 5.15.0-2 off Debian, applies cleanly to both):

$ sudo pytest-3 -k tablet
============================= test session starts ==============================
platform linux -- Python 3.9.9, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
rootdir: /home/nabijaczleweli/data/2021-02-10-linux-hid-stylus-on-touchscreen-device/hid-tools
collected 2430 items / 2397 deselected / 33 selected

tests/test_tablet.py ..............................FFF                   [100%]

=================================== FAILURES ===================================
________________ TestGXTP_27c6_0113.test_contact_idiosyncratic _________________

self = <tests.test_tablet.TestGXTP_27c6_0113 object at 0x7f3a35243fd0>

    def test_contact_idiosyncratic(self):
        """Pen touches, but loses inrange in the process
           Actual reporting from the device: hid=TIPSWITCH,INRANGE (code=TOUCH,TOOL_PEN):
             { 0, 1 } <- hover
             { 1, 1 } <- touch-down
             { 1, 0 } <- still touch, if you scribble on the screen you're in this state
             { 0, 1 } <- liftoff
             { 0, 0 } <- leaves
        """
    
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()
    
        p = Pen(50, 60)
        events = self.post(uhdev, p)
        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in events
        assert evdev.value[libevdev.EV_ABS.ABS_X] == 50
        assert evdev.value[libevdev.EV_ABS.ABS_Y] == 60
    
        p.tipswitch = True
        events = self.post(uhdev, p)
        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in events
    
        p.inrange = False
        events = self.post(uhdev, p)
>       assert not events
E       assert not [InputEvent(EV_KEY, BTN_TOOL_PEN, 0), InputEvent(EV_SYN, SYN_REPORT, 0)]

tests/test_tablet.py:351: AssertionError
----------------------------- Captured stdout call -----------------------------
sending 1 report:
	 08 20 00 32 00 3c 00 0f 00 00 00 00 00
	 ====> ReportID: 8 / Tip Switch: 0 | Barrel Switch: 0 | Invert: 0 | Eraser: 0 | # | In Range: 1 | # | Contact Id:    0 | X:     50 | Y:     60 | Tip Pressure:     15 | X Tilt:      0 | Y Tilt:      0 
events received: [InputEvent(EV_KEY, BTN_TOOL_PEN, 1), InputEvent(EV_ABS, ABS_X, 50), InputEvent(EV_ABS, ABS_Y, 60), InputEvent(EV_ABS, ABS_PRESSURE, 15), InputEvent(EV_SYN, SYN_REPORT, 0)]
sending 1 report:
	 08 21 00 32 00 3c 00 0f 00 00 00 00 00
	 ====> ReportID: 8 / Tip Switch: 1 | Barrel Switch: 0 | Invert: 0 | Eraser: 0 | # | In Range: 1 | # | Contact Id:    0 | X:     50 | Y:     60 | Tip Pressure:     15 | X Tilt:      0 | Y Tilt:      0 
events received: [InputEvent(EV_MSC, MSC_SCAN, 852034), InputEvent(EV_KEY, BTN_TOUCH, 1), InputEvent(EV_SYN, SYN_REPORT, 0)]
sending 1 report:
	 08 01 00 32 00 3c 00 0f 00 00 00 00 00
	 ====> ReportID: 8 / Tip Switch: 1 | Barrel Switch: 0 | Invert: 0 | Eraser: 0 | # | In Range: 0 | # | Contact Id:    0 | X:     50 | Y:     60 | Tip Pressure:     15 | X Tilt:      0 | Y Tilt:      0 
events received: [InputEvent(EV_KEY, BTN_TOOL_PEN, 0), InputEvent(EV_SYN, SYN_REPORT, 0)]
____________ TestGXTP_27c6_0113.test_contact_idiosyncratic_primary _____________

self = <tests.test_tablet.TestGXTP_27c6_0113 object at 0x7f3a34b98df0>

    def test_contact_idiosyncratic_primary(self):
        """Primary button (stylus) pressed, reports as pressed even while hovering; it needs to be ANDed with the tip switch.
           Actual reporting from the device: hid=TIPSWITCH,BARRELSWITCH,INRANGE (code=TOUCH,STYLUS,PEN):
             { 0, 0, 1 } <- hover
             { 0, 1, 1 } <- primary button pressed
             { 1, 1, 1 } <- touch-down
             { 1, 1, 0 } <- still touch, if you scribble on the screen you're in this state
             { 0, 1, 1 } <- liftoff
             { 0, 0, 0 } <- leaves
        """
    
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()
    
        p = Pen(50, 60)
        events = self.post(uhdev, p)
        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in events
        assert evdev.value[libevdev.EV_ABS.ABS_X] == 50
        assert evdev.value[libevdev.EV_ABS.ABS_Y] == 60
        assert not evdev.value[libevdev.EV_KEY.BTN_STYLUS]
    
        p.barrelswitch = True
        events = self.post(uhdev, p)
>       assert not events
E       assert not [InputEvent(EV_MSC, MSC_SCAN, 852036), InputEvent(EV_KEY, BTN_STYLUS, 1), InputEvent(EV_SYN, SYN_REPORT, 0)]

tests/test_tablet.py:392: AssertionError
---------------------------- Captured stdout setup -----------------------------
abort /dev/input/event25 [('ACTION', 'add'), ('DEVNAME', '/dev/input/event25'), ('DEVPATH', '/devices/virtual/misc/uhid/0003:0001:0002.0024/input/input2531/event25'), ('ID_INPUT', '1'), ('LIBINPUT_IGNORE_DEVICE', '1'), ('MAJOR', '13'), ('MINOR', '89'), ('SEQNUM', '22299'), ('SUBSYSTEM', 'input'), ('USEC_INITIALIZED', '15101887877')]
----------------------------- Captured stdout call -----------------------------
sending 1 report:
	 08 20 00 32 00 3c 00 0f 00 00 00 00 00
	 ====> ReportID: 8 / Tip Switch: 0 | Barrel Switch: 0 | Invert: 0 | Eraser: 0 | # | In Range: 1 | # | Contact Id:    0 | X:     50 | Y:     60 | Tip Pressure:     15 | X Tilt:      0 | Y Tilt:      0 
events received: [InputEvent(EV_KEY, BTN_TOOL_PEN, 1), InputEvent(EV_ABS, ABS_X, 50), InputEvent(EV_ABS, ABS_Y, 60), InputEvent(EV_ABS, ABS_PRESSURE, 15), InputEvent(EV_SYN, SYN_REPORT, 0)]
sending 1 report:
	 08 22 00 32 00 3c 00 0f 00 00 00 00 00
	 ====> ReportID: 8 / Tip Switch: 0 | Barrel Switch: 1 | Invert: 0 | Eraser: 0 | # | In Range: 1 | # | Contact Id:    0 | X:     50 | Y:     60 | Tip Pressure:     15 | X Tilt:      0 | Y Tilt:      0 
events received: [InputEvent(EV_MSC, MSC_SCAN, 852036), InputEvent(EV_KEY, BTN_STYLUS, 1), InputEvent(EV_SYN, SYN_REPORT, 0)]
_____________ TestGXTP_27c6_0113.test_contact_idiosyncratic_eraser _____________

self = <tests.test_tablet.TestGXTP_27c6_0113 object at 0x7f3a34b95be0>

    def test_contact_idiosyncratic_eraser(self):
        """Like normal touch, but the secondary button (RUBBER) is held, and provided for the entire time.
           In the reporting, RUBBER implies PEN; however, RUBBER must exclude PEN,
           otherwise the tool in-proximity is RUBBER but PEN when touching.
           Actual reporting from the device: hid=INVERT,ERASER,INRANGE (code=RUBBER,TOUCH,PEN):
             { 1, 0, 1 } <- hover
             { 0, 1, 1 } <- touchdown, scribble
             { 1, 0, 1 } <- liftoff
             { 0, 0, 0 } <- leaves
        """
    
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()
    
        p = Pen(50, 60)
        p.invert = True
        events = self.post(uhdev, p)
        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_RUBBER, 1) in events
        assert evdev.value[libevdev.EV_ABS.ABS_X] == 50
        assert evdev.value[libevdev.EV_ABS.ABS_Y] == 60
        assert not evdev.value[libevdev.EV_KEY.BTN_TOOL_PEN]
    
        p.invert, p.eraser = p.eraser, p.invert
        events = self.post(uhdev, p)
        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in events
        assert evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER]
>       assert not evdev.value[libevdev.EV_KEY.BTN_TOOL_PEN]
E       assert not 1

tests/test_tablet.py:449: AssertionError
---------------------------- Captured stdout setup -----------------------------
abort /dev/input/event25 [('ACTION', 'add'), ('DEVNAME', '/dev/input/event25'), ('DEVPATH', '/devices/virtual/misc/uhid/0003:0001:0002.0025/input/input2535/event25'), ('ID_INPUT', '1'), ('LIBINPUT_IGNORE_DEVICE', '1'), ('MAJOR', '13'), ('MINOR', '89'), ('SEQNUM', '22325'), ('SUBSYSTEM', 'input'), ('USEC_INITIALIZED', '15102459667')]
----------------------------- Captured stdout call -----------------------------
sending 1 report:
	 08 24 00 32 00 3c 00 0f 00 00 00 00 00
	 ====> ReportID: 8 / Tip Switch: 0 | Barrel Switch: 0 | Invert: 1 | Eraser: 0 | # | In Range: 1 | # | Contact Id:    0 | X:     50 | Y:     60 | Tip Pressure:     15 | X Tilt:      0 | Y Tilt:      0 
events received: [InputEvent(EV_KEY, BTN_TOOL_RUBBER, 1), InputEvent(EV_ABS, ABS_X, 50), InputEvent(EV_ABS, ABS_Y, 60), InputEvent(EV_ABS, ABS_PRESSURE, 15), InputEvent(EV_SYN, SYN_REPORT, 0)]
sending 1 report:
	 08 28 00 32 00 3c 00 0f 00 00 00 00 00
	 ====> ReportID: 8 / Tip Switch: 0 | Barrel Switch: 0 | Invert: 0 | Eraser: 1 | # | In Range: 1 | # | Contact Id:    0 | X:     50 | Y:     60 | Tip Pressure:     15 | X Tilt:      0 | Y Tilt:      0 
events received: [InputEvent(EV_MSC, MSC_SCAN, 852037), InputEvent(EV_KEY, BTN_TOUCH, 1), InputEvent(EV_KEY, BTN_TOOL_PEN, 1), InputEvent(EV_SYN, SYN_REPORT, 0)]
=========================== short test summary info ============================
FAILED tests/test_tablet.py::TestGXTP_27c6_0113::test_contact_idiosyncratic
FAILED tests/test_tablet.py::TestGXTP_27c6_0113::test_contact_idiosyncratic_primary
FAILED tests/test_tablet.py::TestGXTP_27c6_0113::test_contact_idiosyncratic_eraser
================ 3 failed, 30 passed, 2397 deselected in 19.06s ================

Passes with 4/4:

$ sudo pytest-3 -k tablet
============================= test session starts ==============================
platform linux -- Python 3.9.9, pytest-6.2.5, py-1.10.0, pluggy-0.13.0
rootdir: /home/nabijaczleweli/data/2021-02-10-linux-hid-stylus-on-touchscreen-device/hid-tools
collected 2430 items / 2397 deselected / 33 selected

tests/test_tablet.py .................................                   [100%]

===================== 33 passed, 2397 deselected in 19.02s =====================

The full and preprocessed recording dumps can be had from https://lfs.nabijaczleweli.xyz/0011-OneMix3-Win8-tablet-screen-recording

CC: @bentiss

Edited by наб

Merge request reports