Commit d07644524b65 ("HID: input: read battery capacity from its actual
report offset") fixed synchronous battery queries for reports that place
the capacity byte after status fields.Add a UHID mouse with the Magic Mouse 2 report layout and answer GET_REPORT with 90 04 5f. Read capacity before sending an input report so the test exercises the synchronous query path. Without the fix, it reads the status byte as 4%; with the fix, it reads capacity as 95%. Enable CONFIG_HID_BATTERY_STRENGTH in the HID selftest configuration. Link: https://bugzilla.kernel.org/show_bug.cgi?id=221263 Assisted-by: LLM Signed-off-by: Mason Camara <[email protected]> --- Changes in v2: - Drop driver fix, superseded by d07644524b65. - Rebase the regression test onto the current HID for-next branch. - Amend commit message and tool-assistance trailer. v1: https://lore.kernel.org/linux-input/[email protected]/ tools/testing/selftests/hid/config | 1 + .../testing/selftests/hid/tests/test_mouse.py | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/tools/testing/selftests/hid/config b/tools/testing/selftests/hid/config index 1758b055f..da52335b8 100644 --- a/tools/testing/selftests/hid/config +++ b/tools/testing/selftests/hid/config @@ -16,6 +16,7 @@ CONFIG_FTRACE_SYSCALLS=y CONFIG_FUNCTION_TRACER=y CONFIG_HIDRAW=y CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HID_BPF=y CONFIG_INPUT_EVDEV=y CONFIG_UHID=y diff --git a/tools/testing/selftests/hid/tests/test_mouse.py b/tools/testing/selftests/hid/tests/test_mouse.py index eb4e15a0e..141c1f069 100644 --- a/tools/testing/selftests/hid/tests/test_mouse.py +++ b/tools/testing/selftests/hid/tests/test_mouse.py @@ -11,6 +11,7 @@ import hidtools.hid from hidtools.util import BusType import libevdev import logging +import threading import pytest logger = logging.getLogger("hidtools.test.mouse") @@ -598,6 +599,35 @@ class ResolutionMultiplierHWheelMouse(TwoWheelMouse): return 0 +class BatteryOffsetMouse(BaseMouse): + report_descriptor = [ + # Mouse report + 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x12, + 0x05, 0x09, 0x19, 0x01, 0x29, 0x02, 0x15, 0x00, + 0x25, 0x01, 0x95, 0x02, 0x75, 0x01, 0x81, 0x02, + 0x95, 0x01, 0x75, 0x06, 0x81, 0x01, 0x05, 0x01, + 0x09, 0x01, 0xa1, 0x00, 0x09, 0x30, 0x09, 0x31, + 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x02, + 0x81, 0x06, 0xc0, 0xc0, + # Battery report: one status byte followed by capacity + 0x06, 0x00, 0xff, 0x09, 0x14, 0xa1, 0x01, 0x85, + 0x90, 0x05, 0x84, 0x75, 0x01, 0x95, 0x03, 0x15, + 0x00, 0x25, 0x01, 0x09, 0x61, 0x05, 0x85, 0x09, + 0x44, 0x09, 0x46, 0x81, 0x02, 0x95, 0x05, 0x81, + 0x01, 0x75, 0x08, 0x95, 0x01, 0x15, 0x00, 0x26, + 0xff, 0x00, 0x09, 0x65, 0x81, 0x02, 0xc0, + ] + + def __init__(self, rdesc=report_descriptor, name=None, input_info=None): + super().__init__(rdesc, name, input_info) + + def get_report(self, req, rnum, rtype): + if rtype != self.UHID_INPUT_REPORT or rnum != 0x90: + return (1, []) + + return (0, [0x90, 0x04, 0x5F]) + + class BaseTest: class TestMouse(base.BaseTestCase.TestUhid): def test_buttons(self): @@ -1045,3 +1075,27 @@ class TestBadReportDescriptorMouse(base.BaseTestCase.TestUhid): def assertName(self, uhdev): pass + + +class TestBatteryOffsetMouse(base.BaseTestCase.TestUhid): + def create_device(self): + return BatteryOffsetMouse() + + def test_queried_battery_field_offset(self): + uhdev = self.uhdev + power_supply = uhdev.power_supply_class + assert power_supply is not None + + done = False + + def dispatch(): + while not done: + uhdev.dispatch(1) + + thread = threading.Thread(target=dispatch) + thread.start() + try: + assert power_supply.capacity == 95 + finally: + done = True + thread.join() base-commit: 931aaa59d1826f43b0bb3f07e21233f6faf4540a -- 2.39.5 (Apple Git-154)

