from __future__ import annotations """ Android hardware.usb 组件 — UsbManager, UsbDevice, UsbDeviceConnection 等 方法签名完全对齐 Android SDK """ from typing import Any, Dict, List, Optional, Set from .._core import Stub, AndroidOnlyError # ═══════════════════════════════════════════════════════════════ # UsbConstants # ═══════════════════════════════════════════════════════════════ class UsbConstants(Stub): """UsbConstants — USB 常量""" USB_DIR_IN = 0x80 USB_DIR_OUT = 0 USB_TYPE_MASK = 0x60 USB_TYPE_CLASS = 0x20 USB_TYPE_VENDOR = 0x40 USB_TYPE_STANDARD = 0x00 USB_ENDPOINT_XFER_CONTROL = 0 USB_ENDPOINT_XFER_ISOC = 1 USB_ENDPOINT_XFER_BULK = 2 USB_ENDPOINT_XFER_INT = 3 USB_CLASS_APP_SPEC = 0xFE USB_CLASS_AUDIO = 0x01 USB_CLASS_CDC_DATA = 0x0A USB_CLASS_COMM = 0x02 USB_CLASS_CONTENT_SEC = 0x0D USB_CLASS_CSCID = 0x0B USB_CLASS_HID = 0x03 USB_CLASS_HUB = 0x09 USB_CLASS_MASS_STORAGE = 0x08 USB_CLASS_MISC = 0xEF USB_CLASS_PER_INTERFACE = 0x00 USB_CLASS_PHYSICA = 0x05 USB_CLASS_PRINTER = 0x07 USB_CLASS_STILL_IMAGE = 0x06 USB_CLASS_VENDOR_SPEC = 0xFF USB_CLASS_VIDEO = 0x0E USB_CLASS_WIRELESS = 0xE0 # ═══════════════════════════════════════════════════════════════ # UsbManager # ═══════════════════════════════════════════════════════════════ class UsbManager(Stub): """UsbManager — USB 管理器""" ACTION_USB_DEVICE_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED" ACTION_USB_DEVICE_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED" ACTION_USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED" ACTION_USB_ACCESSORY_DETACHED = "android.hardware.usb.action.USB_ACCESSORY_DETACHED" EXTRA_DEVICE = "device" EXTRA_ACCESSORY = "accessory" EXTRA_PERMISSION_GRANTED = "permission" def __init__(self): super().__init__() self._devices: Dict[str, UsbDevice] = {} self._permissions: Set[str] = set() self._accessories: List[UsbAccessory] = [] self._connections: Dict[str, UsbDeviceConnection] = {} # Create some mock devices self._devices["001"] = UsbDevice( deviceId=1, deviceName="/dev/bus/usb/001/001", vendorId=0x18D1, productId=0x4EE1, deviceClass=UsbConstants.USB_CLASS_MISC, deviceSubclass=0, deviceProtocol=0, manufacturerName="Google", productName="Pixel Device", version="3.1", serialNumber="ABC123" ) def getDeviceList(self) -> Dict[str, UsbDevice]: return dict(self._devices) def openDevice(self, device: "UsbDevice") -> Optional["UsbDeviceConnection"]: if not device: return None conn = UsbDeviceConnection(device) self._connections[str(device.getDeviceId())] = conn return conn def hasPermission(self, device: "UsbDevice") -> bool: return device.getDeviceName() in self._permissions def requestPermission(self, device: "UsbDevice"): self._permissions.add(device.getDeviceName()) def grantPermission(self, device: "UsbDevice"): self._permissions.add(device.getDeviceName()) def revokePermission(self, device: "UsbDevice"): self._permissions.discard(device.getDeviceName()) def setCurrentFunction(self, function: str, usbDataUnlocked: bool = False): pass def setUsbDataUnlocked(self, unlocked: bool): pass def getCurrentAccessory(self) -> Optional["UsbAccessory"]: return self._accessories[0] if self._accessories else None def openAccessory(self, accessory: "UsbAccessory") -> Optional["UsbDeviceConnection"]: if not accessory: return None conn = UsbDeviceConnection(accessory) return conn # ═══════════════════════════════════════════════════════════════ # UsbDevice # ═══════════════════════════════════════════════════════════════ class UsbDevice(Stub): """UsbDevice — USB 设备""" def __init__(self, deviceId: int = 0, deviceName: str = "", vendorId: int = 0, productId: int = 0, deviceClass: int = 0, deviceSubclass: int = 0, deviceProtocol: int = 0, configurationCount: int = 1, interfaceCount: int = 0, manufacturerName: str = "", productName: str = "", version: str = "", serialNumber: str = ""): super().__init__() self._device_id = deviceId self._device_name = deviceName self._vendor_id = vendorId self._product_id = productId self._device_class = deviceClass self._device_subclass = deviceSubclass self._device_protocol = deviceProtocol self._configuration_count = configurationCount self._interface_count = interfaceCount self._manufacturer_name = manufacturerName self._product_name = productName self._version = version self._serial_number = serialNumber self._interfaces: List[UsbInterface] = [] def getDeviceId(self) -> int: return self._device_id def getDeviceName(self) -> str: return self._device_name def getVendorId(self) -> int: return self._vendor_id def getProductId(self) -> int: return self._product_id def getDeviceClass(self) -> int: return self._device_class def getDeviceSubclass(self) -> int: return self._device_subclass def getDeviceProtocol(self) -> int: return self._device_protocol def getConfigurationCount(self) -> int: return self._configuration_count def getInterfaceCount(self) -> int: return len(self._interfaces) def getInterface(self, index: int) -> Optional["UsbInterface"]: if 0 <= index < len(self._interfaces): return self._interfaces[index] return None def getInterfaces(self) -> List["UsbInterface"]: return list(self._interfaces) def getManufacturerName(self) -> str: return self._manufacturer_name def getProductName(self) -> str: return self._product_name def getVersion(self) -> str: return self._version def getSerialNumber(self) -> str: return self._serial_number def describeContents(self) -> int: return 0 def equals(self, other: Any) -> bool: if not isinstance(other, UsbDevice): return False return self._device_id == other._device_id def hashCode(self) -> int: return hash(self._device_id) & 0x7FFFFFFF def toString(self) -> str: return f"UsbDevice(name={self._device_name}, vid={self._vendor_id:x}," \ f" pid={self._product_id:x})" # ═══════════════════════════════════════════════════════════════ # UsbDeviceConnection # ═══════════════════════════════════════════════════════════════ class UsbDeviceConnection(Stub): """UsbDeviceConnection — USB 设备连接""" def __init__(self, device: Any): super().__init__() self._device = device self._claimed_interfaces: Set[int] = set() self._fd = -1 def claimInterface(self, intf: "UsbInterface", force: bool = False) -> bool: self._claimed_interfaces.add(intf.getId()) return True def releaseInterface(self, intf: "UsbInterface") -> bool: self._claimed_interfaces.discard(intf.getId()) return True def bulkTransfer(self, endpoint: "UsbEndpoint", buffer: bytes, length: int, timeout: int) -> int: return -1 def controlTransfer(self, requestType: int, request: int, value: int, index: int, buffer: bytes, length: int, timeout: int) -> int: return -1 def getRawDescriptors(self) -> bytes: return b"" def getFileDescriptor(self) -> int: return self._fd def serial(self) -> Optional[str]: if hasattr(self._device, 'getSerialNumber'): return self._device.getSerialNumber() return None def close(self): self._claimed_interfaces.clear() def toString(self) -> str: return f"UsbDeviceConnection(device={self._device})" # ═══════════════════════════════════════════════════════════════ # UsbInterface # ═══════════════════════════════════════════════════════════════ class UsbInterface(Stub): """UsbInterface — USB 接口""" def __init__(self, id: int = 0, alternateSetting: int = 0, name: str = "", interfaceClass: int = 0, interfaceSubclass: int = 0, interfaceProtocol: int = 0): super().__init__() self._id = id self._alternate_setting = alternateSetting self._name = name self._interface_class = interfaceClass self._interface_subclass = interfaceSubclass self._interface_protocol = interfaceProtocol self._endpoints: List[UsbEndpoint] = [] def getId(self) -> int: return self._id def getAlternateSetting(self) -> int: return self._alternate_setting def getName(self) -> str: return self._name def getInterfaceClass(self) -> int: return self._interface_class def getInterfaceSubclass(self) -> int: return self._interface_subclass def getInterfaceProtocol(self) -> int: return self._interface_protocol def getEndpointCount(self) -> int: return len(self._endpoints) def getEndpoint(self, index: int) -> Optional["UsbEndpoint"]: if 0 <= index < len(self._endpoints): return self._endpoints[index] return None def toString(self) -> str: return f"UsbInterface(id={self._id}, name={self._name})" # ═══════════════════════════════════════════════════════════════ # UsbEndpoint # ═══════════════════════════════════════════════════════════════ class UsbEndpoint(Stub): """UsbEndpoint — USB 端点""" def __init__(self, address: int = 0, endpointNumber: int = 0, attributes: int = 0, direction: int = 0, maxPacketSize: int = 64, interval: int = 0, type_: int = 0): super().__init__() self._address = address self._endpoint_number = endpointNumber self._attributes = attributes self._direction = direction self._max_packet_size = maxPacketSize self._interval = interval self._type = type_ def getAddress(self) -> int: return self._address def getEndpointNumber(self) -> int: return self._endpoint_number def getAttributes(self) -> int: return self._attributes def getDirection(self) -> int: return self._direction def getMaxPacketSize(self) -> int: return self._max_packet_size def getInterval(self) -> int: return self._interval def getType(self) -> int: return self._type def toString(self) -> str: return f"UsbEndpoint(addr={self._address:#04x}, type={self._type})" # ═══════════════════════════════════════════════════════════════ # UsbAccessory # ═══════════════════════════════════════════════════════════════ class UsbAccessory(Stub): """UsbAccessory — USB 附件""" def __init__(self, manufacturer: str = "", model: str = "", description: str = "", version: str = "", uri: str = "", serial: str = ""): super().__init__() self._manufacturer = manufacturer self._model = model self._description = description self._version = version self._uri = uri self._serial = serial def getManufacturer(self) -> str: return self._manufacturer def getModel(self) -> str: return self._model def getDescription(self) -> str: return self._description def getVersion(self) -> str: return self._version def getUri(self) -> str: return self._uri def getSerial(self) -> str: return self._serial def toString(self) -> str: return f"UsbAccessory(manufacturer={self._manufacturer}, model={self._model})" # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "UsbManager", "UsbDevice", "UsbDeviceConnection", "UsbInterface", "UsbEndpoint", "UsbConstants", "UsbAccessory", ]