新增模块覆盖: 系统层 (14): system, security, print, opengl, renderscript, transition, test, service_notification, service_controls, service_quicksettings, service_wallpaper, service_autofill, service_dreams, service_vr 应用层 (13): app_admin, app_backup, app_job, app_usage, app_role, app_people, appwidget, companion, credentials, mtp, sip, telecom, speech 硬件媒体层 (15): hardware_display, hardware_fingerprint, hardware_usb, hardware_input, media_audiofx, media_browse, media_session, media_tv, media_midi, media_projection, uwb, se, view_autofill, view_textclassifier, view_translation 总计 94 个模块,75,342 行代码
409 lines
14 KiB
Python
409 lines
14 KiB
Python
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",
|
|
] |