Skip to content

Commit 1f01537

Browse files
author
Benjamin Tissoires
committed
selftests/hid: tablets: convert the primary button tests
We get more descriptive in what we are doing, and also get more information of what is actually being tested. Instead of having a non exhaustive button changes that are semi-randomly done, we can describe all the states we want to test. Reviewed-by: Peter Hutterer <[email protected]> Acked-by: Jiri Kosina <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Benjamin Tissoires <[email protected]>
1 parent 74452d6 commit 1f01537

File tree

1 file changed

+65
-95
lines changed

1 file changed

+65
-95
lines changed

tools/testing/selftests/hid/tests/test_tablet.py

Lines changed: 65 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,55 @@ def legal_transitions_with_invert() -> Dict[str, Tuple["PenState", ...]]:
317317
),
318318
}
319319

320+
@staticmethod
321+
def legal_transitions_with_primary_button() -> Dict[str, Tuple["PenState", ...]]:
322+
"""We revisit the Windows Pen Implementation state machine:
323+
we now have a primary button.
324+
"""
325+
return {
326+
"hover-button": (PenState.PEN_IS_IN_RANGE_WITH_BUTTON,),
327+
"hover-button -> out-of-range": (
328+
PenState.PEN_IS_IN_RANGE_WITH_BUTTON,
329+
PenState.PEN_IS_OUT_OF_RANGE,
330+
),
331+
"in-range -> button-press": (
332+
PenState.PEN_IS_IN_RANGE,
333+
PenState.PEN_IS_IN_RANGE_WITH_BUTTON,
334+
),
335+
"in-range -> button-press -> button-release": (
336+
PenState.PEN_IS_IN_RANGE,
337+
PenState.PEN_IS_IN_RANGE_WITH_BUTTON,
338+
PenState.PEN_IS_IN_RANGE,
339+
),
340+
"in-range -> touch -> button-press -> button-release": (
341+
PenState.PEN_IS_IN_RANGE,
342+
PenState.PEN_IS_IN_CONTACT,
343+
PenState.PEN_IS_IN_CONTACT_WITH_BUTTON,
344+
PenState.PEN_IS_IN_CONTACT,
345+
),
346+
"in-range -> touch -> button-press -> release -> button-release": (
347+
PenState.PEN_IS_IN_RANGE,
348+
PenState.PEN_IS_IN_CONTACT,
349+
PenState.PEN_IS_IN_CONTACT_WITH_BUTTON,
350+
PenState.PEN_IS_IN_RANGE_WITH_BUTTON,
351+
PenState.PEN_IS_IN_RANGE,
352+
),
353+
"in-range -> button-press -> touch -> release -> button-release": (
354+
PenState.PEN_IS_IN_RANGE,
355+
PenState.PEN_IS_IN_RANGE_WITH_BUTTON,
356+
PenState.PEN_IS_IN_CONTACT_WITH_BUTTON,
357+
PenState.PEN_IS_IN_RANGE_WITH_BUTTON,
358+
PenState.PEN_IS_IN_RANGE,
359+
),
360+
"in-range -> button-press -> touch -> button-release -> release": (
361+
PenState.PEN_IS_IN_RANGE,
362+
PenState.PEN_IS_IN_RANGE_WITH_BUTTON,
363+
PenState.PEN_IS_IN_CONTACT_WITH_BUTTON,
364+
PenState.PEN_IS_IN_CONTACT,
365+
PenState.PEN_IS_IN_RANGE,
366+
),
367+
}
368+
320369
@staticmethod
321370
def tolerated_transitions() -> Dict[str, Tuple["PenState", ...]]:
322371
"""This is not adhering to the Windows Pen Implementation state machine
@@ -671,6 +720,22 @@ def test_tolerated_pen_states(self, state_list, scribble):
671720
reasons."""
672721
self._test_states(state_list, scribble)
673722

723+
@pytest.mark.skip_if_uhdev(
724+
lambda uhdev: "Barrel Switch" not in uhdev.fields,
725+
"Device not compatible, missing Barrel Switch usage",
726+
)
727+
@pytest.mark.parametrize("scribble", [True, False], ids=["scribble", "static"])
728+
@pytest.mark.parametrize(
729+
"state_list",
730+
[
731+
pytest.param(v, id=k)
732+
for k, v in PenState.legal_transitions_with_primary_button().items()
733+
],
734+
)
735+
def test_valid_primary_button_pen_states(self, state_list, scribble):
736+
"""Rework the transition state machine by adding the primary button."""
737+
self._test_states(state_list, scribble)
738+
674739
@pytest.mark.skip_if_uhdev(
675740
lambda uhdev: "Invert" not in uhdev.fields,
676741
"Device not compatible, missing Invert usage",
@@ -728,101 +793,6 @@ def test_tolerated_broken_pen_states(self, state_list, scribble):
728793
state machine."""
729794
self._test_states(state_list, scribble)
730795

731-
@pytest.mark.skip_if_uhdev(
732-
lambda uhdev: "Barrel Switch" not in uhdev.fields,
733-
"Device not compatible, missing Barrel Switch usage",
734-
)
735-
def test_primary_button(self):
736-
"""Primary button (stylus) pressed, reports as pressed even while hovering.
737-
Actual reporting from the device: hid=TIPSWITCH,BARRELSWITCH,INRANGE (code=TOUCH,STYLUS,PEN):
738-
{ 0, 0, 1 } <- hover
739-
{ 0, 1, 1 } <- primary button pressed
740-
{ 0, 1, 1 } <- liftoff
741-
{ 0, 0, 0 } <- leaves
742-
"""
743-
744-
uhdev = self.uhdev
745-
evdev = uhdev.get_evdev()
746-
747-
p = Pen(50, 60)
748-
p.inrange = True
749-
events = self.post(uhdev, p)
750-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in events
751-
assert evdev.value[libevdev.EV_ABS.ABS_X] == 50
752-
assert evdev.value[libevdev.EV_ABS.ABS_Y] == 60
753-
assert not evdev.value[libevdev.EV_KEY.BTN_STYLUS]
754-
755-
p.barrelswitch = True
756-
events = self.post(uhdev, p)
757-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 1) in events
758-
759-
p.x += 1
760-
p.y -= 1
761-
events = self.post(uhdev, p)
762-
assert len(events) == 3 # X, Y, SYN
763-
assert libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 51) in events
764-
assert libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 59) in events
765-
766-
p.barrelswitch = False
767-
events = self.post(uhdev, p)
768-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 0) in events
769-
770-
p.inrange = False
771-
events = self.post(uhdev, p)
772-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0) in events
773-
774-
@pytest.mark.skip_if_uhdev(
775-
lambda uhdev: "Barrel Switch" not in uhdev.fields,
776-
"Device not compatible, missing Barrel Switch usage",
777-
)
778-
def test_contact_primary_button(self):
779-
"""Primary button (stylus) pressed, reports as pressed even while hovering.
780-
Actual reporting from the device: hid=TIPSWITCH,BARRELSWITCH,INRANGE (code=TOUCH,STYLUS,PEN):
781-
{ 0, 0, 1 } <- hover
782-
{ 0, 1, 1 } <- primary button pressed
783-
{ 1, 1, 1 } <- touch-down
784-
{ 1, 1, 1 } <- still touch, scribble on the screen
785-
{ 0, 1, 1 } <- liftoff
786-
{ 0, 0, 0 } <- leaves
787-
"""
788-
789-
uhdev = self.uhdev
790-
evdev = uhdev.get_evdev()
791-
792-
p = Pen(50, 60)
793-
p.inrange = True
794-
events = self.post(uhdev, p)
795-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in events
796-
assert evdev.value[libevdev.EV_ABS.ABS_X] == 50
797-
assert evdev.value[libevdev.EV_ABS.ABS_Y] == 60
798-
assert not evdev.value[libevdev.EV_KEY.BTN_STYLUS]
799-
800-
p.barrelswitch = True
801-
events = self.post(uhdev, p)
802-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 1) in events
803-
804-
p.tipswitch = True
805-
events = self.post(uhdev, p)
806-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in events
807-
assert evdev.value[libevdev.EV_KEY.BTN_STYLUS]
808-
809-
p.x += 1
810-
p.y -= 1
811-
events = self.post(uhdev, p)
812-
assert len(events) == 3 # X, Y, SYN
813-
assert libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 51) in events
814-
assert libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 59) in events
815-
816-
p.tipswitch = False
817-
events = self.post(uhdev, p)
818-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 0) in events
819-
820-
p.barrelswitch = False
821-
p.inrange = False
822-
events = self.post(uhdev, p)
823-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0) in events
824-
assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 0) in events
825-
826796

827797
class GXTP_pen(PenDigitizer):
828798
def event(self, pen):

0 commit comments

Comments
 (0)