device: Remove hard dependency on hidapi
This commit is contained in:
parent
9907cb2875
commit
615499dce2
|
@ -19,13 +19,12 @@ import logging
|
|||
import threading
|
||||
import time
|
||||
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Optional
|
||||
from typing import Protocol
|
||||
from typing import cast
|
||||
|
||||
import hidapi
|
||||
|
||||
from solaar import configuration
|
||||
|
||||
from . import base
|
||||
|
@ -65,7 +64,9 @@ low_level_interface = cast(LowLevelInterface, base)
|
|||
|
||||
class DeviceFactory:
|
||||
@staticmethod
|
||||
def create_device(low_level: LowLevelInterface, device_info, setting_callback=None):
|
||||
def create_device(
|
||||
find_paired_node_func: Callable[[str, int, int], Any], low_level: LowLevelInterface, device_info, setting_callback=None
|
||||
):
|
||||
"""Opens a Logitech Device found attached to the machine, by Linux device path.
|
||||
:returns: An open file handle for the found receiver, or None.
|
||||
"""
|
||||
|
@ -74,6 +75,7 @@ class DeviceFactory:
|
|||
if handle:
|
||||
# a direct connected device might not be online (as reported by user)
|
||||
return Device(
|
||||
find_paired_node_func,
|
||||
low_level,
|
||||
None,
|
||||
None,
|
||||
|
@ -98,6 +100,7 @@ class Device:
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
find_paired_node_func: Callable[[str, int, int], Any],
|
||||
low_level: LowLevelInterface,
|
||||
receiver,
|
||||
number,
|
||||
|
@ -154,7 +157,7 @@ class Device:
|
|||
self.cleanups = [] # functions to run on the device when it is closed
|
||||
|
||||
if not self.path:
|
||||
self.path = hidapi.find_paired_node(receiver.path, number, 1) if receiver else None
|
||||
self.path = find_paired_node_func(receiver.path, number, 1) if receiver else None
|
||||
if not self.handle:
|
||||
try:
|
||||
self.handle = self.low_level.open_path(self.path) if self.path else None
|
||||
|
|
|
@ -24,6 +24,7 @@ from collections import namedtuple
|
|||
from functools import partial
|
||||
|
||||
import gi
|
||||
import hidapi
|
||||
import logitech_receiver
|
||||
|
||||
from logitech_receiver import base
|
||||
|
@ -257,7 +258,9 @@ def _start(device_info):
|
|||
if not isDevice:
|
||||
receiver_ = logitech_receiver.receiver.ReceiverFactory.create_receiver(device_info, _setting_callback)
|
||||
else:
|
||||
receiver_ = logitech_receiver.device.DeviceFactory.create_device(base, device_info, _setting_callback)
|
||||
receiver_ = logitech_receiver.device.DeviceFactory.create_device(
|
||||
hidapi.find_paired_node, base, device_info, _setting_callback
|
||||
)
|
||||
if receiver_:
|
||||
configuration.attach_to(receiver_)
|
||||
if receiver_.bluetooth and receiver_.hid_serial:
|
||||
|
|
|
@ -80,12 +80,12 @@ def test_create_device(device_info, responses, expected_success):
|
|||
low_level_mock = LowLevelInterfaceFake(responses)
|
||||
if expected_success is None:
|
||||
with pytest.raises(PermissionError):
|
||||
device.DeviceFactory.create_device(low_level_mock, device_info)
|
||||
device.DeviceFactory.create_device(mock.Mock(), low_level_mock, device_info)
|
||||
elif not expected_success:
|
||||
with pytest.raises(TypeError):
|
||||
device.DeviceFactory.create_device(low_level_mock, device_info)
|
||||
device.DeviceFactory.create_device(mock.Mock(), low_level_mock, device_info)
|
||||
else:
|
||||
test_device = device.DeviceFactory.create_device(low_level_mock, device_info)
|
||||
test_device = device.DeviceFactory.create_device(mock.Mock(), low_level_mock, device_info)
|
||||
assert bool(test_device) == expected_success
|
||||
|
||||
|
||||
|
@ -96,7 +96,7 @@ def test_create_device(device_info, responses, expected_success):
|
|||
def test_device_name(device_info, responses, expected_codename, expected_name, expected_kind):
|
||||
low_level = LowLevelInterfaceFake(responses)
|
||||
|
||||
test_device = device.DeviceFactory.create_device(low_level, device_info)
|
||||
test_device = device.DeviceFactory.create_device(mock.Mock(), low_level, device_info)
|
||||
|
||||
assert test_device.codename == expected_codename
|
||||
assert test_device.name == expected_name
|
||||
|
@ -124,7 +124,9 @@ def test_device_name(device_info, responses, expected_codename, expected_name, e
|
|||
),
|
||||
)
|
||||
def test_device_info(device_info, responses, handle, _name, _codename, number, protocol, registers):
|
||||
test_device = device.Device(LowLevelInterfaceFake(responses), None, None, None, handle=handle, device_info=device_info)
|
||||
test_device = device.Device(
|
||||
mock.Mock(), LowLevelInterfaceFake(responses), None, None, None, handle=handle, device_info=device_info
|
||||
)
|
||||
|
||||
assert test_device.handle == handle
|
||||
assert test_device._name == _name
|
||||
|
@ -152,12 +154,6 @@ class FakeReceiver:
|
|||
return True
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_hid():
|
||||
with mock.patch("hidapi.find_paired_node", return_value=None) as find_paired_node:
|
||||
yield find_paired_node
|
||||
|
||||
|
||||
pi_CCCC = {"wpid": "CCCC", "kind": 0, "serial": None, "polling": "1ms", "power_switch": "top"}
|
||||
pi_2011 = {"wpid": "2011", "kind": 1, "serial": "1234", "polling": "2ms", "power_switch": "bottom"}
|
||||
pi_4066 = {"wpid": "4066", "kind": 1, "serial": "5678", "polling": "4ms", "power_switch": "left"}
|
||||
|
@ -194,14 +190,14 @@ pi_DDDD = {"wpid": "DDDD", "kind": 2, "serial": "1234", "polling": "2ms", "power
|
|||
],
|
||||
),
|
||||
)
|
||||
def test_device_receiver(number, pairing_info, responses, handle, _name, codename, p, p2, name, mock_hid):
|
||||
mock_hid.side_effect = lambda x, y, z: x
|
||||
|
||||
def test_device_receiver(number, pairing_info, responses, handle, _name, codename, p, p2, name):
|
||||
low_level = LowLevelInterfaceFake(responses)
|
||||
low_level.request = partial(fake_hidpp.request, fake_hidpp.replace_number(responses, number))
|
||||
low_level.ping = partial(fake_hidpp.ping, fake_hidpp.replace_number(responses, number))
|
||||
|
||||
test_device = device.Device(low_level, FakeReceiver(codename="CODE"), number, True, pairing_info, handle=handle)
|
||||
test_device = device.Device(
|
||||
mock.Mock(), low_level, FakeReceiver(codename="CODE"), number, True, pairing_info, handle=handle
|
||||
)
|
||||
test_device.receiver.device = test_device
|
||||
|
||||
assert test_device.handle == handle
|
||||
|
@ -245,14 +241,12 @@ def test_device_receiver(number, pairing_info, responses, handle, _name, codenam
|
|||
["1ms", "2ms", "4ms", "8ms", "1ms", "9ms"], # polling rate
|
||||
),
|
||||
)
|
||||
def test_device_ids(number, info, responses, handle, unitId, modelId, tid, kind, firmware, serial, id, psl, rate, mock_hid):
|
||||
mock_hid.side_effect = lambda x, y, z: x
|
||||
|
||||
def test_device_ids(number, info, responses, handle, unitId, modelId, tid, kind, firmware, serial, id, psl, rate):
|
||||
low_level = LowLevelInterfaceFake(responses)
|
||||
low_level.request = partial(fake_hidpp.request, fake_hidpp.replace_number(responses, number))
|
||||
low_level.ping = partial(fake_hidpp.ping, fake_hidpp.replace_number(responses, number))
|
||||
|
||||
test_device = device.Device(low_level, FakeReceiver(), number, True, info, handle=handle)
|
||||
test_device = device.Device(mock.Mock(), low_level, FakeReceiver(), number, True, info, handle=handle)
|
||||
|
||||
assert test_device.unitId == unitId
|
||||
assert test_device.modelId == modelId
|
||||
|
@ -267,7 +261,7 @@ def test_device_ids(number, info, responses, handle, unitId, modelId, tid, kind,
|
|||
class FakeDevice(device.Device): # a fully functional Device but its HID++ functions look at local data
|
||||
def __init__(self, responses, *args, **kwargs):
|
||||
self.responses = responses
|
||||
super().__init__(LowLevelInterfaceFake(responses), *args, **kwargs)
|
||||
super().__init__(mock.Mock(), LowLevelInterfaceFake(responses), *args, **kwargs)
|
||||
|
||||
request = fake_hidpp.Device.request
|
||||
ping = fake_hidpp.Device.ping
|
||||
|
|
Loading…
Reference in New Issue