""" Android media.tv 组件 — TvInputManager, TvInputInfo, TvInputService 等 方法签名完全对齐 Android SDK """ from typing import Any, Callable, Dict, List, Optional from .._core import Stub, AndroidOnlyError # ═══════════════════════════════════════════════════════════════ # TvInputManager # ═══════════════════════════════════════════════════════════════ class TvInputManager(Stub): """TvInputManager — 电视输入管理器""" ACTION_VIEW_RECORDING_SCHEDULES = "android.tv.action.VIEW_RECORDING_SCHEDULES" ACTION_WATCH_NEXT = "android.tv.action.WATCH_NEXT" TIME_SHIFT_STATUS_AVAILABLE = 0 TIME_SHIFT_STATUS_UNAVAILABLE = 1 TIME_SHIFT_STATUS_UNKNOWN = 2 TIME_SHIFT_STATUS_UNSUPPORTED = 3 VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 8 VIDEO_UNAVAILABLE_REASON_BUFFERING = 3 VIDEO_UNAVAILABLE_REASON_CAS = 7 VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 5 VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 6 VIDEO_UNAVAILABLE_REASON_PREEMPTED = 4 VIDEO_UNAVAILABLE_REASON_TUNING = 1 VIDEO_UNAVAILABLE_REASON_UNKNOWN = 0 VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2 # ═══════════════════════════════════════════════════════════ # TvInputCallback # ═══════════════════════════════════════════════════════════ class TvInputCallback(Stub): """TvInputManager.TvInputCallback — 电视输入回调""" def onInputAdded(self, inputId: str): pass def onInputRemoved(self, inputId: str): pass def onInputChanged(self, inputId: str): pass def onInputStateChanged(self, inputId: str, state: int): pass def onTvInputInfoUpdated(self, inputInfo: "TvInputInfo"): pass def __init__(self): super().__init__() self._inputs: Dict[str, TvInputInfo] = {} self._callbacks: Dict[int, TvInputManager.TvInputCallback] = {} def getTvInputList(self) -> List["TvInputInfo"]: return list(self._inputs.values()) def getTvInputInfo(self, inputId: str) -> Optional["TvInputInfo"]: return self._inputs.get(inputId) def getCurrentTvInputInfo(self) -> Optional["TvInputInfo"]: for inp in self._inputs.values(): return inp return None def updateTvInputInfo(self, inputInfo: "TvInputInfo"): if inputInfo: self._inputs[inputInfo.getId()] = inputInfo def registerCallback(self, callback: TvInputCallback, handler: Any = None): lid = id(callback) self._callbacks[lid] = callback def unregisterCallback(self, callback: TvInputCallback): lid = id(callback) self._callbacks.pop(lid, None) def createRecordingSession(self, recordingService: str, inputId: str): raise AndroidOnlyError("TvInputManager.createRecordingSession() is not available on desktop") def sendTvInputNotifyIntent(self, intent: Any, inputId: str): pass def isParentalControlsEnabled(self) -> bool: return False def isRatingBlocked(self, rating: str) -> bool: return False def getBlockedRatings(self) -> List[str]: return [] def getAvailableTvInputs(self) -> List[str]: return list(self._inputs.keys()) def getTvContentRatingSystems(self) -> List[str]: return ["US_TV", "US_MOVIE"] # ═══════════════════════════════════════════════════════════════ # TvInputInfo # ═══════════════════════════════════════════════════════════════ class TvInputInfo(Stub): """TvInputInfo — 电视输入信息""" TYPE_COMPONENT = 1005 TYPE_COMPOSITE = 1004 TYPE_HDMI = 1007 TYPE_OTHER = 1001 TYPE_SCART = 1003 TYPE_SVIDEO = 1006 TYPE_TUNER = 0 TYPE_DISPLAY_LINK = 1008 TYPE_VGA = 1002 def __init__(self, id: str = "", serviceInfo: Any = None, parentId: str = "", type_: int = TYPE_TUNER, hdmiDeviceInfo: Any = None, isHidden: bool = False, canRecord: bool = False, canPauseRecording: bool = False): super().__init__() self._id = id self._service_info = serviceInfo self._parent_id = parentId self._type = type_ self._hdmi_device_info = hdmiDeviceInfo self._is_hidden = isHidden self._can_record = canRecord self._can_pause_recording = canPauseRecording def getId(self) -> str: return self._id def getServiceInfo(self) -> Any: return self._service_info def getParentId(self) -> str: return self._parent_id def getType(self) -> int: return self._type def getHdmiDeviceInfo(self) -> Any: return self._hdmi_device_info def loadIcon(self, context: Any) -> Any: return None def loadLogo(self, context: Any) -> Any: return None def createIntentForSetupScreen(self) -> Any: return None def isHidden(self) -> bool: return self._is_hidden def canRecord(self) -> bool: return self._can_record def canPauseRecording(self) -> bool: return self._can_pause_recording def toString(self) -> str: type_names = { TvInputInfo.TYPE_TUNER: "TUNER", TvInputInfo.TYPE_HDMI: "HDMI", TvInputInfo.TYPE_COMPOSITE: "COMPOSITE", TvInputInfo.TYPE_COMPONENT: "COMPONENT", } return f"TvInputInfo(id={self._id}, type={type_names.get(self._type, str(self._type))})" # ═══════════════════════════════════════════════════════════════ # TvInputService # ═══════════════════════════════════════════════════════════════ class TvInputService(Stub): """TvInputService — 电视输入服务""" RECORDING_ERROR_RECORDING_LOST = 0 RECORDING_ERROR_TIMEOUT = 1 RECORDING_ERROR_OTHER = 2 # ═══════════════════════════════════════════════════════════ # Session # ═══════════════════════════════════════════════════════════ class Session(Stub): """TvInputService.Session — 电视会话""" def __init__(self): super().__init__() self._main = False self._stream_volume = 1.0 self._caption_enabled = False def onSetSurface(self, surface: Any) -> bool: return True def onSurfaceChanged(self, format: int, width: int, height: int): pass def onSurfaceReleased(self): pass def onAppPrivateCommand(self, action: str, data: Any): pass def onCreateOverlayView(self) -> Any: return None def onRelayoutContent(self): pass def onSetCaptionEnabled(self, enabled: bool): self._caption_enabled = enabled def onSetStreamVolume(self, volume: float): self._stream_volume = volume def onTimeShiftSetCurrentPositionRequest(self, positionMs: int): pass def notifyTimeShiftStatusChanged(self, status: int): pass def scheduleOverlayView(self, view: Any): pass def timeShiftPlay(self, uri: str): pass def timeShiftPause(self): pass def timeShiftResume(self): pass def timeShiftSeekTo(self, positionMs: int): pass def timeShiftSetPlaybackParams(self, params: Any): pass def timeShiftEnablePositionTracking(self, enable: bool): pass def notifyVideoAvailable(self): pass def notifyVideoUnavailable(self, reason: int): pass def notifySessionEvent(self, eventType: str, eventArgs: Any): pass def notifyTracksChanged(self, tracks: List[Any]): pass def notifyTrackSelected(self, type_: str, trackId: str): pass def notifyContentAllowed(self): pass def notifyContentBlocked(self, rating: str): pass def setMain(self, main: bool): self._main = main def setStreamVolume(self, volume: float): self._stream_volume = volume def __init__(self): super().__init__() self._sessions: List[TvInputService.Session] = [] def onCreateSession(self, inputId: str) -> Session: session = TvInputService.Session() self._sessions.append(session) return session def onSetupFinished(self, inputId: str): pass def sessionCreated(self, session: Session): pass def notifyHardwareFailed(self, deviceId: int): pass # ═══════════════════════════════════════════════════════════════ # TvRecordingClient / TvRecordingService (stubs) # ═══════════════════════════════════════════════════════════════ class TvRecordingClient(Stub): """TvRecordingClient — 电视录制客户端""" def __init__(self): super().__init__() def startRecording(self, uri: str): pass def stopRecording(self): pass def pauseRecording(self): pass def resumeRecording(self): pass def release(self): pass class TvRecordingService(Stub): """TvRecordingService — 电视录制服务""" def __init__(self): super().__init__() def onStartRecording(self, inputId: str, sessionId: str): pass def onStopRecording(self, sessionId: str): pass def onPauseRecording(self, sessionId: str): pass def onResumeRecording(self, sessionId: str): pass # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "TvInputManager", "TvInputInfo", "TvInputService", "TvRecordingClient", "TvRecordingService", ]