diff --git a/source/bdDetect.py b/source/bdDetect.py index cccec5f204b..8fa0e297f68 100644 --- a/source/bdDetect.py +++ b/source/bdDetect.py @@ -17,7 +17,7 @@ import itertools import threading from concurrent.futures import ThreadPoolExecutor, Future -from enum import StrEnum +from enum import Enum from typing import ( Any, Callable, @@ -53,15 +53,46 @@ USB_ID_REGEX = re.compile(r"^VID_[0-9A-F]{4}&PID_[0-9A-F]{4}$", re.U) -class DeviceType(StrEnum): +class ProtocolType(str, Enum): HID = "hid" """HID devices""" SERIAL = "serial" """Serial devices (COM ports)""" CUSTOM = "custom" - """Devices with a manufacturer specific driver""" + """Devices with a manufacturer specific protocol""" + + +class CommunicationType(str, Enum): BLUETOOTH = "bluetooth" """Bluetooth devices""" + USB = "usb" + """USB devices""" + + +class _DeviceTypeMeta(type): + # Mapping old attributes to the new enums + _mapping = { + "HID": ProtocolType.HID, + "SERIAL": ProtocolType.SERIAL, + "CUSTOM": ProtocolType.CUSTOM, + "BLUETOOTH": CommunicationType.BLUETOOTH, + } + + def __getattr__(cls, name: str) -> ProtocolType | CommunicationType: + repl = cls._mapping.get(name) + if repl is not None and NVDAState._allowDeprecatedAPI(): + log.warning( + f"{cls.__name__}.{name} is deprecated. Use {repl} instead.", + ) + return repl + raise AttributeError(f"'{cls.__name__}' object has no attribute '{name}'") + + +class DeviceType(metaclass=_DeviceTypeMeta): + """This class is kept for backwards compatibility. + Former members were split into the L{ProtocolType} and L{CommunicationType} enums.""" + + ... def __getattr__(attrName: str) -> Any: @@ -73,25 +104,25 @@ def __getattr__(attrName: str) -> Any: log.warning(f"{attrName} is deprecated.") return 2 _deprecatedConstantsMap = { - "KEY_HID": DeviceType.HID, - "KEY_SERIAL": DeviceType.SERIAL, - "KEY_BLUETOOTH": DeviceType.BLUETOOTH, - "KEY_CUSTOM": DeviceType.CUSTOM, + "KEY_HID": ProtocolType.HID, + "KEY_SERIAL": ProtocolType.SERIAL, + "KEY_BLUETOOTH": CommunicationType.BLUETOOTH, + "KEY_CUSTOM": ProtocolType.CUSTOM, } if attrName in _deprecatedConstantsMap and NVDAState._allowDeprecatedAPI(): replacementSymbol = _deprecatedConstantsMap[attrName] log.warning( - f"{attrName} is deprecated. " f"Use bdDetect.DeviceType.{replacementSymbol.name} instead. ", + f"{attrName} is deprecated. " f"Use bdDetect.{replacementSymbol} instead. ", ) - return replacementSymbol + return replacementSymbol.value raise AttributeError(f"module {repr(__name__)} has no attribute {repr(attrName)}") class DeviceMatch(NamedTuple): """Represents a detected device.""" - type: DeviceType - """The type of the device.""" + type: ProtocolType + """The protocol type of the device.""" id: str """The identifier of the device.""" port: str @@ -109,6 +140,8 @@ class _UsbDeviceRegistryEntry: id: str """The identifier of the device.""" + type: ProtocolType + """The protocol type of the device.""" useAsFallback: bool = field(default=False, compare=False) """ determine how a device is associated with a driver. @@ -123,9 +156,16 @@ class _UsbDeviceRegistryEntry: It takes a L{DeviceMatch} as its only argument and returns a C{bool} indicating whether it matched.""" + def matches(self, deviceMatch: DeviceMatch) -> bool: + """Returns whether this registry entry matches a specific device.""" + if deviceMatch.type != self.type or deviceMatch.id != self.id: + return False + if self.matchFunc is None: + return True + return self.matchFunc(deviceMatch) -DriverDictT = defaultdict[DeviceType, set[_UsbDeviceRegistryEntry] | MatchFuncT] +DriverDictT = defaultdict[CommunicationType, set[_UsbDeviceRegistryEntry] | MatchFuncT] _driverDevices = OrderedDict[str, DriverDictT]() scanForDevices = extensionPoints.Chain[Tuple[str, DeviceMatch]]() @@ -158,11 +198,11 @@ def getDriversForConnectedUsbDevices( @return: Generator of pairs of drivers and device information. """ usbCustomDeviceMatches = ( - DeviceMatch(DeviceType.CUSTOM, port["usbID"], port["devicePath"], port) + DeviceMatch(ProtocolType.CUSTOM, port["usbID"], port["devicePath"], port) for port in deviceInfoFetcher.usbDevices ) usbComDeviceMatches = ( - DeviceMatch(DeviceType.SERIAL, port["usbID"], port["port"], port) + DeviceMatch(ProtocolType.SERIAL, port["usbID"], port["port"], port) for port in deviceInfoFetcher.usbComPorts ) # Tee is used to ensure that the DeviceMatches aren't created multiple times. @@ -172,7 +212,7 @@ def getDriversForConnectedUsbDevices( # device matches), if one is found early the iteration can stop. usbHidDeviceMatches, usbHidDeviceMatchesForCustom = itertools.tee( ( - DeviceMatch(DeviceType.HID, port["usbID"], port["devicePath"], port) + DeviceMatch(ProtocolType.HID, port["usbID"], port["devicePath"], port) for port in deviceInfoFetcher.hidDevices if port["provider"] == "usb" ) @@ -183,21 +223,9 @@ def getDriversForConnectedUsbDevices( for driver, devs in _driverDevices.items(): if limitToDevices and driver not in limitToDevices: continue - for type, typeDefs in devs.items(): - if ( - match.type == type - and ( - typeDef := next( - ( - t - for t in typeDefs - if isinstance(t, _UsbDeviceRegistryEntry) and t.id == match.id - ), - None, - ) - ) - and (not callable(typeDef.matchFunc) or typeDef.matchFunc(match)) - ): + typeDefs = devs[CommunicationType.USB] + for typeDef in typeDefs: + if typeDef.matches(match): if typeDef.useAsFallback: fallbackDriversAndMatches.append({driver, match}) else: @@ -225,7 +253,7 @@ def _getStandardHidDriverName() -> str: def _isHIDUsagePageMatch(match: DeviceMatch, usagePage: int) -> bool: - return match.type == DeviceType.HID and match.deviceInfo.get("HIDUsagePage") == usagePage + return match.type == ProtocolType.HID and match.deviceInfo.get("HIDUsagePage") == usagePage def _isHIDBrailleMatch(match: DeviceMatch) -> bool: @@ -247,7 +275,7 @@ def getDriversForPossibleBluetoothDevices( @return: Generator of pairs of drivers and port information. """ btSerialMatchesForCustom = ( - DeviceMatch(DeviceType.SERIAL, port["bluetoothName"], port["port"], port) + DeviceMatch(ProtocolType.SERIAL, port["bluetoothName"], port["port"], port) for port in deviceInfoFetcher.comPorts if "bluetoothName" in port ) @@ -258,7 +286,7 @@ def getDriversForPossibleBluetoothDevices( # device matches), if one is found early the iteration can stop. btHidDevMatchesForHid, btHidDevMatchesForCustom = itertools.tee( ( - DeviceMatch(DeviceType.HID, port["hardwareID"], port["devicePath"], port) + DeviceMatch(ProtocolType.HID, port["hardwareID"], port["devicePath"], port) for port in deviceInfoFetcher.hidDevices if port["provider"] == "bluetooth" ) @@ -267,7 +295,7 @@ def getDriversForPossibleBluetoothDevices( for driver, devs in _driverDevices.items(): if limitToDevices and driver not in limitToDevices: continue - matchFunc = devs[DeviceType.BLUETOOTH] + matchFunc = devs[CommunicationType.BLUETOOTH] if not callable(matchFunc): continue if matchFunc(match): @@ -517,16 +545,16 @@ def getConnectedUsbDevicesForDriver(driver: str) -> Iterator[DeviceMatch]: """ usbDevs = itertools.chain( ( - DeviceMatch(DeviceType.CUSTOM, port["usbID"], port["devicePath"], port) + DeviceMatch(ProtocolType.CUSTOM, port["usbID"], port["devicePath"], port) for port in deviceInfoFetcher.usbDevices ), ( - DeviceMatch(DeviceType.HID, port["usbID"], port["devicePath"], port) + DeviceMatch(ProtocolType.HID, port["usbID"], port["devicePath"], port) for port in deviceInfoFetcher.hidDevices if port["provider"] == "usb" ), ( - DeviceMatch(DeviceType.SERIAL, port["usbID"], port["port"], port) + DeviceMatch(ProtocolType.SERIAL, port["usbID"], port["port"], port) for port in deviceInfoFetcher.usbComPorts ), ) @@ -538,23 +566,10 @@ def getConnectedUsbDevicesForDriver(driver: str) -> Iterator[DeviceMatch]: if _isHIDBrailleMatch(match): yield match else: - devs = _driverDevices[driver] - for type, typeDefs in devs.items(): - if ( - match.type == type - and ( - typeDef := next( - ( - t - for t in typeDefs - if isinstance(t, _UsbDeviceRegistryEntry) and t.id == match.id - ), - None, - ) - ) - and (not callable(typeDef.matchFunc) or typeDef.matchFunc(match)) - ): - if typeDef.useAsFallback: + devs = _driverDevices[driver][CommunicationType.USB] + for dev in devs: + if dev.matches(match): + if dev.useAsFallback: fallbackMatches.append(match) else: yield match @@ -572,17 +587,17 @@ def getPossibleBluetoothDevicesForDriver(driver: str) -> Iterator[DeviceMatch]: if driver == _getStandardHidDriverName(): matchFunc = _isHIDBrailleMatch else: - matchFunc = _driverDevices[driver][DeviceType.BLUETOOTH] + matchFunc = _driverDevices[driver][CommunicationType.BLUETOOTH] if not callable(matchFunc): return btDevs = itertools.chain( ( - DeviceMatch(DeviceType.SERIAL, port["bluetoothName"], port["port"], port) + DeviceMatch(ProtocolType.SERIAL, port["bluetoothName"], port["port"], port) for port in deviceInfoFetcher.comPorts if "bluetoothName" in port ), ( - DeviceMatch(DeviceType.HID, port["hardwareID"], port["devicePath"], port) + DeviceMatch(ProtocolType.HID, port["hardwareID"], port["devicePath"], port) for port in deviceInfoFetcher.hidDevices if port["provider"] == "bluetooth" ), @@ -693,7 +708,7 @@ def _getDriverDict(self) -> DriverDictT: def addUsbDevice( self, - type: DeviceType, + type: ProtocolType, id: str, useAsFallback: bool = False, matchFunc: MatchFuncT | None = None, @@ -719,8 +734,8 @@ def addUsbDevice( f"Invalid ID provided for driver {self._driver!r}, type {type!r}: " f"{id!r}", ) devs = self._getDriverDict() - driverUsb = devs[type] - driverUsb.add(_UsbDeviceRegistryEntry(id, useAsFallback, matchFunc)) + driverUsb = devs[CommunicationType.USB] + driverUsb.add(_UsbDeviceRegistryEntry(type, id, useAsFallback, matchFunc)) def addUsbDevices( self, @@ -752,8 +767,8 @@ def addUsbDevices( f"{', '.join(malformedIds)}", ) devs = self._getDriverDict() - driverUsb = devs[type] - driverUsb.update((_UsbDeviceRegistryEntry(id, useAsFallback, matchFunc) for id in ids)) + driverUsb = devs[CommunicationType.USB] + driverUsb.update((_UsbDeviceRegistryEntry(id, type, useAsFallback, matchFunc) for id in ids)) def addBluetoothDevices(self, matchFunc: MatchFuncT): """Associate Bluetooth HID or COM ports with the driver on this instance. @@ -762,7 +777,7 @@ def addBluetoothDevices(self, matchFunc: MatchFuncT): and returns a C{bool} indicating whether it matched. """ devs = self._getDriverDict() - devs[DeviceType.BLUETOOTH] = matchFunc + devs[CommunicationType.BLUETOOTH] = matchFunc def addDeviceScanner( self, diff --git a/source/braille.py b/source/braille.py index ba44325c07b..54a70dac138 100644 --- a/source/braille.py +++ b/source/braille.py @@ -3517,7 +3517,7 @@ def _getTryPorts( pass else: yield bdDetect.DeviceMatch( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, portInfo["bluetoothName" if "bluetoothName" in portInfo else "friendlyName"], portInfo["port"], portInfo, diff --git a/source/brailleDisplayDrivers/albatross/driver.py b/source/brailleDisplayDrivers/albatross/driver.py index 976f4a38c41..55a8568268e 100644 --- a/source/brailleDisplayDrivers/albatross/driver.py +++ b/source/brailleDisplayDrivers/albatross/driver.py @@ -12,7 +12,7 @@ import time from collections import deque -from bdDetect import DeviceType, DriverRegistrar +from bdDetect import DriverRegistrar, ProtocolType from logHandler import log from serial.win32 import ( PURGE_RXABORT, @@ -85,7 +85,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: DriverRegistrar): driverRegistrar.addUsbDevice( - DeviceType.SERIAL, + ProtocolType.SERIAL, VID_AND_PID, # Caiku Albatross 46/80 # Filter for bus reported device description, which should be "Albatross Braille Display". matchFunc=lambda match: match.deviceInfo.get("busReportedDeviceDescription") == BUS_DEVICE_DESC, diff --git a/source/brailleDisplayDrivers/alva.py b/source/brailleDisplayDrivers/alva.py index 0402bf31692..73f8aaf63be 100644 --- a/source/brailleDisplayDrivers/alva.py +++ b/source/brailleDisplayDrivers/alva.py @@ -158,7 +158,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.HID, + bdDetect.ProtocolType.HID, { "VID_0798&PID_0640", # BC640 "VID_0798&PID_0680", # BC680 @@ -216,7 +216,7 @@ def __init__(self, port="auto"): self._deviceId = None for portType, portId, port, portInfo in self._getTryPorts(port): - self.isHid = portType == bdDetect.DeviceType.HID + self.isHid = portType == bdDetect.ProtocolType.HID # Try talking to the display. try: if self.isHid: diff --git a/source/brailleDisplayDrivers/baum.py b/source/brailleDisplayDrivers/baum.py index 5ba90c7cc36..e734cf7e234 100644 --- a/source/brailleDisplayDrivers/baum.py +++ b/source/brailleDisplayDrivers/baum.py @@ -84,7 +84,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.HID, + bdDetect.ProtocolType.HID, { "VID_0904&PID_3001", # RefreshaBraille 18 "VID_0904&PID_6101", # VarioUltra 20 @@ -111,7 +111,7 @@ def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): ) driverRegistrar.addUsbDevices( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, { "VID_0403&PID_FE70", # Vario 40 "VID_0403&PID_FE71", # PocketVario @@ -164,7 +164,7 @@ def __init__(self, port="auto"): for portType, portId, port, portInfo in self._getTryPorts(port): # At this point, a port bound to this display has been found. # Try talking to the display. - self.isHid = portType == bdDetect.DeviceType.HID + self.isHid = portType == bdDetect.ProtocolType.HID try: if self.isHid: self._dev = hwIo.Hid(port, onReceive=self._onReceive) diff --git a/source/brailleDisplayDrivers/brailleNote.py b/source/brailleDisplayDrivers/brailleNote.py index e3ca3b471de..3d843cf8e3d 100644 --- a/source/brailleDisplayDrivers/brailleNote.py +++ b/source/brailleDisplayDrivers/brailleNote.py @@ -130,7 +130,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, { "VID_1C71&PID_C004", # Apex }, diff --git a/source/brailleDisplayDrivers/brailliantB.py b/source/brailleDisplayDrivers/brailliantB.py index 58f0e9ad324..cea8bb80658 100644 --- a/source/brailleDisplayDrivers/brailliantB.py +++ b/source/brailleDisplayDrivers/brailliantB.py @@ -90,7 +90,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.HID, + bdDetect.ProtocolType.HID, { "VID_1C71&PID_C111", # Mantis Q 40 "VID_1C71&PID_C101", # Chameleon 20 @@ -100,7 +100,7 @@ def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): matchFunc=bdDetect.HIDUsagePageMatchFuncFactory(HID_USAGE_PAGE), ) driverRegistrar.addUsbDevices( - bdDetect.DeviceType.HID, + bdDetect.ProtocolType.HID, { "VID_1C71&PID_C121", # Humanware BrailleOne 20 HID "VID_1C71&PID_CE01", # NLS eReader 20 HID @@ -111,7 +111,7 @@ def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): }, ) driverRegistrar.addUsbDevices( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, { "VID_1C71&PID_C005", # Brailliant BI 32, 40 and 80 "VID_1C71&PID_C021", # Brailliant BI 14 @@ -119,13 +119,13 @@ def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): ) driverRegistrar.addBluetoothDevices( lambda m: ( - m.type == bdDetect.DeviceType.SERIAL + m.type == bdDetect.ProtocolType.SERIAL and ( m.id.startswith("Brailliant B") or m.id == "Brailliant 80" or "BrailleNote Touch" in m.id ) ) or ( - m.type == bdDetect.DeviceType.HID + m.type == bdDetect.ProtocolType.HID and m.deviceInfo.get("manufacturer") == "Humanware" and ( ( @@ -158,7 +158,7 @@ def __init__(self, port="auto"): self.numCells = 0 for portType, portId, port, portInfo in self._getTryPorts(port): - self.isHid = portType == bdDetect.DeviceType.HID + self.isHid = portType == bdDetect.ProtocolType.HID # Try talking to the display. try: if self.isHid: diff --git a/source/brailleDisplayDrivers/eurobraille/driver.py b/source/brailleDisplayDrivers/eurobraille/driver.py index 2911d90b9fc..77d22c97df8 100644 --- a/source/brailleDisplayDrivers/eurobraille/driver.py +++ b/source/brailleDisplayDrivers/eurobraille/driver.py @@ -45,7 +45,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.HID, + bdDetect.ProtocolType.HID, { "VID_C251&PID_1122", # Esys (version < 3.0, no SD card "VID_C251&PID_1123", # Esys (version >= 3.0, with HID keyboard, no SD card @@ -67,7 +67,7 @@ def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): }, ) driverRegistrar.addUsbDevices( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, { "VID_28AC&PID_0012", # b.note "VID_28AC&PID_0013", # b.note 2 @@ -97,7 +97,7 @@ def __init__(self, port="Auto"): for portType, portId, port, portInfo in self._getTryPorts(port): # At this point, a port bound to this display has been found. # Try talking to the display. - self.isHid = portType == bdDetect.DeviceType.HID + self.isHid = portType == bdDetect.ProtocolType.HID try: if self.isHid: self._dev = hwIo.Hid( @@ -141,7 +141,7 @@ def __init__(self, port="Auto"): port=port, ), ) - if self.deviceType.startswith(("bnote", "bbook")): + if self.ProtocolType.startswith(("bnote", "bbook")): # send identifier to bnote / bbook with current COM port comportNumber = f'{int(re.match(".*?([0-9]+)$", port).group(1)):02d}' identifier = f"NVDA/{comportNumber}".encode() @@ -158,7 +158,7 @@ def __init__(self, port="Auto"): def terminate(self): try: - if self.deviceType.startswith(("bnote", "bbook")): + if self.ProtocolType.startswith(("bnote", "bbook")): # reset identifier to bnote / bbook with current COM port self._sendPacket(constants.EB_SYSTEM, constants.EB_CONNECTION_NAME, b"") super().terminate() @@ -287,7 +287,7 @@ def _handleKeyPacket(self, group: bytes, data: bytes): log.debug("Ignoring key repetition") return self.keysDown[group] |= arg - isIris = self.deviceType.startswith("Iris") + isIris = self.ProtocolType.startswith("Iris") if not isIris and group == constants.EB_KEY_COMMAND and arg >= self.keysDown[group]: # Started a gesture including command keys self._ignoreCommandKeyReleases = False diff --git a/source/brailleDisplayDrivers/eurobraille/gestures.py b/source/brailleDisplayDrivers/eurobraille/gestures.py index b02e307cb8b..4e056b4ebd6 100644 --- a/source/brailleDisplayDrivers/eurobraille/gestures.py +++ b/source/brailleDisplayDrivers/eurobraille/gestures.py @@ -162,7 +162,7 @@ class InputGesture(braille.BrailleDisplayGesture, brailleInput.BrailleInputGestu def __init__(self, display: "BrailleDisplayDriver"): super().__init__() - self.model = display.deviceType.lower().split(" ")[0] + self.model = display.ProtocolType.lower().split(" ")[0] keysDown = dict(display.keysDown) self.keyNames = names = [] diff --git a/source/brailleDisplayDrivers/freedomScientific.py b/source/brailleDisplayDrivers/freedomScientific.py index fe00e79e721..ce6ebb00901 100755 --- a/source/brailleDisplayDrivers/freedomScientific.py +++ b/source/brailleDisplayDrivers/freedomScientific.py @@ -199,7 +199,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.CUSTOM, + bdDetect.ProtocolType.CUSTOM, { "VID_0F4E&PID_0100", # Focus 1 "VID_0F4E&PID_0111", # PAC Mate @@ -243,7 +243,7 @@ def __init__(self, port="auto"): self.gestureMap.add("br(freedomScientific):rightWizWheelDown", *action[2]) super(BrailleDisplayDriver, self).__init__() for portType, portId, port, portInfo in self._getTryPorts(port): - self.isUsb = portType == bdDetect.DeviceType.CUSTOM + self.isUsb = portType == bdDetect.ProtocolType.CUSTOM # Try talking to the display. try: if self.isUsb: diff --git a/source/brailleDisplayDrivers/handyTech.py b/source/brailleDisplayDrivers/handyTech.py index a5a808027ef..e68555bf72d 100644 --- a/source/brailleDisplayDrivers/handyTech.py +++ b/source/brailleDisplayDrivers/handyTech.py @@ -689,7 +689,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, { "VID_0403&PID_6001", # FTDI chip "VID_0921&PID_1200", # GoHubs chip @@ -698,7 +698,7 @@ def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): # Newer Handy Tech displays have a native HID processor driverRegistrar.addUsbDevices( - bdDetect.DeviceType.HID, + bdDetect.ProtocolType.HID, { "VID_1FE4&PID_0054", # Active Braille "VID_1FE4&PID_0055", # Connect Braille @@ -723,7 +723,7 @@ def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): # Some older HT displays use a HID converter and an internal serial interface driverRegistrar.addUsbDevices( - bdDetect.DeviceType.HID, + bdDetect.ProtocolType.HID, { "VID_1FE4&PID_0003", # USB-HID adapter "VID_1FE4&PID_0074", # Braille Star 40 @@ -774,7 +774,7 @@ def __init__(self, port="auto"): for portType, portId, port, portInfo in self._getTryPorts(port): # At this point, a port bound to this display has been found. # Try talking to the display. - self.isHid = portType == bdDetect.DeviceType.HID + self.isHid = portType == bdDetect.ProtocolType.HID self.isHidSerial = portId in USB_IDS_HID_CONVERTER self.port = port try: diff --git a/source/brailleDisplayDrivers/hidBrailleStandard.py b/source/brailleDisplayDrivers/hidBrailleStandard.py index 3e06d5e3912..c7e27ea5300 100644 --- a/source/brailleDisplayDrivers/hidBrailleStandard.py +++ b/source/brailleDisplayDrivers/hidBrailleStandard.py @@ -95,7 +95,7 @@ def __init__(self, port="auto"): self.numCols = 0 for portType, portId, port, portInfo in self._getTryPorts(port): - if portType != bdDetect.DeviceType.HID: + if portType != bdDetect.ProtocolType.HID: continue # Try talking to the display. try: diff --git a/source/brailleDisplayDrivers/hims.py b/source/brailleDisplayDrivers/hims.py index a129c8c68fd..25bd648bebd 100644 --- a/source/brailleDisplayDrivers/hims.py +++ b/source/brailleDisplayDrivers/hims.py @@ -281,20 +281,20 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): deviceTypes = { - bdDetect.DeviceType.HID: ( + bdDetect.ProtocolType.HID: ( { "VID_045E&PID_940A", # Braille Edge3S 40 }, True, ), - bdDetect.DeviceType.CUSTOM: ( + bdDetect.ProtocolType.CUSTOM: ( { "VID_045E&PID_930A", # Braille Sense & Smart Beetle "VID_045E&PID_930B", # Braille EDGE 40 }, False, ), - bdDetect.DeviceType.SERIAL: ( + bdDetect.ProtocolType.SERIAL: ( { "VID_0403&PID_6001", "VID_1A86&PID_55D3", # Braille Edge2S 40 @@ -329,17 +329,17 @@ def __init__(self, port="auto"): for match in self._getTryPorts(port): portType, portId, port, portInfo = match - self.isBulk = portType == bdDetect.DeviceType.CUSTOM - self.isHID = portType == bdDetect.DeviceType.HID + self.isBulk = portType == bdDetect.ProtocolType.CUSTOM + self.isHID = portType == bdDetect.ProtocolType.HID # Try talking to the display. try: match portType: - case bdDetect.DeviceType.HID: + case bdDetect.ProtocolType.HID: self._dev = hwIo.Hid(port, onReceive=self._hidOnReceive) - case bdDetect.DeviceType.CUSTOM: + case bdDetect.ProtocolType.CUSTOM: # onReceiveSize based on max packet size according to USB endpoint information. self._dev = hwIo.Bulk(port, 0, 1, self._onReceive, onReceiveSize=64) - case bdDetect.DeviceType.SERIAL: + case bdDetect.ProtocolType.SERIAL: self._dev = hwIo.Serial( port, baudrate=BAUD_RATE, diff --git a/source/brailleDisplayDrivers/nattiqbraille.py b/source/brailleDisplayDrivers/nattiqbraille.py index d83955d8130..9088ed5c080 100644 --- a/source/brailleDisplayDrivers/nattiqbraille.py +++ b/source/brailleDisplayDrivers/nattiqbraille.py @@ -39,7 +39,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, { "VID_2341&PID_8036", # Atmel-based USB Serial for Nattiq nBraille }, diff --git a/source/brailleDisplayDrivers/seikantk.py b/source/brailleDisplayDrivers/seikantk.py index 28beb399ae2..e7e1b0d16b4 100644 --- a/source/brailleDisplayDrivers/seikantk.py +++ b/source/brailleDisplayDrivers/seikantk.py @@ -16,7 +16,7 @@ import serial import braille -from bdDetect import DeviceType, DeviceMatch, DriverRegistrar +from bdDetect import DeviceMatch, DriverRegistrar import brailleInput import inputCore import bdDetect @@ -107,7 +107,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: DriverRegistrar): driverRegistrar.addUsbDevices( - DeviceType.HID, + bdDetect.ProtocolType.HID, { vidpid, # Seika Notetaker }, @@ -134,8 +134,8 @@ def __init__(self, port: typing.Union[None, str, DeviceMatch]): log.debug(f"Seika Notetaker braille driver: ({port!r})") dev: typing.Optional[typing.Union[hwIo.Hid, hwIo.Serial]] = None for match in self._getTryPorts(port): - self.isHid = match.type == bdDetect.DeviceType.HID - self.isSerial = match.type == bdDetect.DeviceType.SERIAL + self.isHid = match.type == bdDetect.ProtocolType.HID + self.isSerial = match.type == bdDetect.ProtocolType.SERIAL try: if self.isHid: log.info("Trying Seika notetaker on USB-HID") diff --git a/source/brailleDisplayDrivers/superBrl.py b/source/brailleDisplayDrivers/superBrl.py index 10a28ee856a..beef924445f 100644 --- a/source/brailleDisplayDrivers/superBrl.py +++ b/source/brailleDisplayDrivers/superBrl.py @@ -34,7 +34,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def registerAutomaticDetection(cls, driverRegistrar: bdDetect.DriverRegistrar): driverRegistrar.addUsbDevices( - bdDetect.DeviceType.SERIAL, + bdDetect.ProtocolType.SERIAL, { "VID_10C4&PID_EA60", # SuperBraille 3.2 }, diff --git a/tests/unit/test_bdDetect.py b/tests/unit/test_bdDetect.py index 7a85583d376..180bb0f9b05 100644 --- a/tests/unit/test_bdDetect.py +++ b/tests/unit/test_bdDetect.py @@ -1,7 +1,7 @@ # A part of NonVisual Desktop Access (NVDA) # This file is covered by the GNU General Public License. # See the file COPYING for more details. -# Copyright (C) 2023 NV Access Limited, Babbage B.V., Leonard de Ruijter +# Copyright (C) 2023-2025 NV Access Limited, Babbage B.V., Leonard de Ruijter """Unit tests for the bdDetect module.""" diff --git a/user_docs/en/changes.md b/user_docs/en/changes.md index 09ac77a8150..8fcba6a107a 100644 --- a/user_docs/en/changes.md +++ b/user_docs/en/changes.md @@ -165,6 +165,7 @@ Please use `braille.filter_displayDimensions` instead. (#17011) * The following symbols are deprecated (#17486, @CyrilleB79): * `NoConsoleOptionParser`, `stringToBool`, `stringToLang` in `__main__`; use the same symbols in `argsParsing` instead. * `__main__.parser`; use `argsParsing.getParser()` instead. +* `bdDetect.DeviceType` is deprecated in favour of `bdDetect.ProtocolType` and `bdDetect.CommunicationType` to take into account the fact that both HID and Serial communication can take place over USB and Bluetooth. (#17537 , @LeonarddeR) ## 2024.4.1