""" Android Service Voice 组件 — VoiceInteractionService, VoiceInteractionSession, VoiceInteractor 等 方法签名完全对齐 Android SDK (android.service.voice 包) """ from __future__ import annotations import time from typing import Any, Callable, Dict, List, Optional, Set, Tuple from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException # ═══════════════════════════════════════════════════════════════ # 常量定义 # ═══════════════════════════════════════════════════════════════ KEY_ACTION = "action" KEY_ACTION_ARG = "action_arg" KEY_ARGUMENTS = "arguments" KEY_CONFIDENCE_SCORE = "confidence_score" KEY_ERROR = "error" KEY_FEATURE_ID = "feature_id" KEY_ID = "id" KEY_LANGUAGE = "language" KEY_LOCALE = "locale" KEY_MESSAGE = "message" KEY_PACKAGE_NAME = "package_name" KEY_POWER_SOURCE = "power_source" KEY_PROMPT = "prompt" KEY_RESULT = "result" KEY_SESSION_ID = "session_id" KEY_STATUS = "status" KEY_TIMEOUT_MS = "timeout_ms" KEY_VOLUME = "volume" KEY_WAKE_WORD = "wake_word" KEY_IS_DEMO = "is_demo" KEY_IS_TRUSTED = "is_trusted" KEY_IS_VALID = "is_valid" KEY_RECOGNITION_RESULT = "recognition_result" SHOW_SOURCE_FULL_SCREEN = 0 SHOW_SOURCE_DOCKED = 1 SHOW_SOURCE_PEEK = 2 SHOW_SOURCE_ASSISTANT = 3 SHOW_SOURCE_VOICE_SEARCH = 4 SHOW_SOURCE_SHORTCUT = 5 SHOW_SOURCE_NOTIFICATION = 6 SHOW_SOURCE_WIDGET = 7 VOICE_INTERACTION_ACTION = "android.service.voice.action.VOICE_INTERACTION" VOICE_INTERACTION_META_DATA = "android.service.voice.voice_interaction" VOICE_INTERACTION_SERVICE = "android.service.voice.VoiceInteractionService" SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService" SESSION_SERVICE_INTERFACE = "android.service.voice.VoiceInteractionSessionService" FLAG_SHOW_WITH_SCREEN_ON = 1 FLAG_SHOW_WITH_SCREEN_OFF = 2 FLAG_SHOW_WHEN_LOCKED = 4 FLAG_SHOW_AS_SYSTEM_OVERLAY = 8 FLAG_EXCLUSIVE = 16 VOICE_ACTIVITY_STATE_UNKNOWN = 0 VOICE_ACTIVITY_STATE_LISTENING = 1 VOICE_ACTIVITY_STATE_PROCESSING = 2 VOICE_ACTIVITY_STATE_RESPONDING = 3 VOICE_ACTIVITY_STATE_INACTIVE = 4 VOICE_ACTIVITY_STATE_ERROR = 5 # ═══════════════════════════════════════════════════════════════ # VoiceInteractionService # ═══════════════════════════════════════════════════════════════ class VoiceInteractionService(Stub): """VoiceInteractionService — 语音交互服务""" def __init__(self): super().__init__() self._is_connected: bool = False self._session: Optional[VoiceInteractionSession] = None self._available_voice_actions: List[str] = [] self._supported_languages: List[str] = [] self._active_session: bool = False self._disabled_until: int = 0 self._feature_id: str = "" self._package_name: str = "" def onReady(self): """服务就绪回调""" self._is_connected = True def onConnected(self): """已连接回调""" self._is_connected = True def onDisconnected(self): """断开连接回调""" self._is_connected = False def onShutdown(self): """关闭回调""" self._is_connected = False self._session = None def setAvailableVoiceActions(self, actions: List[str]): """设置可用语音动作""" self._available_voice_actions = list(actions) def getAvailableVoiceActions(self) -> List[str]: return list(self._available_voice_actions) def setSupportedLanguages(self, languages: List[str]): self._supported_languages = list(languages) def getSupportedLanguages(self) -> List[str]: return list(self._supported_languages) def isConnected(self) -> bool: return self._is_connected def getActiveSession(self) -> Optional[VoiceInteractionSession]: return self._session def setActiveSession(self, session: Optional[VoiceInteractionSession]): self._session = session self._active_session = session is not None def isActiveSession(self) -> bool: return self._active_session def showSession(self, args: Dict[str, Any] = None, flags: int = 0): """显示语音会话""" if self._session: self._session.show(args or {}, flags) def finish(self): """结束服务""" self._is_connected = False if self._session: self._session.finish() self._session = None def createSession(self, service_context: Any = None, session_id: int = 0) -> VoiceInteractionSession: """创建语音交互会话""" session = VoiceInteractionSession(service_context) session.setSessionId(session_id) self._session = session return session def getFeatureId(self) -> str: return self._feature_id def setFeatureId(self, feature_id: str): self._feature_id = feature_id def getPackageName(self) -> str: return self._package_name def setPackageName(self, pkg: str): self._package_name = pkg def isDisabled(self) -> bool: return self._disabled_until > int(time.time() * 1000) def toString(self) -> str: return f"VoiceInteractionService(connected={self._is_connected})" # ═══════════════════════════════════════════════════════════════ # VoiceInteractionSession # ═══════════════════════════════════════════════════════════════ class VoiceInteractionSession(Stub): """VoiceInteractionSession — 语音交互会话""" STATE_UNKNOWN = 0 STATE_LISTENING = 1 STATE_PROCESSING = 2 STATE_RESPONDING = 3 STATE_INACTIVE = 4 STATE_ERROR = 5 STATE_FINISHED = 6 def __init__(self, context: Any = None): super().__init__() self._context = context self._session_id: int = 0 self._state: int = VoiceInteractionSession.STATE_UNKNOWN self._interactor: Optional[VoiceInteractor] = None self._current_arguments: Dict[str, Any] = {} self._is_active: bool = False self._is_finished: bool = False self._prompt: str = "" self._confidence_score: float = 0.0 self._recognition_result: Any = None self._current_action: str = "" def setSessionId(self, session_id: int): self._session_id = session_id def getSessionId(self) -> int: return self._session_id def getState(self) -> int: return self._state def setState(self, state: int): self._state = state def getInteractor(self) -> Optional[VoiceInteractor]: return self._interactor def setInteractor(self, interactor: VoiceInteractor): self._interactor = interactor def show(self, args: Dict[str, Any], flags: int): """显示会话""" self._current_arguments = args self._is_active = True self._state = VoiceInteractionSession.STATE_LISTENING self.onShow(args, flags) def hide(self): """隐藏会话""" self._is_active = False self._state = VoiceInteractionSession.STATE_INACTIVE self.onHide() def finish(self): """结束会话""" self._is_finished = True self._state = VoiceInteractionSession.STATE_FINISHED self._is_active = False self.onFinish() def setPrompt(self, prompt: str): self._prompt = prompt def getPrompt(self) -> str: return self._prompt def setConfidenceScore(self, score: float): self._confidence_score = score def getConfidenceScore(self) -> float: return self._confidence_score def setRecognitionResult(self, result: Any): self._recognition_result = result def getRecognitionResult(self) -> Any: return self._recognition_result def setCurrentAction(self, action: str): self._current_action = action def getCurrentAction(self) -> str: return self._current_action def isActive(self) -> bool: return self._is_active def isFinished(self) -> bool: return self._is_finished def startListening(self, prompt: str = ""): """开始监听""" self._state = VoiceInteractionSession.STATE_LISTENING self._prompt = prompt def stopListening(self): """停止监听""" if self._state == VoiceInteractionSession.STATE_LISTENING: self._state = VoiceInteractionSession.STATE_PROCESSING def processVoiceInput(self, input_data: Any): """处理语音输入""" self._state = VoiceInteractionSession.STATE_PROCESSING self._recognition_result = input_data def respond(self, response: Any): """响应""" self._state = VoiceInteractionSession.STATE_RESPONDING def onShow(self, args: Dict[str, Any], flags: int): """会话显示回调""" pass def onHide(self): """会话隐藏回调""" pass def onFinish(self): """会话结束回调""" pass def onListeningStarted(self, prompt: str): """开始监听回调""" pass def onListeningFinished(self): """监听结束回调""" pass def onRecognitionResult(self, result: Any): """识别结果回调""" pass def onConfidenceScoreChanged(self, score: float): """置信度变化回调""" pass def onRequestConfirmation(self, prompt: Any): """请求确认回调""" if self._interactor: self._interactor.onRequestConfirmation(prompt) def onRequestSelect(self, prompt: Any, options: List[Any]): """请求选择回调""" if self._interactor: self._interactor.onRequestSelect(prompt, options) def onRequestComplete(self, result: Any): """请求完成回调""" if self._interactor: self._interactor.onRequestComplete(result) def onRequestError(self, error: Any): """请求错误回调""" if self._interactor: self._interactor.onRequestError(error) def toString(self) -> str: return f"VoiceInteractionSession(id={self._session_id}, state={self._state})" # ═══════════════════════════════════════════════════════════════ # VoiceInteractionManager # ═══════════════════════════════════════════════════════════════ class VoiceInteractionManager(Stub): """VoiceInteractionManager — 语音交互管理器""" def __init__(self, context: Any = None): super().__init__() self._context = context self._active_service: Optional[VoiceInteractionService] = None self._supported_actions: List[str] = [] self._is_available: bool = True @staticmethod def getInstance(context: Any) -> Optional[VoiceInteractionManager]: return VoiceInteractionManager(context) def getActiveService(self) -> Optional[VoiceInteractionService]: return self._active_service def setActiveService(self, service: VoiceInteractionService): self._active_service = service def isAvailable(self) -> bool: return self._is_available def setAvailable(self, available: bool): self._is_available = available def getSupportedActions(self) -> List[str]: return list(self._supported_actions) def setSupportedActions(self, actions: List[str]): self._supported_actions = list(actions) def startVoiceActivity(self, voice_session: VoiceInteractionSession): """启动语音活动""" voice_session.setState(VoiceInteractionSession.STATE_LISTENING) def setVoiceActivityState(self, state: int): """设置语音活动状态""" pass def showSession(self, service: VoiceInteractionService, args: Dict[str, Any], flags: int): """显示会话""" service.showSession(args, flags) def hideSession(self, service: VoiceInteractionService): """隐藏会话""" session = service.getActiveSession() if session: session.hide() def finishSession(self, service: VoiceInteractionService): """结束会话""" session = service.getActiveSession() if session: session.finish() def getSessionToken(self) -> Any: return None def toString(self) -> str: return f"VoiceInteractionManager(available={self._is_available})" # ═══════════════════════════════════════════════════════════════ # VoiceInteractor # ═══════════════════════════════════════════════════════════════ class VoiceInteractor(Stub): """VoiceInteractor — 语音交互器""" REQUEST_CONFIRMATION = "confirmation" REQUEST_SELECT = "select" REQUEST_COMPLETE = "complete" REQUEST_ERROR = "error" REQUEST_ABORT = "abort" REQUEST_COMMAND = "command" def __init__(self): super().__init__() self._requests: List[VoiceInteractor.Request] = [] self._active_request: Optional[VoiceInteractor.Request] = None self._is_available: bool = True def submitRequest(self, request: VoiceInteractor.Request): """提交请求""" self._requests.append(request) self._active_request = request def cancelRequest(self, request: VoiceInteractor.Request): """取消请求""" self._requests = [r for r in self._requests if r is not request] if self._active_request is request: self._active_request = None def getActiveRequest(self) -> Optional[VoiceInteractor.Request]: return self._active_request def getPendingRequests(self) -> List[VoiceInteractor.Request]: return list(self._requests) def isAvailable(self) -> bool: return self._is_available def setAvailable(self, available: bool): self._is_available = available def onRequestConfirmation(self, prompt: Any): """确认请求回调""" request = VoiceInteractor.ConfirmationRequest(prompt) self.submitRequest(request) def onRequestSelect(self, prompt: Any, options: List[Any]): """选择请求回调""" request = VoiceInteractor.SelectRequest(prompt, options) self.submitRequest(request) def onRequestComplete(self, result: Any): """完成请求回调""" request = VoiceInteractor.CompleteRequest(result) self.submitRequest(request) def onRequestError(self, error: Any): """错误请求回调""" request = VoiceInteractor.ErrorRequest(error) self.submitRequest(request) def destroy(self): """销毁""" self._requests.clear() self._active_request = None def toString(self) -> str: return f"VoiceInteractor(requests={len(self._requests)})" # ═══════════════════════════════════════════════════════ # VoiceInteractor.Request 基类 # ═══════════════════════════════════════════════════════ class Request(Stub): """VoiceInteractor.Request — 请求基类""" def __init__(self, request_type: str = ""): super().__init__() self._request_type = request_type self._is_active: bool = True self._timeout_ms: int = 30000 self._created_at: int = int(time.time() * 1000) self._result: Any = None def getRequestType(self) -> str: return self._request_type def isActive(self) -> bool: return self._is_active def setActive(self, active: bool): self._is_active = active def getTimeoutMs(self) -> int: return self._timeout_ms def setTimeoutMs(self, timeout: int): self._timeout_ms = timeout def getCreatedAt(self) -> int: return self._created_at def getResult(self) -> Any: return self._result def setResult(self, result: Any): self._result = result def isExpired(self) -> bool: return (int(time.time() * 1000) - self._created_at) > self._timeout_ms def onCancelled(self): self._is_active = False # ═══════════════════════════════════════════════════════ # ConfirmationRequest # ═══════════════════════════════════════════════════════ class ConfirmationRequest(Request): """VoiceInteractor.ConfirmationRequest — 确认请求""" def __init__(self, prompt: Any = None, args: Dict[str, Any] = None): super().__init__(VoiceInteractor.REQUEST_CONFIRMATION) self._prompt = prompt self._args = args or {} def getPrompt(self) -> Any: return self._prompt def getArgs(self) -> Dict[str, Any]: return dict(self._args) def onConfirmationResult(self, confirmed: bool, result: Any = None): """确认结果回调""" self.setResult({"confirmed": confirmed, "data": result}) # ═══════════════════════════════════════════════════════ # SelectRequest # ═══════════════════════════════════════════════════════ class SelectRequest(Request): """VoiceInteractor.SelectRequest — 选择请求""" def __init__(self, prompt: Any = None, options: List[Any] = None): super().__init__(VoiceInteractor.REQUEST_SELECT) self._prompt = prompt self._options = options or [] self._selected_index: int = -1 def getPrompt(self) -> Any: return self._prompt def getOptions(self) -> List[Any]: return list(self._options) def getSelectedIndex(self) -> int: return self._selected_index def onSelectResult(self, index: int, result: Any = None): """选择结果回调""" self._selected_index = index self.setResult({"index": index, "data": result}) # ═══════════════════════════════════════════════════════ # CompleteRequest # ═══════════════════════════════════════════════════════ class CompleteRequest(Request): """VoiceInteractor.CompleteRequest — 完成请求""" def __init__(self, result: Any = None): super().__init__(VoiceInteractor.REQUEST_COMPLETE) self.setResult(result) def onCompleteResult(self, result: Any = None): """完成结果回调""" self.setResult(result) # ═══════════════════════════════════════════════════════ # ErrorRequest # ═══════════════════════════════════════════════════════ class ErrorRequest(Request): """VoiceInteractor.ErrorRequest — 错误请求""" def __init__(self, error: Any = None): super().__init__(VoiceInteractor.REQUEST_ERROR) self._error = error def getError(self) -> Any: return self._error def onErrorResult(self, error: Any = None): """错误结果回调""" self.setResult({"error": error or self._error}) # ═══════════════════════════════════════════════════════════════ # VoiceInteractionSessionService # ═══════════════════════════════════════════════════════════════ class VoiceInteractionSessionService(Stub): """VoiceInteractionSessionService — 语音交互会话服务""" SERVICE_INTERFACE = "android.service.voice.VoiceInteractionSessionService" SERVICE_META_DATA = "android.voice_interaction" def __init__(self): super().__init__() self._service: Optional[VoiceInteractionService] = None self._current_session: Optional[VoiceInteractionSession] = None self._session_count: int = 0 self._is_running: bool = False def onNewSession(self, args: Dict[str, Any]) -> VoiceInteractionSession: """创建新会话""" self._session_count += 1 session = VoiceInteractionSession() session.setSessionId(self._session_count) session.show(args, 0) self._current_session = session return session def onSessionFinished(self, session: VoiceInteractionSession): """会话结束回调""" if self._current_session is session: self._current_session = None session.finish() def setVoiceInteractionService(self, service: VoiceInteractionService): self._service = service def getVoiceInteractionService(self) -> Optional[VoiceInteractionService]: return self._service def getCurrentSession(self) -> Optional[VoiceInteractionSession]: return self._current_session def isRunning(self) -> bool: return self._is_running def setRunning(self, running: bool): self._is_running = running def onDestroy(self): """销毁""" if self._current_session: self._current_session.finish() self._current_session = None self._is_running = False def toString(self) -> str: return f"VoiceInteractionSessionService(running={self._is_running})" # ═══════════════════════════════════════════════════════════════ # VoiceInteractionSessionCallback # ═══════════════════════════════════════════════════════════════ class VoiceInteractionSessionCallback(Stub): """VoiceInteractionSessionCallback — 语音交互会话回调""" def onSessionStarted(self, session: VoiceInteractionSession): pass def onSessionFinished(self, session: VoiceInteractionSession): pass def onSessionHidden(self, session: VoiceInteractionSession): pass def onSessionShown(self, session: VoiceInteractionSession): pass def onResultChanged(self, session: VoiceInteractionSession, result: Any): pass # ═══════════════════════════════════════════════════════════════ # VoiceInteractionUtils # ═══════════════════════════════════════════════════════════════ class VoiceInteractionUtils(Stub): """VoiceInteractionUtils — 语音交互工具类""" @staticmethod def isVoiceInteractionAvailable(context: Any) -> bool: return True @staticmethod def getActiveServiceComponentName(context: Any) -> Any: return None @staticmethod def getSupportedVoiceActions(context: Any) -> List[str]: return [] @staticmethod def setVoiceActionEnabled(context: Any, action: str, enabled: bool): pass @staticmethod def requestVoiceInteractionService(context: Any, service: VoiceInteractionService): pass @staticmethod def createVoiceInteractor(context: Any) -> VoiceInteractor: return VoiceInteractor() @staticmethod def getVoiceInteractionServiceInfo(context: Any) -> Any: return None @staticmethod def isVoiceInteractionService(context: Any, pkg: str) -> bool: return True # ═══════════════════════════════════════════════════════════════ # Keyphrase (hotword detection helpers) # ═══════════════════════════════════════════════════════════════ class Keyphrase(Stub): """Keyphrase — 唤醒词/关键词""" def __init__(self, phrase: str = "", id: int = 0): super().__init__() self._phrase = phrase self._id = id self._locale: str = "" self._confidence_level: float = 0.0 self._is_enabled: bool = True def getPhrase(self) -> str: return self._phrase def setPhrase(self, phrase: str): self._phrase = phrase def getId(self) -> int: return self._id def setId(self, id: int): self._id = id def getLocale(self) -> str: return self._locale def setLocale(self, locale: str): self._locale = locale def getConfidenceLevel(self) -> float: return self._confidence_level def setConfidenceLevel(self, level: float): self._confidence_level = level def isEnabled(self) -> bool: return self._is_enabled def setEnabled(self, enabled: bool): self._is_enabled = enabled def toString(self) -> str: return f"Keyphrase(phrase={self._phrase})" # ═══════════════════════════════════════════════════════════════ # VoiceInteractionSessionActivity (helper) # ═══════════════════════════════════════════════════════════════ class VoiceInteractionSessionActivity(Stub): """VoiceInteractionSessionActivity — 语音交互会话活动""" def __init__(self): super().__init__() self._session: Optional[VoiceInteractionSession] = None self._activity_state: int = 0 def setSession(self, session: VoiceInteractionSession): self._session = session def getSession(self) -> Optional[VoiceInteractionSession]: return self._session def getActivityState(self) -> int: return self._activity_state def setActivityState(self, state: int): self._activity_state = state def finishActivity(self): self._activity_state = VoiceInteractionSession.STATE_FINISHED def toString(self) -> str: return f"VoiceInteractionSessionActivity(state={self._activity_state})" # ═══════════════════════════════════════════════════════════════ # AlwaysOnHotwordDetector (helper) # ═══════════════════════════════════════════════════════════════ class AlwaysOnHotwordDetector(Stub): """AlwaysOnHotwordDetector — 始终开启的唤醒词检测器""" STATE_NOT_READY = 0 STATE_READY = 1 STATE_DETECTING = 2 STATE_PAUSED = 3 STATE_ERROR = 4 STATE_DISABLED = 5 RECOGNITION_FLAG_NONE = 0 RECOGNITION_FLAG_ALLOW_MULTIPLE = 1 RECOGNITION_FLAG_CAPTURE_TRIGGER = 2 RECOGNITION_FLAG_TRIGGER_AFTER_PREVIOUS = 4 def __init__(self): super().__init__() self._state: int = AlwaysOnHotwordDetector.STATE_NOT_READY self._keyphrases: List[Keyphrase] = [] self._is_detecting: bool = False self._detection_callback: Optional[Callable] = None def getState(self) -> int: return self._state def setState(self, state: int): self._state = state def getKeyphrases(self) -> List[Keyphrase]: return list(self._keyphrases) def addKeyphrase(self, keyphrase: Keyphrase): self._keyphrases.append(keyphrase) def startRecognition(self, recognition_flags: int = 0): """开始识别""" self._is_detecting = True self._state = AlwaysOnHotwordDetector.STATE_DETECTING def stopRecognition(self): """停止识别""" self._is_detecting = False self._state = AlwaysOnHotwordDetector.STATE_READY def isDetecting(self) -> bool: return self._is_detecting def setDetectionCallback(self, callback: Callable): self._detection_callback = callback def destroy(self): self._is_detecting = False self._state = AlwaysOnHotwordDetector.STATE_NOT_READY self._keyphrases.clear() def toString(self) -> str: return f"AlwaysOnHotwordDetector(state={self._state})"