feat: 新增 42 个 Android API 模块
新增模块覆盖: 系统层 (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 行代码
This commit is contained in:
1 parent
8ad62be068
commit
506f9ac725
43 files changed
+16704
-23
No files matched your search
@@ -0,0 +1,519 @@
|
||||
"""
|
||||
Android SIP API — SipManager, SipProfile, SipSession, SipAudioCall
|
||||
(已废弃但存在于 SDK 中)
|
||||
方法签名完全对齐 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__ = [
|
||||
"SipManager",
|
||||
"SipProfile",
|
||||
"SipSession",
|
||||
"SipAudioCall",
|
||||
]
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# SipManager
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class SipManager(Stub):
|
||||
"""SipManager — SIP 会话管理器 (桌面存根, 已废弃)"""
|
||||
|
||||
EXTRA_CALL_ID = "android.sip.extra.CALL_ID"
|
||||
EXTRA_OFFER_SD = "android.sip.extra.OFFER_SD"
|
||||
EXTRA_PEER_PROFILE = "android.sip.extra.PEER_PROFILE"
|
||||
|
||||
def __init__(self, context: Any = None):
|
||||
super().__init__()
|
||||
self._context = context
|
||||
self._opened = False
|
||||
self._registered = False
|
||||
self._session: Optional["SipSession"] = None
|
||||
self._listener: Optional[Callable] = None
|
||||
|
||||
@staticmethod
|
||||
def isSipWifiOnly(context: Any) -> bool:
|
||||
"""检查 SIP 是否仅限 WiFi"""
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def isVoipSupported(context: Any) -> bool:
|
||||
"""检查是否支持 VoIP"""
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def isApiSupported(context: Any) -> bool:
|
||||
"""检查 SIP API 是否支持"""
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def newInstance(context: Any) -> "SipManager":
|
||||
"""创建新实例"""
|
||||
return SipManager(context)
|
||||
|
||||
def open(self, localProfile: "SipProfile") -> "SipSession":
|
||||
"""打开 SIP 会话"""
|
||||
self._opened = True
|
||||
self._session = SipSession(localProfile)
|
||||
return self._session
|
||||
|
||||
def setRegistrationListener(
|
||||
self, localProfileUri: str, listener: "SipSession.Listener"
|
||||
):
|
||||
"""设置注册监听器"""
|
||||
if self._session:
|
||||
self._session.setListener(listener)
|
||||
|
||||
def close(self, localProfileUri: str):
|
||||
"""关闭 SIP 会话"""
|
||||
self._opened = False
|
||||
self._registered = False
|
||||
self._session = None
|
||||
|
||||
def getSessionFor(self, intent: Any) -> Optional["SipSession"]:
|
||||
"""获取 Intent 对应的 SIP 会话"""
|
||||
return self._session
|
||||
|
||||
def register(
|
||||
self, localProfile: "SipProfile", expiryTime: int, listener: "SipSession.Listener"
|
||||
):
|
||||
"""注册 SIP"""
|
||||
raise AndroidOnlyError("SipManager.register() 仅在 Android 设备上可用")
|
||||
|
||||
def unregister(
|
||||
self, localProfile: "SipProfile", listener: "SipSession.Listener"
|
||||
):
|
||||
"""注销 SIP"""
|
||||
raise AndroidOnlyError("SipManager.unregister() 仅在 Android 设备上可用")
|
||||
|
||||
def isOpened(self, localProfileUri: str) -> bool:
|
||||
"""检查是否已打开"""
|
||||
return self._opened
|
||||
|
||||
def isRegistered(self, localProfileUri: str) -> bool:
|
||||
"""检查是否已注册"""
|
||||
return self._registered
|
||||
|
||||
def createSipSessionIfNeeded(self, localProfile: "SipProfile") -> "SipSession":
|
||||
"""如有必要则创建 SIP 会话"""
|
||||
if self._session is None:
|
||||
self._session = SipSession(localProfile)
|
||||
return self._session
|
||||
|
||||
def createSipProfile(self, intent: Any) -> Optional["SipProfile"]:
|
||||
"""从 Intent 创建 SIP 配置文件"""
|
||||
return None
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"SipManager(opened={self._opened}, registered={self._registered})"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return id(self) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# SipProfile
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class SipProfile(Stub):
|
||||
"""SipProfile — SIP 配置文件"""
|
||||
|
||||
# --- Protocol constants ---
|
||||
PROTOCOL_UDP = "UDP"
|
||||
PROTOCOL_TCP = "TCP"
|
||||
PROTOCOL_TLS = "TLS"
|
||||
|
||||
class Builder(Stub):
|
||||
"""SipProfile.Builder — SIP 配置文件构建器"""
|
||||
|
||||
def __init__(self, uri: str = ""):
|
||||
super().__init__()
|
||||
self._profile = SipProfile()
|
||||
self._profile._uri = uri
|
||||
|
||||
def setProfileName(self, name: str) -> "SipProfile.Builder":
|
||||
self._profile._profile_name = name
|
||||
return self
|
||||
|
||||
def setUserName(self, userName: str) -> "SipProfile.Builder":
|
||||
self._profile._user_name = userName
|
||||
return self
|
||||
|
||||
def setDomain(self, domain: str) -> "SipProfile.Builder":
|
||||
self._profile._domain = domain
|
||||
return self
|
||||
|
||||
def setPassword(self, password: str) -> "SipProfile.Builder":
|
||||
self._profile._password = password
|
||||
return self
|
||||
|
||||
def setPort(self, port: int) -> "SipProfile.Builder":
|
||||
self._profile._port = port
|
||||
return self
|
||||
|
||||
def setProtocol(self, protocol: str) -> "SipProfile.Builder":
|
||||
self._profile._protocol = protocol
|
||||
return self
|
||||
|
||||
def setSendKeepAlive(self, enabled: bool) -> "SipProfile.Builder":
|
||||
self._profile._send_keep_alive = enabled
|
||||
return self
|
||||
|
||||
def setAutoRegistration(self, enabled: bool) -> "SipProfile.Builder":
|
||||
self._profile._auto_registration = enabled
|
||||
return self
|
||||
|
||||
def setDisplayName(self, displayName: str) -> "SipProfile.Builder":
|
||||
self._profile._display_name = displayName
|
||||
return self
|
||||
|
||||
def setAuthUserName(self, authUserName: str) -> "SipProfile.Builder":
|
||||
self._profile._auth_user_name = authUserName
|
||||
return self
|
||||
|
||||
def build(self) -> "SipProfile":
|
||||
return self._profile
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"SipProfile.Builder(name={self._profile._profile_name})"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return id(self) & 0x7FFFFFFF
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._uri = ""
|
||||
self._profile_name = ""
|
||||
self._user_name = ""
|
||||
self._domain = ""
|
||||
self._display_name = ""
|
||||
self._password = ""
|
||||
self._protocol = self.PROTOCOL_UDP
|
||||
self._port = 5060
|
||||
self._send_keep_alive = False
|
||||
self._auto_registration = True
|
||||
self._auth_user_name = ""
|
||||
|
||||
def getProfileName(self) -> str:
|
||||
return self._profile_name
|
||||
|
||||
def getUserName(self) -> str:
|
||||
return self._user_name
|
||||
|
||||
def getDomain(self) -> str:
|
||||
return self._domain
|
||||
|
||||
def getDisplayName(self) -> str:
|
||||
return self._display_name
|
||||
|
||||
def getPassword(self) -> str:
|
||||
return self._password
|
||||
|
||||
def getProtocol(self) -> str:
|
||||
return self._protocol
|
||||
|
||||
def getPort(self) -> int:
|
||||
return self._port
|
||||
|
||||
def getSendKeepAlive(self) -> bool:
|
||||
return self._send_keep_alive
|
||||
|
||||
def isAutoRegistration(self) -> bool:
|
||||
return self._auto_registration
|
||||
|
||||
def getUri(self) -> str:
|
||||
return self._uri
|
||||
|
||||
def toString(self) -> str:
|
||||
return (f"SipProfile(name={self._profile_name}, "
|
||||
f"user={self._user_name}@{self._domain})")
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, SipProfile):
|
||||
return False
|
||||
return self._uri == other._uri
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(self._uri) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# SipSession
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class SipSession(Stub):
|
||||
"""SipSession — SIP 会话"""
|
||||
|
||||
# --- State constants ---
|
||||
STATE_READY_TO_CALL = 0
|
||||
STATE_INCOMING_CALL = 1
|
||||
STATE_INCOMING_CALL_ANSWERING = 2
|
||||
STATE_IN_CALL = 3
|
||||
STATE_OUTGOING_CALL = 4
|
||||
STATE_OUTGOING_CALL_RINGING = 5
|
||||
STATE_OUTGOING_CALL_CANCELING = 6
|
||||
STATE_PINGING = 7
|
||||
STATE_DEREGISTERING = 8
|
||||
STATE_CLOSED = 9
|
||||
|
||||
def __init__(self, profile: "SipProfile" = None):
|
||||
super().__init__()
|
||||
self._profile = profile
|
||||
self._listener: Optional["SipSession.Listener"] = None
|
||||
self._state = self.STATE_CLOSED
|
||||
self._call_id = ""
|
||||
self._peer_profile: Optional[SipProfile] = None
|
||||
self._in_call = False
|
||||
|
||||
def setListener(self, listener: "SipSession.Listener"):
|
||||
"""设置会话监听器"""
|
||||
self._listener = listener
|
||||
|
||||
def register(self, duration: int):
|
||||
"""注册 SIP"""
|
||||
raise AndroidOnlyError("SipSession.register() 仅在 Android 设备上可用")
|
||||
|
||||
def unregister(self):
|
||||
"""注销 SIP"""
|
||||
raise AndroidOnlyError("SipSession.unregister() 仅在 Android 设备上可用")
|
||||
|
||||
def makeAudioCall(
|
||||
self, localProfile: "SipProfile", peerProfile: "SipProfile"
|
||||
):
|
||||
"""发起音频呼叫"""
|
||||
raise AndroidOnlyError("SipSession.makeAudioCall() 仅在 Android 设备上可用")
|
||||
|
||||
def answerCall(self, callId: str, sessionDescription: int):
|
||||
"""接听呼叫"""
|
||||
raise AndroidOnlyError("SipSession.answerCall() 仅在 Android 设备上可用")
|
||||
|
||||
def endCall(self):
|
||||
"""结束呼叫"""
|
||||
raise AndroidOnlyError("SipSession.endCall() 仅在 Android 设备上可用")
|
||||
|
||||
def changeCall(self, callId: str, sessionDescription: int):
|
||||
"""更改呼叫"""
|
||||
raise AndroidOnlyError("SipSession.changeCall() 仅在 Android 设备上可用")
|
||||
|
||||
def getCallId(self) -> str:
|
||||
return self._call_id
|
||||
|
||||
def getPeerProfile(self) -> Optional["SipProfile"]:
|
||||
return self._peer_profile
|
||||
|
||||
def getState(self) -> int:
|
||||
return self._state
|
||||
|
||||
def isInCall(self) -> bool:
|
||||
return self._in_call
|
||||
|
||||
def getLocalProfile(self) -> Optional["SipProfile"]:
|
||||
return self._profile
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# Listener
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
class Listener(Stub):
|
||||
"""SipSession.Listener — SIP 会话监听器"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def onCalling(self, session: "SipSession"):
|
||||
"""呼叫中回调"""
|
||||
pass
|
||||
|
||||
def onRinging(self, session: "SipSession", caller: "SipProfile"):
|
||||
"""响铃回调"""
|
||||
pass
|
||||
|
||||
def onCallEstablished(self, session: "SipSession", sessionDescription: str):
|
||||
"""呼叫建立回调"""
|
||||
pass
|
||||
|
||||
def onCallEnded(self, session: "SipSession"):
|
||||
"""呼叫结束回调"""
|
||||
pass
|
||||
|
||||
def onCallBusy(self, session: "SipSession"):
|
||||
"""呼叫忙碌回调"""
|
||||
pass
|
||||
|
||||
def onError(self, session: "SipSession", errorCode: int, errorMessage: str):
|
||||
"""错误回调"""
|
||||
pass
|
||||
|
||||
def onCallChangeFailed(self, session: "SipSession", errorCode: int, errorMessage: str):
|
||||
"""呼叫变更失败回调"""
|
||||
pass
|
||||
|
||||
def onRegistrationDone(self, session: "SipSession", duration: int):
|
||||
"""注册成功回调"""
|
||||
pass
|
||||
|
||||
def onRegistrationFailed(
|
||||
self, session: "SipSession", errorCode: int, errorMessage: str
|
||||
):
|
||||
"""注册失败回调"""
|
||||
pass
|
||||
|
||||
def onRegistrationTimeout(self, session: "SipSession"):
|
||||
"""注册超时回调"""
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"SipSession.Listener@{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"SipSession(state={self._state})"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return id(self) & 0x7FFFFFFF
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# SipAudioCall
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class SipAudioCall(Stub):
|
||||
"""SipAudioCall — SIP 音频呼叫"""
|
||||
|
||||
def __init__(self, context: Any = None, localProfile: "SipProfile" = None):
|
||||
super().__init__()
|
||||
self._context = context
|
||||
self._local_profile = localProfile
|
||||
self._listener: Optional["SipAudioCall.Listener"] = None
|
||||
self._muted = False
|
||||
self._holding = False
|
||||
self._in_call = False
|
||||
|
||||
def setListener(self, listener: "SipAudioCall.Listener"):
|
||||
"""设置音频呼叫监听器"""
|
||||
self._listener = listener
|
||||
|
||||
def startAudio(self):
|
||||
"""开始音频"""
|
||||
raise AndroidOnlyError("SipAudioCall.startAudio() 仅在 Android 设备上可用")
|
||||
|
||||
def stopAudio(self):
|
||||
"""停止音频"""
|
||||
raise AndroidOnlyError("SipAudioCall.stopAudio() 仅在 Android 设备上可用")
|
||||
|
||||
def close(self):
|
||||
"""关闭音频呼叫"""
|
||||
self._in_call = False
|
||||
self._holding = False
|
||||
|
||||
def isMuted(self) -> bool:
|
||||
return self._muted
|
||||
|
||||
def toggleMute(self):
|
||||
"""切换静音"""
|
||||
self._muted = not self._muted
|
||||
|
||||
def hold(self, hold: int):
|
||||
"""保持呼叫"""
|
||||
self._holding = (hold != 0)
|
||||
|
||||
def continueCall(self, sessionDescription: int):
|
||||
"""继续呼叫"""
|
||||
raise AndroidOnlyError("SipAudioCall.continueCall() 仅在 Android 设备上可用")
|
||||
|
||||
def makeCall(
|
||||
self, localProfile: "SipProfile", peerProfile: "SipProfile", timeout: int
|
||||
):
|
||||
"""发起呼叫"""
|
||||
raise AndroidOnlyError("SipAudioCall.makeCall() 仅在 Android 设备上可用")
|
||||
|
||||
def answerCall(self, sessionDescription: int):
|
||||
"""接听呼叫"""
|
||||
raise AndroidOnlyError("SipAudioCall.answerCall() 仅在 Android 设备上可用")
|
||||
|
||||
def sendDtmf(self, code: int):
|
||||
"""发送 DTMF"""
|
||||
pass
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# Listener
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
class Listener(Stub):
|
||||
"""SipAudioCall.Listener — 音频呼叫监听器"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def onReadyToCall(self, call: "SipAudioCall"):
|
||||
"""准备呼叫回调"""
|
||||
pass
|
||||
|
||||
def onCallEstablished(self, call: "SipAudioCall", sessionDescription: str):
|
||||
"""呼叫建立回调"""
|
||||
pass
|
||||
|
||||
def onCallEnded(self, call: "SipAudioCall"):
|
||||
"""呼叫结束回调"""
|
||||
pass
|
||||
|
||||
def onCallHeld(self, call: "SipAudioCall"):
|
||||
"""呼叫保持回调"""
|
||||
pass
|
||||
|
||||
def onCallChanged(self, call: "SipAudioCall"):
|
||||
"""呼叫变更回调"""
|
||||
pass
|
||||
|
||||
def onError(self, call: "SipAudioCall", errorCode: int, errorMessage: str):
|
||||
"""错误回调"""
|
||||
pass
|
||||
|
||||
def onRingingBack(self, call: "SipAudioCall"):
|
||||
"""回铃回调"""
|
||||
pass
|
||||
|
||||
def onRinging(self, call: "SipAudioCall", caller: "SipProfile"):
|
||||
"""响铃回调"""
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"SipAudioCall.Listener@{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"SipAudioCall(inCall={self._in_call})"
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return id(self) & 0x7FFFFFFF
|
||||
Reference in new issue
Block a user