新增模块覆盖: 系统层 (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 行代码
415 lines
15 KiB
Python
415 lines
15 KiB
Python
"""
|
|
Android Companion Device API — CompanionDeviceManager, AssociationInfo, DeviceFilters
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
import sys
|
|
from typing import Any, Dict, List, Optional, Set, Tuple, Callable
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
from ..java.lang import RuntimeException
|
|
|
|
|
|
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
|
|
|
|
__all__ = [
|
|
"CompanionDeviceManager",
|
|
"AssociationInfo",
|
|
"WifiDeviceFilter",
|
|
"BluetoothDeviceFilter",
|
|
"BluetoothLeDeviceFilter",
|
|
"CommsDevice",
|
|
"DeviceActivityCallback",
|
|
"CompanionService",
|
|
]
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# CompanionDeviceManager
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class CompanionDeviceManager(Stub):
|
|
"""CompanionDeviceManager — 配套设备管理器 (桌面存根)"""
|
|
|
|
EXTRA_DEVICE = "android.companion.extra.DEVICE"
|
|
EXTRA_ASSOCIATION = "android.companion.extra.ASSOCIATION"
|
|
|
|
def __init__(self, context: Any = None):
|
|
super().__init__()
|
|
self._context = context
|
|
self._associations: Dict[str, "AssociationInfo"] = {}
|
|
self._callbacks: List[Callable] = []
|
|
|
|
def associate(
|
|
self,
|
|
request: Any,
|
|
callback: "CompanionDeviceManager.Callback",
|
|
handler: Any = None,
|
|
):
|
|
"""发起设备关联请求"""
|
|
raise AndroidOnlyError("CompanionDeviceManager.associate() 仅在 Android 设备上可用")
|
|
|
|
def associateCallback(
|
|
self,
|
|
request: Any,
|
|
callback: Callable,
|
|
executor: Any = None,
|
|
):
|
|
"""使用回调方式发起设备关联"""
|
|
raise AndroidOnlyError("CompanionDeviceManager.associateCallback() 仅在 Android 设备上可用")
|
|
|
|
def requestNotificationAccess(self, pairingDevice: "AssociationInfo"):
|
|
"""请求通知访问权限"""
|
|
raise AndroidOnlyError("CompanionDeviceManager.requestNotificationAccess() 仅在 Android 设备上可用")
|
|
|
|
def requestSystemAppStore(self, pairingDevice: "AssociationInfo"):
|
|
"""请求系统应用商店"""
|
|
pass
|
|
|
|
def startObservingDevicePresence(self, deviceAddress: str):
|
|
"""开始监听设备存在"""
|
|
pass
|
|
|
|
def stopObservingDevicePresence(self, deviceAddress: str):
|
|
"""停止监听设备存在"""
|
|
pass
|
|
|
|
def isDeviceAssociated(self, deviceAddress: str) -> bool:
|
|
"""检查设备是否已关联"""
|
|
return deviceAddress in self._associations
|
|
|
|
def getDeviceId(self, deviceAddress: str) -> Optional[str]:
|
|
"""获取设备 ID"""
|
|
info = self._associations.get(deviceAddress)
|
|
return info.getSelfManagedDeviceId() if info else None
|
|
|
|
def getAssociations(self) -> List["AssociationInfo"]:
|
|
"""获取所有关联信息"""
|
|
return list(self._associations.values())
|
|
|
|
def removeAssociation(self, deviceAddress: str):
|
|
"""移除设备关联"""
|
|
self._associations.pop(deviceAddress, None)
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# Callback - 回调类
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class Callback(Stub):
|
|
"""CompanionDeviceManager.Callback — 设备发现回调"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onDeviceFound(self, intent: Any):
|
|
"""设备找到回调"""
|
|
pass
|
|
|
|
def onFailure(self, error: str):
|
|
"""设备发现失败回调"""
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"Callback@{hex(id(self))}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
def toString(self) -> str:
|
|
return f"CompanionDeviceManager(associations={len(self._associations)})"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# AssociationInfo
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class AssociationInfo(Stub):
|
|
"""AssociationInfo — 设备关联信息"""
|
|
|
|
def __init__(
|
|
self,
|
|
userId: int = 0,
|
|
deviceProfile: str = "",
|
|
selfManagedDeviceId: str = "",
|
|
associatedDevice: Any = None,
|
|
isSelfManaged: bool = False,
|
|
isNotAssociated: bool = False,
|
|
):
|
|
super().__init__()
|
|
self._user_id = userId
|
|
self._device_profile = deviceProfile
|
|
self._self_managed_device_id = selfManagedDeviceId
|
|
self._associated_device = associatedDevice
|
|
self._self_managed = isSelfManaged
|
|
self._not_associated = isNotAssociated
|
|
|
|
def getUserId(self) -> int:
|
|
return self._user_id
|
|
|
|
def getDeviceProfile(self) -> str:
|
|
return self._device_profile
|
|
|
|
def getSelfManagedDeviceId(self) -> str:
|
|
return self._self_managed_device_id
|
|
|
|
def getAssociatedDevice(self) -> Optional[Any]:
|
|
return self._associated_device
|
|
|
|
def isSelfManaged(self) -> bool:
|
|
return self._self_managed
|
|
|
|
def isNotAssociated(self) -> bool:
|
|
return self._not_associated
|
|
|
|
def toString(self) -> str:
|
|
return (f"AssociationInfo(deviceId={self._self_managed_device_id}, "
|
|
f"profile={self._device_profile})")
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, AssociationInfo):
|
|
return False
|
|
return self._self_managed_device_id == other._self_managed_device_id
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._self_managed_device_id) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# WifiDeviceFilter
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class WifiDeviceFilter(Stub):
|
|
"""WifiDeviceFilter — WiFi 设备过滤器"""
|
|
|
|
def __init__(self, namePattern: str = ""):
|
|
super().__init__()
|
|
self._name_pattern = namePattern
|
|
|
|
def getNamePattern(self) -> str:
|
|
return self._name_pattern
|
|
|
|
def toString(self) -> str:
|
|
return f"WifiDeviceFilter(pattern={self._name_pattern})"
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, WifiDeviceFilter):
|
|
return False
|
|
return self._name_pattern == other._name_pattern
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._name_pattern) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# BluetoothDeviceFilter
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class BluetoothDeviceFilter(Stub):
|
|
"""BluetoothDeviceFilter — 蓝牙设备过滤器"""
|
|
|
|
class Builder(Stub):
|
|
"""BluetoothDeviceFilter.Builder — 蓝牙过滤器构建器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._name_pattern = ""
|
|
self._address = ""
|
|
|
|
def setNamePattern(self, pattern: str) -> "BluetoothDeviceFilter.Builder":
|
|
self._name_pattern = pattern
|
|
return self
|
|
|
|
def setAddress(self, address: str) -> "BluetoothDeviceFilter.Builder":
|
|
self._address = address
|
|
return self
|
|
|
|
def build(self) -> "BluetoothDeviceFilter":
|
|
return BluetoothDeviceFilter(
|
|
namePattern=self._name_pattern,
|
|
address=self._address,
|
|
)
|
|
|
|
def toString(self) -> str:
|
|
return f"Builder(pattern={self._name_pattern})"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
def __init__(self, namePattern: str = "", address: str = ""):
|
|
super().__init__()
|
|
self._name_pattern = namePattern
|
|
self._address = address
|
|
|
|
def getNamePattern(self) -> str:
|
|
return self._name_pattern
|
|
|
|
def getAddress(self) -> str:
|
|
return self._address
|
|
|
|
def toString(self) -> str:
|
|
return f"BluetoothDeviceFilter(address={self._address})"
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, BluetoothDeviceFilter):
|
|
return False
|
|
return self._address == other._address
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._address) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# BluetoothLeDeviceFilter
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class BluetoothLeDeviceFilter(Stub):
|
|
"""BluetoothLeDeviceFilter — BLE 设备过滤器"""
|
|
|
|
class Builder(Stub):
|
|
"""BluetoothLeDeviceFilter.Builder — BLE 过滤器构建器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._name_pattern = ""
|
|
self._scan_filter = None
|
|
|
|
def setNamePattern(self, pattern: str) -> "BluetoothLeDeviceFilter.Builder":
|
|
self._name_pattern = pattern
|
|
return self
|
|
|
|
def setScanFilter(self, scanFilter: Any) -> "BluetoothLeDeviceFilter.Builder":
|
|
self._scan_filter = scanFilter
|
|
return self
|
|
|
|
def build(self) -> "BluetoothLeDeviceFilter":
|
|
return BluetoothLeDeviceFilter(
|
|
namePattern=self._name_pattern,
|
|
scanFilter=self._scan_filter,
|
|
)
|
|
|
|
def toString(self) -> str:
|
|
return f"BLEBuilder(pattern={self._name_pattern})"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
def __init__(self, namePattern: str = "", scanFilter: Any = None):
|
|
super().__init__()
|
|
self._name_pattern = namePattern
|
|
self._scan_filter = scanFilter
|
|
|
|
def getNamePattern(self) -> str:
|
|
return self._name_pattern
|
|
|
|
def getScanFilter(self) -> Optional[Any]:
|
|
return self._scan_filter
|
|
|
|
def toString(self) -> str:
|
|
return f"BluetoothLeDeviceFilter(pattern={self._name_pattern})"
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, BluetoothLeDeviceFilter):
|
|
return False
|
|
return self._name_pattern == other._name_pattern
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._name_pattern) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# CommsDevice
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class CommsDevice(Stub):
|
|
"""CommsDevice — 通信设备信息"""
|
|
|
|
def __init__(self, deviceId: str = "", displayName: str = ""):
|
|
super().__init__()
|
|
self._device_id = deviceId
|
|
self._display_name = displayName
|
|
|
|
def getDeviceId(self) -> str:
|
|
return self._device_id
|
|
|
|
def getDisplayName(self) -> str:
|
|
return self._display_name
|
|
|
|
def toString(self) -> str:
|
|
return f"CommsDevice(id={self._device_id}, name={self._display_name})"
|
|
|
|
def equals(self, other) -> bool:
|
|
if not isinstance(other, CommsDevice):
|
|
return False
|
|
return self._device_id == other._device_id
|
|
|
|
def hashCode(self) -> int:
|
|
return hash(self._device_id) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# DeviceActivityCallback
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class DeviceActivityCallback(Stub):
|
|
"""DeviceActivityCallback — 设备活动回调"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onDeviceActivityChanged(self, associationInfo: "AssociationInfo", active: bool):
|
|
"""设备活动状态变更回调"""
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"DeviceActivityCallback@{hex(id(self))}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# CompanionService
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class CompanionService(Stub):
|
|
"""CompanionService — 配套服务"""
|
|
|
|
SERVICE_INTERFACE = "android.companion.CompanionDeviceService"
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onConnected(self, deviceInfo: Any):
|
|
"""已连接回调"""
|
|
pass
|
|
|
|
def onDisconnected(self, deviceInfo: Any):
|
|
"""已断开回调"""
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"CompanionService@{hex(id(self))}"
|
|
|
|
def equals(self, other) -> bool:
|
|
return self is other
|
|
|
|
def hashCode(self) -> int:
|
|
return id(self) & 0x7FFFFFFF |