Files
Android-pyApi/android_pyapi/android/service_controls.py
T
shuiyu1123 506f9ac725 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 行代码
2026-06-24 12:00:28 +00:00

350 lines
12 KiB
Python

"""
Android Service Controls 组件 — ControlsProviderService, Control, DeviceTypes,
StatefulControl, StatelessControl 等
方法签名完全对齐 Android SDK (android.service.controls 包)
"""
from typing import Any, Callable, Dict, List, Optional, Set
from .._core import Stub, AndroidOnlyError
# ═══════════════════════════════════════════════════════════════
# DeviceTypes
# ═══════════════════════════════════════════════════════════════
class DeviceTypes(Stub):
"""DeviceTypes — 设备类型常量"""
TYPE_AC_HEATER = "AC_HEATER"
TYPE_AC_UNIT = "AC_UNIT"
TYPE_AIR_FRESHENER = "AIR_FRESHENER"
TYPE_AIR_PURIFIER = "AIR_PURIFIER"
TYPE_BLINDS = "BLINDS"
TYPE_CAMERA = "CAMERA"
TYPE_CLOSET = "CLOSET"
TYPE_COFFEE_MAKER = "COFFEE_MAKER"
TYPE_CURTAIN = "CURTAIN"
TYPE_DEHUMIDIFIER = "DEHUMIDIFIER"
TYPE_DISHWASHER = "DISHWASHER"
TYPE_DISPLAY = "DISPLAY"
TYPE_DOOR = "DOOR"
TYPE_DOORBELL = "DOORBELL"
TYPE_DRAWER = "DRAWER"
TYPE_DRYER = "DRYER"
TYPE_FAN = "FAN"
TYPE_GARAGE = "GARAGE"
TYPE_GATE = "GATE"
TYPE_HEATER = "HEATER"
TYPE_HOOD = "HOOD"
TYPE_HUMIDIFIER = "HUMIDIFIER"
TYPE_KETTLE = "KETTLE"
TYPE_LIGHT = "LIGHT"
TYPE_LIGHTBULB = "LIGHTBULB"
TYPE_LOCK = "LOCK"
TYPE_MICROWAVE = "MICROWAVE"
TYPE_MOP = "MOP"
TYPE_MOWER = "MOWER"
TYPE_MULTICOOKER = "MULTICOOKER"
TYPE_OUTLET = "OUTLET"
TYPE_OVEN = "OVEN"
TYPE_PERGOLLA = "PERGOLLA"
TYPE_RADIATOR = "RADIATOR"
TYPE_REFRIGERATOR = "REFRIGERATOR"
TYPE_REMOTE_STAND = "REMOTE_STAND"
TYPE_RICE_COOKER = "RICE_COOKER"
TYPE_ROUTINE = "ROUTINE"
TYPE_SCENE = "SCENE"
TYPE_SECURITY_SYSTEM = "SECURITY_SYSTEM"
TYPE_SET_TOP = "SET_TOP"
TYPE_SHOWER = "SHOWER"
TYPE_SHUTTER = "SHUTTER"
TYPE_SMOKE_DETECTOR = "SMOKE_DETECTOR"
TYPE_SOUNDBAR = "SOUNDBAR"
TYPE_SPRINKLER = "SPRINKLER"
TYPE_STANDMIXER = "STANDMIXER"
TYPE_THERMOSTAT = "THERMOSTAT"
TYPE_TV = "TV"
TYPE_VACUUM = "VACUUM"
TYPE_VALVE = "VALVE"
TYPE_WASHER = "WASHER"
TYPE_WATER_HEATER = "WATER_HEATER"
TYPE_WINDOW = "WINDOW"
TYPE_WINE_COOLER = "WINE_COOLER"
def __init__(self):
super().__init__()
# ═══════════════════════════════════════════════════════════════
# Control
# ═══════════════════════════════════════════════════════════════
class Control(Stub):
"""Control — 设备控件基类"""
# 状态
STATUS_UNKNOWN = 0
STATUS_OK = 1
STATUS_NOT_RESPONDING = 2
STATUS_ERROR = 3
STATUS_FIRMWARE_UPDATE = 4
def __init__(self, control_id: str, title: str,
subtitle: str, device_type: str):
super().__init__()
self._control_id = control_id
self._title = title
self._subtitle = subtitle
self._device_type = device_type
self._status = Control.STATUS_OK
self._status_text: str = ""
self._custom_icon: Optional[Any] = None
self._custom_color: int = 0
self._is_auth_required: bool = False
self._structure: str = ""
self._zone: str = ""
self._is_favorite: bool = False
self._device_types_list: List[str] = [device_type]
self._parent_id: Optional[str] = None
def getControlId(self) -> str:
"""获取控件 ID"""
return self._control_id
def getTitle(self) -> str:
"""获取标题"""
return self._title
def getSubtitle(self) -> str:
"""获取副标题"""
return self._subtitle
def getDeviceType(self) -> str:
"""获取设备类型"""
return self._device_type
def getStatus(self) -> int:
return self._status
def setStatus(self, status: int):
self._status = status
def getStatusText(self) -> str:
return self._status_text
def setStatusText(self, status_text: str):
self._status_text = status_text
def getStructure(self) -> str:
return self._structure
def setStructure(self, structure: str):
self._structure = structure
def getZone(self) -> str:
return self._zone
def setZone(self, zone: str):
self._zone = zone
def isFavorite(self) -> bool:
return self._is_favorite
def setFavorite(self, favorite: bool):
self._is_favorite = favorite
def toString(self) -> str:
return (f"Control(id={self._control_id}, title={self._title}, "
f"type={self._device_type}, status={self._status})")
def hashCode(self) -> int:
return hash(self._control_id) & 0x7FFFFFFF
def equals(self, other) -> bool:
if not isinstance(other, Control):
return False
return self._control_id == other._control_id
# ═══════════════════════════════════════════════════════════════
# StatefulControl
# ═══════════════════════════════════════════════════════════════
class StatefulControl(Control):
"""StatefulControl — 有状态控件"""
def __init__(self, control_id: str, title: str,
subtitle: str, device_type: str):
super().__init__(control_id, title, subtitle, device_type)
self._current_value: Any = None
self._min_value: Optional[float] = None
self._max_value: Optional[float] = None
self._step: Optional[float] = None
self._unit: Optional[str] = None
self._is_on: bool = False
self._mode: str = ""
def setStatus(self, status: int) -> "StatefulControl":
"""设置状态"""
self._status = status
return self
def setStatusText(self, status_text: str) -> "StatefulControl":
"""设置状态文本"""
self._status_text = status_text
return self
def getCurrentValue(self) -> Any:
return self._current_value
def setCurrentValue(self, value: Any) -> "StatefulControl":
self._current_value = value
return self
def getMinValue(self) -> Optional[float]:
return self._min_value
def setMinValue(self, min_value: float) -> "StatefulControl":
self._min_value = min_value
return self
def getMaxValue(self) -> Optional[float]:
return self._max_value
def setMaxValue(self, max_value: float) -> "StatefulControl":
self._max_value = max_value
return self
def getStep(self) -> Optional[float]:
return self._step
def setStep(self, step: float) -> "StatefulControl":
self._step = step
return self
def isOn(self) -> bool:
return self._is_on
def setOn(self, is_on: bool) -> "StatefulControl":
self._is_on = is_on
return self
def getMode(self) -> str:
return self._mode
def setMode(self, mode: str) -> "StatefulControl":
self._mode = mode
return self
def toString(self) -> str:
return (f"StatefulControl(id={self._control_id}, title={self._title}, "
f"type={self._device_type}, on={self._is_on}, "
f"value={self._current_value})")
# ═══════════════════════════════════════════════════════════════
# StatelessControl
# ═══════════════════════════════════════════════════════════════
class StatelessControl(Control):
"""StatelessControl — 无状态控件"""
def __init__(self, control_id: str, title: str,
subtitle: str, device_type: str):
super().__init__(control_id, title, subtitle, device_type)
self._action_text: str = ""
def getActionText(self) -> str:
return self._action_text
def setActionText(self, action_text: str) -> "StatelessControl":
self._action_text = action_text
return self
def toString(self) -> str:
return (f"StatelessControl(id={self._control_id}, "
f"title={self._title}, type={self._device_type})")
# ═══════════════════════════════════════════════════════════════
# ControlsProviderService
# ═══════════════════════════════════════════════════════════════
class ControlsProviderService(Stub):
"""ControlsProviderService — 控件提供者服务"""
SERVICE_INTERFACE = "android.service.controls.ControlsProviderService"
# 控件类型
CONTROL_TYPE_TOGGLE = 1
CONTROL_TYPE_RANGE = 2
CONTROL_TYPE_STATELESS = 3
CONTROL_TYPE_BUTTON = 4
def __init__(self):
super().__init__()
self._controls: Dict[str, Control] = {}
self._publishers: Dict[str, Any] = {}
self._subscribers: Dict[str, Any] = {}
def onCreatePublisherFor(self, control_ids: List[str]) -> Any:
"""为指定控件创建发布者"""
publisher = type("Publisher", (), {
"onUnsubscribe": lambda: None,
"onRequest": lambda cid: None,
})()
for cid in control_ids:
self._publishers[cid] = publisher
return publisher
def onGetSubscriberFor(self, control_ids: List[str]) -> Any:
"""获取控件订阅者"""
subscriber = type("Subscriber", (), {
"onSubscribe": lambda cid: None,
"onUnsubscribe": lambda cid: None,
})()
for cid in control_ids:
self._subscribers[cid] = subscriber
return subscriber
def publishControls(self, control_ids: List[str], controls: List[Control]):
"""发布控件状态"""
for control in controls:
self._controls[control.getControlId()] = control
def addControl(self, control: Control):
"""添加控件"""
self._controls[control.getControlId()] = control
def removeControl(self, control_id: str):
"""移除控件"""
self._controls.pop(control_id, None)
def getControl(self, control_id: str) -> Optional[Control]:
return self._controls.get(control_id)
def getControls(self) -> List[Control]:
return list(self._controls.values())
def toString(self) -> str:
return f"ControlsProviderService(controls={len(self._controls)})"
def hashCode(self) -> int:
return id(self) & 0x7FFFFFFF
def equals(self, other) -> bool:
return self is other
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"ControlsProviderService",
"Control",
"DeviceTypes",
"StatefulControl",
"StatelessControl",
]