""" Android hardware.location 包 — ContextHubManager, ContextHubClient, ContextHubInfo, NanoApp, NanoAppInstanceInfo, NanoAppFilter 等 方法签名完全对齐 Android SDK """ from __future__ import annotations from typing import Any, Callable, Dict, List, Optional, Tuple from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) __all__ = [ "ContextHubManager", "ContextHubClient", "ContextHubInfo", "ContextHubTransaction", "ContextHubIntentEvent", "ContextHubService", "ContextHubServiceCallback", "NanoApp", "NanoAppInstanceInfo", "NanoAppFilter", "NanoAppMessage", "NanoAppRpcService", "NanoAppStateInfo", "ContextHubManagerCallback", ] # ═══════════════════════════════════════════════════════════════ # 常量 # ═══════════════════════════════════════════════════════════════ HUB_TYPE_PRIMARY = 0 HUB_TYPE_SECONDARY = 1 HUB_TYPE_VIRTUAL = 2 HUB_STATUS_OK = 0 HUB_STATUS_ERROR = -1 HUB_STATUS_TIMEOUT = -2 HUB_STATUS_BUSY = -3 HUB_STATUS_NOT_FOUND = -4 HUB_STATUS_INVALID_PARAM = -5 HUB_STATUS_UNSUPPORTED = -6 HUB_STATUS_DISABLED = -7 HUB_STATUS_RESTARTING = -8 HUB_STATUS_LOW_POWER = -9 TRANSACTION_SUCCESS = 0 TRANSACTION_FAILURE = -1 TRANSACTION_PENDING = 1 TRANSACTION_CANCELLED = -2 TRANSACTION_TYPE_LOAD_NANOAPP = 0 TRANSACTION_TYPE_UNLOAD_NANOAPP = 1 TRANSACTION_TYPE_QUERY_NANOAPPS = 2 TRANSACTION_TYPE_QUERY_MEMORY = 3 TRANSACTION_TYPE_RESET_HUB = 4 TRANSACTION_TYPE_ENABLE_NANOAPP = 5 TRANSACTION_TYPE_DISABLE_NANOAPP = 6 TRANSACTION_TYPE_QUERY_NANOAPP_DETAILS = 7 TRANSACTION_TYPE_CONFIGURE_HUB = 8 TRANSACTION_TYPE_SET_NANOAPP_LOADED = 9 NANOAPP_STATE_NOT_LOADED = 0 NANOAPP_STATE_LOADING = 1 NANOAPP_STATE_LOADED = 2 NANOAPP_STATE_UNLOADING = 3 NANOAPP_STATE_RUNNING = 4 NANOAPP_STATE_SUSPENDED = 5 NANOAPP_STATE_ERROR = 6 NANOAPP_STATE_STOPPED = 7 NANOAPP_STATE_CRASHED = 8 NANOAPP_FLAG_ENABLED = 1 NANOAPP_FLAG_DISABLED = 2 NANOAPP_FLAG_SYSTEM = 4 NANOAPP_FLAG_VENDOR = 8 NANOAPP_FLAG_SIGNED = 16 NANOAPP_FLAG_DEBUG = 32 NANOAPP_TYPE_ANY = -1 NANOAPP_TYPE_SENSOR = 0 NANOAPP_TYPE_AUDIO = 1 NANOAPP_TYPE_LOCATION = 2 NANOAPP_TYPE_ACTIVITY = 3 NANOAPP_TYPE_CONTEXT = 4 NANOAPP_TYPE_COMMUNICATION = 5 NANOAPP_TYPE_SECURITY = 6 NANOAPP_TYPE_CUSTOM = 100 # ═══════════════════════════════════════════════════════════════ # NanoApp # ═══════════════════════════════════════════════════════════════ class NanoApp(Stub): """NanoApp — Nano 应用程序""" def __init__(self, id: int = 0, name: str = "", vendor: str = "", version: int = 1, size: int = 0, type_: int = NANOAPP_TYPE_CUSTOM, binary: bytes = b"", flags: int = 0, description: str = ""): super().__init__() self._id = id self._name = name self._vendor = vendor self._version = version self._size = size if size > 0 else len(binary) self._type = type_ self._binary = binary self._flags = flags self._description = description def getId(self) -> int: return self._id def getName(self) -> str: return self._name def getVendor(self) -> str: return self._vendor def getVersion(self) -> int: return self._version def getSize(self) -> int: return self._size def getType(self) -> int: return self._type def getBinary(self) -> bytes: return self._binary def getFlags(self) -> int: return self._flags def getDescription(self) -> str: return self._description def toString(self) -> str: return f"NanoApp(id={self._id}, name={self._name}, version={self._version})" def equals(self, other: Any) -> bool: if not isinstance(other, NanoApp): return False return self._id == other._id def hashCode(self) -> int: return self._id & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # NanoAppMessage # ═══════════════════════════════════════════════════════════════ class NanoAppMessage(Stub): """NanoAppMessage — NanoApp 消息""" def __init__(self, nanoAppId: int = 0, messageType: int = 0, data: bytes = b"", isReliable: bool = False, isSequenced: bool = True): super().__init__() self._nano_app_id = nanoAppId self._message_type = messageType self._data = data self._is_reliable = isReliable self._is_sequenced = isSequenced def getNanoAppId(self) -> int: return self._nano_app_id def getMessageType(self) -> int: return self._message_type def getData(self) -> bytes: return self._data def isReliable(self) -> bool: return self._is_reliable def isSequenced(self) -> bool: return self._is_sequenced def toString(self) -> str: return f"NanoAppMessage(appId={self._nano_app_id}, type={self._message_type})" def equals(self, other: Any) -> bool: if not isinstance(other, NanoAppMessage): return False return self._nano_app_id == other._nano_app_id and self._message_type == other._message_type def hashCode(self) -> int: return hash((self._nano_app_id, self._message_type)) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # NanoAppInstanceInfo # ═══════════════════════════════════════════════════════════════ class NanoAppInstanceInfo(Stub): """NanoAppInstanceInfo — NanoApp 实例信息""" def __init__(self, id: int = 0, name: str = "", vendor: str = "", version: int = 1, state: int = NANOAPP_STATE_NOT_LOADED, type_: int = NANOAPP_TYPE_CUSTOM, flags: int = 0, memUsage: int = 0, handle: int = 0, isEnabled: bool = True): super().__init__() self._id = id self._name = name self._vendor = vendor self._version = version self._state = state self._type = type_ self._flags = flags self._mem_usage = memUsage self._handle = handle self._is_enabled = isEnabled def getId(self) -> int: return self._id def getName(self) -> str: return self._name def getVendor(self) -> str: return self._vendor def getVersion(self) -> int: return self._version def getState(self) -> int: return self._state def getType(self) -> int: return self._type def getFlags(self) -> int: return self._flags def getMemUsage(self) -> int: return self._mem_usage def getHandle(self) -> int: return self._handle def isEnabled(self) -> bool: return self._is_enabled def toString(self) -> str: return f"NanoAppInstanceInfo(id={self._id}, name={self._name}, state={self._state})" def equals(self, other: Any) -> bool: if not isinstance(other, NanoAppInstanceInfo): return False return self._id == other._id def hashCode(self) -> int: return self._id & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # NanoAppFilter # ═══════════════════════════════════════════════════════════════ class NanoAppFilter(Stub): """NanoAppFilter — NanoApp 过滤器""" def __init__(self, nanoAppId: int = -1, type_: int = NANOAPP_TYPE_ANY, vendor: str = "", name: str = "", minVersion: int = 0, maxVersion: int = -1, flags: int = 0): super().__init__() self._nano_app_id = nanoAppId self._type = type_ self._vendor = vendor self._name = name self._min_version = minVersion self._max_version = maxVersion self._flags = flags def getNanoAppId(self) -> int: return self._nano_app_id def getType(self) -> int: return self._type def getVendor(self) -> str: return self._vendor def getName(self) -> str: return self._name def getMinVersion(self) -> int: return self._min_version def getMaxVersion(self) -> int: return self._max_version def getFlags(self) -> int: return self._flags def matches(self, info: NanoAppInstanceInfo) -> bool: if self._nano_app_id != -1 and info.getId() != self._nano_app_id: return False if self._type != NANOAPP_TYPE_ANY and info.getType() != self._type: return False if self._vendor and self._vendor != info.getVendor(): return False return True class Builder(Stub): """NanoAppFilter.Builder — 过滤器构建器""" def __init__(self): super().__init__() self._nano_app_id = -1 self._type = NANOAPP_TYPE_ANY self._vendor = "" self._name = "" self._min_version = 0 self._max_version = -1 self._flags = 0 def setNanoAppId(self, id: int) -> "NanoAppFilter.Builder": self._nano_app_id = id return self def setType(self, type_: int) -> "NanoAppFilter.Builder": self._type = type_ return self def setVendor(self, vendor: str) -> "NanoAppFilter.Builder": self._vendor = vendor return self def build(self) -> "NanoAppFilter": return NanoAppFilter( nanoAppId=self._nano_app_id, type_=self._type, vendor=self._vendor, name=self._name, minVersion=self._min_version, maxVersion=self._max_version, flags=self._flags, ) def toString(self) -> str: return f"NanoAppFilter(id={self._nano_app_id}, type={self._type})" def equals(self, other: Any) -> bool: if not isinstance(other, NanoAppFilter): return False return (self._nano_app_id == other._nano_app_id and self._type == other._type) def hashCode(self) -> int: return hash((self._nano_app_id, self._type)) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # NanoAppRpcService # ═══════════════════════════════════════════════════════════════ class NanoAppRpcService(Stub): """NanoAppRpcService — NanoApp RPC 服务""" def __init__(self, id: int = 0, name: str = "", version: int = 1, description: str = "", methods: List[str] = None): super().__init__() self._id = id self._name = name self._version = version self._description = description self._methods = methods or [] def getId(self) -> int: return self._id def getName(self) -> str: return self._name def getVersion(self) -> int: return self._version def getDescription(self) -> str: return self._description def getMethods(self) -> List[str]: return list(self._methods) def toString(self) -> str: return f"NanoAppRpcService(id={self._id}, name={self._name})" # ═══════════════════════════════════════════════════════════════ # NanoAppStateInfo # ═══════════════════════════════════════════════════════════════ class NanoAppStateInfo(Stub): """NanoAppStateInfo — NanoApp 状态信息""" def __init__(self, nanoAppId: int = 0, state: int = NANOAPP_STATE_NOT_LOADED, isEnabled: bool = False, memUsage: int = 0, uptimeMs: int = 0, lastError: int = 0, errorMessage: str = ""): super().__init__() self._nano_app_id = nanoAppId self._state = state self._is_enabled = isEnabled self._mem_usage = memUsage self._uptime_ms = uptimeMs self._last_error = lastError self._error_message = errorMessage def getNanoAppId(self) -> int: return self._nano_app_id def getState(self) -> int: return self._state def isEnabled(self) -> bool: return self._is_enabled def getMemUsage(self) -> int: return self._mem_usage def getUptimeMs(self) -> int: return self._uptime_ms def getLastError(self) -> int: return self._last_error def getErrorMessage(self) -> str: return self._error_message def toString(self) -> str: return f"NanoAppStateInfo(id={self._nano_app_id}, state={self._state})" # ═══════════════════════════════════════════════════════════════ # ContextHubInfo # ═══════════════════════════════════════════════════════════════ class ContextHubInfo(Stub): """ContextHubInfo — 上下文 Hub 信息""" def __init__(self, id: int = 0, name: str = "", vendor: str = "", version: int = 1, type_: int = HUB_TYPE_PRIMARY, maxSensors: int = 32, maxNanoApps: int = 16, memorySize: int = 256 * 1024, supportedSensors: List[int] = None, isAvailable: bool = True): super().__init__() self._id = id self._name = name self._vendor = vendor self._version = version self._type = type_ self._max_sensors = maxSensors self._max_nano_apps = maxNanoApps self._memory_size = memorySize self._supported_sensors = supportedSensors or [] self._is_available = isAvailable def getId(self) -> int: return self._id def getName(self) -> str: return self._name def getVendor(self) -> str: return self._vendor def getVersion(self) -> int: return self._version def getHubType(self) -> int: return self._type def getMaxSensors(self) -> int: return self._max_sensors def getMaxNanoApps(self) -> int: return self._max_nano_apps def getMemorySize(self) -> int: return self._memory_size def getSupportedSensors(self) -> List[int]: return list(self._supported_sensors) def isAvailable(self) -> bool: return self._is_available def toString(self) -> str: return f"ContextHubInfo(id={self._id}, name={self._name})" def equals(self, other: Any) -> bool: if not isinstance(other, ContextHubInfo): return False return self._id == other._id def hashCode(self) -> int: return self._id & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # ContextHubTransaction # ═══════════════════════════════════════════════════════════════ class ContextHubTransaction(Stub): """ContextHubTransaction — ContextHub 事务""" def __init__(self, id: int = 0, type_: int = TRANSACTION_TYPE_QUERY_NANOAPPS, status: int = TRANSACTION_PENDING, result: Any = None): super().__init__() self._id = id self._type = type_ self._status = status self._result = result def getId(self) -> int: return self._id def getType(self) -> int: return self._type def getStatus(self) -> int: return self._status def getResult(self) -> Any: return self._result def setResult(self, result: Any): self._result = result def waitForResult(self, timeoutMs: int = 0) -> Any: return self._result def cancel(self): self._status = TRANSACTION_CANCELLED def toString(self) -> str: return f"ContextHubTransaction(id={self._id}, type={self._type}, status={self._status})" def equals(self, other: Any) -> bool: if not isinstance(other, ContextHubTransaction): return False return self._id == other._id def hashCode(self) -> int: return self._id & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # ContextHubIntentEvent # ═══════════════════════════════════════════════════════════════ class ContextHubIntentEvent(Stub): """ContextHubIntentEvent — ContextHub 意图事件""" EVENT_HUB_RESTARTED = 0 EVENT_HUB_ERROR = 1 EVENT_NANOAPP_LOADED = 2 EVENT_NANOAPP_UNLOADED = 3 EVENT_NANOAPP_STARTED = 4 EVENT_NANOAPP_STOPPED = 5 EVENT_NANOAPP_ERROR = 6 EVENT_NANOAPP_MESSAGE = 7 EVENT_NANOAPP_CRASHED = 8 def __init__(self, eventType: int = EVENT_HUB_RESTARTED, hubId: int = 0, nanoAppId: int = 0, timestamp: int = 0, data: bytes = b""): super().__init__() self._event_type = eventType self._hub_id = hubId self._nano_app_id = nanoAppId self._timestamp = timestamp self._data = data def getEventType(self) -> int: return self._event_type def getHubId(self) -> int: return self._hub_id def getNanoAppId(self) -> int: return self._nano_app_id def getTimestamp(self) -> int: return self._timestamp def getData(self) -> bytes: return self._data def toString(self) -> str: return f"ContextHubIntentEvent(type={self._event_type}, hub={self._hub_id})" # ═══════════════════════════════════════════════════════════════ # ContextHubManagerCallback # ═══════════════════════════════════════════════════════════════ class ContextHubManagerCallback(Stub): """ContextHubManagerCallback — ContextHub 管理器回调""" def onHubStarted(self, hubInfo: ContextHubInfo): pass def onHubStopped(self, hubInfo: ContextHubInfo): pass def onHubError(self, hubInfo: ContextHubInfo, errorCode: int): pass def onNanoAppLoaded(self, hubId: int, nanoAppId: int): pass def onNanoAppUnloaded(self, hubId: int, nanoAppId: int): pass def onNanoAppStarted(self, hubId: int, nanoAppId: int): pass def onNanoAppStopped(self, hubId: int, nanoAppId: int): pass def onNanoAppCrashed(self, hubId: int, nanoAppId: int): pass def onNanoAppMessage(self, hubId: int, message: NanoAppMessage): pass def toString(self) -> str: return f"ContextHubManagerCallback@{hex(id(self))}" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # ContextHubClient # ═══════════════════════════════════════════════════════════════ class ContextHubClient(Stub): """ContextHubClient — ContextHub 客户端""" def __init__(self, hubInfo: Optional[ContextHubInfo] = None, callback: Optional[ContextHubManagerCallback] = None): super().__init__() self._hub_info = hubInfo self._callback = callback def getHubInfo(self) -> Optional[ContextHubInfo]: return self._hub_info def sendMessageToNanoApp(self, nanoAppId: int, message: NanoAppMessage) -> int: return TRANSACTION_SUCCESS def sendMessageToHub(self, message: NanoAppMessage) -> int: return TRANSACTION_SUCCESS def requestNanoAppState(self, nanoAppId: int) -> Optional[NanoAppStateInfo]: return None def enableNanoApp(self, nanoAppId: int) -> int: return TRANSACTION_SUCCESS def disableNanoApp(self, nanoAppId: int) -> int: return TRANSACTION_SUCCESS def close(self): pass def setCallback(self, callback: ContextHubManagerCallback): self._callback = callback def getCallback(self) -> Optional[ContextHubManagerCallback]: return self._callback def toString(self) -> str: return f"ContextHubClient(hub={self._hub_info})" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # ContextHubService / ContextHubServiceCallback # ═══════════════════════════════════════════════════════════════ class ContextHubService(Stub): """ContextHubService — ContextHub 服务""" SERVICE_NAME = "contexthub" def __init__(self): super().__init__() def startHub(self, hubInfo: ContextHubInfo) -> int: return TRANSACTION_SUCCESS def stopHub(self, hubInfo: ContextHubInfo) -> int: return TRANSACTION_SUCCESS def resetHub(self, hubInfo: ContextHubInfo) -> int: return TRANSACTION_SUCCESS def configureHub(self, hubInfo: ContextHubInfo, config: bytes) -> int: return TRANSACTION_SUCCESS def toString(self) -> str: return "ContextHubService()" class ContextHubServiceCallback(Stub): """ContextHubServiceCallback — ContextHub 服务回调""" def onHubStarted(self, hubId: int): pass def onHubStopped(self, hubId: int): pass def onHubReset(self, hubId: int): pass def onHubError(self, hubId: int, errorCode: int): pass def toString(self) -> str: return f"ContextHubServiceCallback@{hex(id(self))}" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # ContextHubManager # ═══════════════════════════════════════════════════════════════ class ContextHubManager(Stub): """ContextHubManager — ContextHub 管理器""" def __init__(self): super().__init__() self._hubs: Dict[int, ContextHubInfo] = {} self._clients: Dict[int, ContextHubClient] = {} self._callbacks: Dict[int, ContextHubManagerCallback] = {} def getHubs(self, filter_: Optional[NanoAppFilter] = None) -> List[ContextHubInfo]: if filter_ is None: return list(self._hubs.values()) return [h for h in self._hubs.values() if h.getId() == filter_.getNanoAppId()] def createClient(self, hubInfo: ContextHubInfo, callback: ContextHubManagerCallback) -> ContextHubClient: client = ContextHubClient(hubInfo=hubInfo, callback=callback) cid = id(client) self._clients[cid] = client if callback: cb_id = id(callback) self._callbacks[cb_id] = callback return client def destroyClient(self, client: ContextHubClient): cid = id(client) self._clients.pop(cid, None) cb = client.getCallback() if cb: self._callbacks.pop(id(cb), None) def registerCallback(self, hubInfo: ContextHubInfo, callback: ContextHubManagerCallback): cb_id = id(callback) self._callbacks[cb_id] = callback def unregisterCallback(self, hubInfo: ContextHubInfo, callback: ContextHubManagerCallback): cb_id = id(callback) self._callbacks.pop(cb_id, None) def loadNanoApp(self, hubInfo: ContextHubInfo, nanoApp: NanoApp) -> ContextHubTransaction: tx = ContextHubTransaction(type_=TRANSACTION_TYPE_LOAD_NANOAPP) tx.setResult(TRANSACTION_SUCCESS) return tx def unloadNanoApp(self, hubInfo: ContextHubInfo, nanoAppId: int) -> ContextHubTransaction: tx = ContextHubTransaction(type_=TRANSACTION_TYPE_UNLOAD_NANOAPP) tx.setResult(TRANSACTION_SUCCESS) return tx def queryNanoApps(self, hubInfo: ContextHubInfo) -> ContextHubTransaction: tx = ContextHubTransaction(type_=TRANSACTION_TYPE_QUERY_NANOAPPS) tx.setResult([]) return tx def queryNanoAppDetails(self, hubInfo: ContextHubInfo, nanoAppId: int) -> ContextHubTransaction: tx = ContextHubTransaction(type_=TRANSACTION_TYPE_QUERY_NANOAPP_DETAILS) tx.setResult(NanoAppInstanceInfo(id=nanoAppId)) return tx def queryHubMemory(self, hubInfo: ContextHubInfo) -> ContextHubTransaction: tx = ContextHubTransaction(type_=TRANSACTION_TYPE_QUERY_MEMORY) tx.setResult({"total": 262144, "free": 131072}) return tx def resetHub(self, hubInfo: ContextHubInfo) -> ContextHubTransaction: tx = ContextHubTransaction(type_=TRANSACTION_TYPE_RESET_HUB) tx.setResult(TRANSACTION_SUCCESS) return tx def enableNanoApp(self, hubInfo: ContextHubInfo, nanoAppId: int) -> int: return TRANSACTION_SUCCESS def disableNanoApp(self, hubInfo: ContextHubInfo, nanoAppId: int) -> int: return TRANSACTION_SUCCESS def findNanoAppByFilter(self, filter_: NanoAppFilter) -> List[NanoAppInstanceInfo]: return [] def getNanoAppInstanceInfo(self, hubInfo: ContextHubInfo, nanoAppId: int) -> Optional[NanoAppInstanceInfo]: return None def addHub(self, hubInfo: ContextHubInfo): self._hubs[hubInfo.getId()] = hubInfo def removeHub(self, hubId: int): self._hubs.pop(hubId, None) def toString(self) -> str: return f"ContextHubManager(hubs={len(self._hubs)})" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF