162306a36Sopenharmony_ci#!/bin/env python3
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
362306a36Sopenharmony_ci# -*- coding: utf-8 -*-
462306a36Sopenharmony_ci#
562306a36Sopenharmony_ci# Copyright (c) 2019 Benjamin Tissoires <benjamin.tissoires@gmail.com>
662306a36Sopenharmony_ci# Copyright (c) 2019 Red Hat, Inc.
762306a36Sopenharmony_ci#
862306a36Sopenharmony_ci
962306a36Sopenharmony_cifrom . import base
1062306a36Sopenharmony_ciimport libevdev
1162306a36Sopenharmony_ciimport pytest
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cifrom hidtools.device.base_gamepad import AsusGamepad, SaitekGamepad
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ciimport logging
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cilogger = logging.getLogger("hidtools.test.gamepad")
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciclass BaseTest:
2162306a36Sopenharmony_ci    class TestGamepad(base.BaseTestCase.TestUhid):
2262306a36Sopenharmony_ci        @pytest.fixture(autouse=True)
2362306a36Sopenharmony_ci        def send_initial_state(self):
2462306a36Sopenharmony_ci            """send an empty report to initialize the axes"""
2562306a36Sopenharmony_ci            uhdev = self.uhdev
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci            r = uhdev.event()
2862306a36Sopenharmony_ci            events = uhdev.next_sync_events()
2962306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci        def assert_button(self, button):
3262306a36Sopenharmony_ci            uhdev = self.uhdev
3362306a36Sopenharmony_ci            evdev = uhdev.get_evdev()
3462306a36Sopenharmony_ci            syn_event = self.syn_event
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci            buttons = {}
3762306a36Sopenharmony_ci            key = libevdev.evbit(uhdev.buttons_map[button])
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci            buttons[button] = True
4062306a36Sopenharmony_ci            r = uhdev.event(buttons=buttons)
4162306a36Sopenharmony_ci            expected_event = libevdev.InputEvent(key, 1)
4262306a36Sopenharmony_ci            events = uhdev.next_sync_events()
4362306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
4462306a36Sopenharmony_ci            self.assertInputEventsIn((syn_event, expected_event), events)
4562306a36Sopenharmony_ci            assert evdev.value[key] == 1
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci            buttons[button] = False
4862306a36Sopenharmony_ci            r = uhdev.event(buttons=buttons)
4962306a36Sopenharmony_ci            expected_event = libevdev.InputEvent(key, 0)
5062306a36Sopenharmony_ci            events = uhdev.next_sync_events()
5162306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
5262306a36Sopenharmony_ci            self.assertInputEventsIn((syn_event, expected_event), events)
5362306a36Sopenharmony_ci            assert evdev.value[key] == 0
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci        def test_buttons(self):
5662306a36Sopenharmony_ci            """check for button reliability."""
5762306a36Sopenharmony_ci            uhdev = self.uhdev
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci            for b in uhdev.buttons:
6062306a36Sopenharmony_ci                self.assert_button(b)
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci        def test_dual_buttons(self):
6362306a36Sopenharmony_ci            """check for button reliability when pressing 2 buttons"""
6462306a36Sopenharmony_ci            uhdev = self.uhdev
6562306a36Sopenharmony_ci            evdev = uhdev.get_evdev()
6662306a36Sopenharmony_ci            syn_event = self.syn_event
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci            # can change intended b1 b2 values
6962306a36Sopenharmony_ci            b1 = uhdev.buttons[0]
7062306a36Sopenharmony_ci            key1 = libevdev.evbit(uhdev.buttons_map[b1])
7162306a36Sopenharmony_ci            b2 = uhdev.buttons[1]
7262306a36Sopenharmony_ci            key2 = libevdev.evbit(uhdev.buttons_map[b2])
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci            buttons = {b1: True, b2: True}
7562306a36Sopenharmony_ci            r = uhdev.event(buttons=buttons)
7662306a36Sopenharmony_ci            expected_event0 = libevdev.InputEvent(key1, 1)
7762306a36Sopenharmony_ci            expected_event1 = libevdev.InputEvent(key2, 1)
7862306a36Sopenharmony_ci            events = uhdev.next_sync_events()
7962306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
8062306a36Sopenharmony_ci            self.assertInputEventsIn(
8162306a36Sopenharmony_ci                (syn_event, expected_event0, expected_event1), events
8262306a36Sopenharmony_ci            )
8362306a36Sopenharmony_ci            assert evdev.value[key1] == 1
8462306a36Sopenharmony_ci            assert evdev.value[key2] == 1
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci            buttons = {b1: False, b2: None}
8762306a36Sopenharmony_ci            r = uhdev.event(buttons=buttons)
8862306a36Sopenharmony_ci            expected_event = libevdev.InputEvent(key1, 0)
8962306a36Sopenharmony_ci            events = uhdev.next_sync_events()
9062306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
9162306a36Sopenharmony_ci            self.assertInputEventsIn((syn_event, expected_event), events)
9262306a36Sopenharmony_ci            assert evdev.value[key1] == 0
9362306a36Sopenharmony_ci            assert evdev.value[key2] == 1
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci            buttons = {b1: None, b2: False}
9662306a36Sopenharmony_ci            r = uhdev.event(buttons=buttons)
9762306a36Sopenharmony_ci            expected_event = libevdev.InputEvent(key2, 0)
9862306a36Sopenharmony_ci            events = uhdev.next_sync_events()
9962306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
10062306a36Sopenharmony_ci            self.assertInputEventsIn((syn_event, expected_event), events)
10162306a36Sopenharmony_ci            assert evdev.value[key1] == 0
10262306a36Sopenharmony_ci            assert evdev.value[key2] == 0
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci        def _get_libevdev_abs_events(self, which):
10562306a36Sopenharmony_ci            """Returns which ABS_* evdev axes are expected for the given stick"""
10662306a36Sopenharmony_ci            abs_map = self.uhdev.axes_map[which]
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci            x = abs_map["x"].evdev
10962306a36Sopenharmony_ci            y = abs_map["y"].evdev
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci            assert x
11262306a36Sopenharmony_ci            assert y
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci            return x, y
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci        def _test_joystick_press(self, which, data):
11762306a36Sopenharmony_ci            uhdev = self.uhdev
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci            libevdev_axes = self._get_libevdev_abs_events(which)
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci            r = None
12262306a36Sopenharmony_ci            if which == "left_stick":
12362306a36Sopenharmony_ci                r = uhdev.event(left=data)
12462306a36Sopenharmony_ci            else:
12562306a36Sopenharmony_ci                r = uhdev.event(right=data)
12662306a36Sopenharmony_ci            events = uhdev.next_sync_events()
12762306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci            for i, d in enumerate(data):
13062306a36Sopenharmony_ci                if d is not None and d != 127:
13162306a36Sopenharmony_ci                    assert libevdev.InputEvent(libevdev_axes[i], d) in events
13262306a36Sopenharmony_ci                else:
13362306a36Sopenharmony_ci                    assert libevdev.InputEvent(libevdev_axes[i]) not in events
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci        def test_left_joystick_press_left(self):
13662306a36Sopenharmony_ci            """check for the left joystick reliability"""
13762306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (63, None))
13862306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (0, 127))
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci        def test_left_joystick_press_right(self):
14162306a36Sopenharmony_ci            """check for the left joystick reliability"""
14262306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (191, 127))
14362306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (255, None))
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci        def test_left_joystick_press_up(self):
14662306a36Sopenharmony_ci            """check for the left joystick reliability"""
14762306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (None, 63))
14862306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (127, 0))
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci        def test_left_joystick_press_down(self):
15162306a36Sopenharmony_ci            """check for the left joystick reliability"""
15262306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (127, 191))
15362306a36Sopenharmony_ci            self._test_joystick_press("left_stick", (None, 255))
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci        def test_right_joystick_press_left(self):
15662306a36Sopenharmony_ci            """check for the right joystick reliability"""
15762306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (63, None))
15862306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (0, 127))
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci        def test_right_joystick_press_right(self):
16162306a36Sopenharmony_ci            """check for the right joystick reliability"""
16262306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (191, 127))
16362306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (255, None))
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci        def test_right_joystick_press_up(self):
16662306a36Sopenharmony_ci            """check for the right joystick reliability"""
16762306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (None, 63))
16862306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (127, 0))
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci        def test_right_joystick_press_down(self):
17162306a36Sopenharmony_ci            """check for the right joystick reliability"""
17262306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (127, 191))
17362306a36Sopenharmony_ci            self._test_joystick_press("right_stick", (None, 255))
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci        @pytest.mark.skip_if_uhdev(
17662306a36Sopenharmony_ci            lambda uhdev: "Hat switch" not in uhdev.fields,
17762306a36Sopenharmony_ci            "Device not compatible, missing Hat switch usage",
17862306a36Sopenharmony_ci        )
17962306a36Sopenharmony_ci        @pytest.mark.parametrize(
18062306a36Sopenharmony_ci            "hat_value,expected_evdev,evdev_value",
18162306a36Sopenharmony_ci            [
18262306a36Sopenharmony_ci                (0, "ABS_HAT0Y", -1),
18362306a36Sopenharmony_ci                (2, "ABS_HAT0X", 1),
18462306a36Sopenharmony_ci                (4, "ABS_HAT0Y", 1),
18562306a36Sopenharmony_ci                (6, "ABS_HAT0X", -1),
18662306a36Sopenharmony_ci            ],
18762306a36Sopenharmony_ci        )
18862306a36Sopenharmony_ci        def test_hat_switch(self, hat_value, expected_evdev, evdev_value):
18962306a36Sopenharmony_ci            uhdev = self.uhdev
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci            r = uhdev.event(hat_switch=hat_value)
19262306a36Sopenharmony_ci            events = uhdev.next_sync_events()
19362306a36Sopenharmony_ci            self.debug_reports(r, uhdev, events)
19462306a36Sopenharmony_ci            assert (
19562306a36Sopenharmony_ci                libevdev.InputEvent(
19662306a36Sopenharmony_ci                    libevdev.evbit("EV_ABS", expected_evdev), evdev_value
19762306a36Sopenharmony_ci                )
19862306a36Sopenharmony_ci                in events
19962306a36Sopenharmony_ci            )
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ciclass TestSaitekGamepad(BaseTest.TestGamepad):
20362306a36Sopenharmony_ci    def create_device(self):
20462306a36Sopenharmony_ci        return SaitekGamepad()
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ciclass TestAsusGamepad(BaseTest.TestGamepad):
20862306a36Sopenharmony_ci    def create_device(self):
20962306a36Sopenharmony_ci        return AsusGamepad()
210