feat: 大规模扩充至212个模块/175K行代码 — 覆盖android/java/javax/org/dalvik全包
- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等) - java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等) - javax/ 4个模块 (net/crypto/security/sql) - org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http) - dalvik/ 1个模块 (system) - ~3053个类/接口,方法签名完全对齐Android SDK - 桌面跨平台运行 (Windows/macOS/Linux) - 修复所有导入错误和Python关键字冲突
This commit is contained in:
1 parent
506f9ac725
commit
a51854455b
128 files changed
+100571
-3
No files matched your search
@@ -0,0 +1,744 @@
|
||||
"""
|
||||
Android View Accessibility 扩展组件
|
||||
方法签名完全对齐 Android SDK
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import threading
|
||||
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
from ..java.lang import RuntimeException
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# 无障碍事件常量
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
TYPE_VIEW_CLICKED = 0x00000001
|
||||
TYPE_VIEW_LONG_CLICKED = 0x00000002
|
||||
TYPE_VIEW_SELECTED = 0x00000004
|
||||
TYPE_VIEW_FOCUSED = 0x00000008
|
||||
TYPE_VIEW_TEXT_CHANGED = 0x00000010
|
||||
TYPE_WINDOW_STATE_CHANGED = 0x00000020
|
||||
TYPE_NOTIFICATION_STATE_CHANGED = 0x00000040
|
||||
TYPE_VIEW_HOVER_ENTER = 0x00000080
|
||||
TYPE_VIEW_HOVER_EXIT = 0x00000100
|
||||
TYPE_TOUCH_EXPLORATION_GESTURE_START = 0x00000200
|
||||
TYPE_TOUCH_EXPLORATION_GESTURE_END = 0x00000400
|
||||
TYPE_WINDOW_CONTENT_CHANGED = 0x00000800
|
||||
TYPE_VIEW_SCROLLED = 0x00001000
|
||||
TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000
|
||||
TYPE_ANNOUNCEMENT = 0x00004000
|
||||
TYPE_VIEW_ACCESSIBILITY_FOCUSED = 0x00008000
|
||||
TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 0x00010000
|
||||
TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000
|
||||
TYPE_GESTURE_DETECTION_START = 0x00040000
|
||||
TYPE_GESTURE_DETECTION_END = 0x00080000
|
||||
TYPE_TOUCH_INTERACTION_START = 0x00100000
|
||||
TYPE_TOUCH_INTERACTION_END = 0x00200000
|
||||
TYPE_WINDOWS_CHANGED = 0x00400000
|
||||
TYPE_VIEW_CONTEXT_CLICKED = 0x00800000
|
||||
TYPE_ASSIST_READING_CONTEXT = 0x01000000
|
||||
|
||||
CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 0x00000001
|
||||
CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 0x00000002
|
||||
CONTENT_CHANGE_TYPE_SUBTREE = 0x00000004
|
||||
CONTENT_CHANGE_TYPE_TEXT = 0x00000008
|
||||
CONTENT_CHANGE_TYPE_UNDEFINED = 0x00000010
|
||||
|
||||
WINDOWS_CHANGE_ADDED = 0x00000001
|
||||
WINDOWS_CHANGE_REMOVED = 0x00000002
|
||||
WINDOWS_CHANGE_TITLE = 0x00000004
|
||||
WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED = 0x00000008
|
||||
WINDOWS_CHANGE_ACTIVE = 0x00000010
|
||||
WINDOWS_CHANGE_PARENT = 0x00000020
|
||||
WINDOWS_CHANGE_CHILDREN = 0x00000040
|
||||
WINDOWS_CHANGE_BOUNDS = 0x00000080
|
||||
WINDOWS_CHANGE_LAYER = 0x00000100
|
||||
|
||||
WINDOW_TYPE_ACCESSIBILITY_OVERLAY = 4
|
||||
WINDOW_TYPE_APPLICATION = 1
|
||||
WINDOW_TYPE_INPUT_METHOD = 2
|
||||
WINDOW_TYPE_SPLIT_SCREEN_DIVIDER = 5
|
||||
WINDOW_TYPE_SYSTEM = 3
|
||||
|
||||
FLAG_REPORT_VIEW_IDS = 0x10
|
||||
FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x80
|
||||
FLAG_REQUEST_FILTER_KEY_EVENTS = 0x20
|
||||
FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x40
|
||||
FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x08
|
||||
FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x02
|
||||
FLAG_REQUEST_ACCESSIBILITY_BUTTON = 0x100
|
||||
|
||||
CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1
|
||||
CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2
|
||||
CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4
|
||||
CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 8
|
||||
|
||||
CAPTIONING_TYPE_UNKNOWN = -1
|
||||
CAPTIONING_TYPE_FEATURE = 0
|
||||
CAPTIONING_TYPE_COUNTRY = 1
|
||||
CAPTIONING_TYPE_SPOKEN = 2
|
||||
CAPTIONING_TYPE_UNKNOWN_CHARACTER = 3
|
||||
CAPTIONING_TYPE_MUSIC = 4
|
||||
CAPTIONING_TYPE_SFX = 5
|
||||
CAPTIONING_TYPE_VOICE = 6
|
||||
|
||||
CAPTIONING_PRESET_INVALID = -1
|
||||
CAPTIONING_PRESET_CUSTOM = 0
|
||||
CAPTIONING_PRESET_WHITE_ON_BLACK = 1
|
||||
CAPTIONING_PRESET_BLACK_ON_WHITE = 2
|
||||
CAPTIONING_PRESET_YELLOW_ON_BLACK = 3
|
||||
CAPTIONING_PRESET_YELLOW_ON_BLUE = 4
|
||||
CAPTIONING_PRESET_CUSTOM_BLACK_ON_WHITE = 5
|
||||
CAPTIONING_PRESET_CUSTOM_WHITE_ON_BLACK = 6
|
||||
CAPTIONING_PRESET_CUSTOM_YELLOW_ON_BLACK = 7
|
||||
CAPTIONING_PRESET_CUSTOM_YELLOW_ON_BLUE = 8
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AccessibilityEvent
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AccessibilityRecord(Stub):
|
||||
"""AccessibilityRecord — 无障碍记录"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._source_view: Optional[Any] = None
|
||||
self._source_node_id: int = -1
|
||||
self._source_window_id: int = -1
|
||||
self._event_time: int = 0
|
||||
self._package_name: Optional[str] = None
|
||||
self._class_name: Optional[str] = None
|
||||
self._text: List[str] = []
|
||||
self._content_description: Optional[str] = None
|
||||
self._item_count: int = -1
|
||||
self._current_item_index: int = -1
|
||||
self._from_index: int = -1
|
||||
self._to_index: int = -1
|
||||
self._scrollable: bool = False
|
||||
self._password: bool = False
|
||||
self._checked: bool = False
|
||||
self._enabled: bool = True
|
||||
self._clickable: bool = False
|
||||
self._focusable: bool = False
|
||||
self._focused: bool = False
|
||||
self._long_clickable: bool = False
|
||||
self._selected: bool = False
|
||||
self._pass_through: bool = False
|
||||
self._before_text: Optional[str] = None
|
||||
self._removed_count: int = 0
|
||||
self._added_count: int = 0
|
||||
self._max_scroll_x: int = -1
|
||||
self._max_scroll_y: int = -1
|
||||
self._scroll_x: int = -1
|
||||
self._scroll_y: int = -1
|
||||
|
||||
def setSource(self, view: Any) -> None:
|
||||
self._source_view = view
|
||||
|
||||
def getSource(self) -> Optional[Any]:
|
||||
return self._source_view
|
||||
|
||||
def setSourceNodeId(self, node_id: int) -> None:
|
||||
self._source_node_id = node_id
|
||||
|
||||
def getSourceNodeId(self) -> int:
|
||||
return self._source_node_id
|
||||
|
||||
def setWindowId(self, window_id: int) -> None:
|
||||
self._source_window_id = window_id
|
||||
|
||||
def getWindowId(self) -> int:
|
||||
return self._source_window_id
|
||||
|
||||
def setEventTime(self, time: int) -> None:
|
||||
self._event_time = time
|
||||
|
||||
def getEventTime(self) -> int:
|
||||
return self._event_time if self._event_time else int(time.time() * 1000)
|
||||
|
||||
def setPackageName(self, name: str) -> None:
|
||||
self._package_name = name
|
||||
|
||||
def getPackageName(self) -> Optional[str]:
|
||||
return self._package_name
|
||||
|
||||
def setClassName(self, name: str) -> None:
|
||||
self._class_name = name
|
||||
|
||||
def getClassName(self) -> Optional[str]:
|
||||
return self._class_name
|
||||
|
||||
def setText(self, text: List[str]) -> None:
|
||||
self._text = list(text)
|
||||
|
||||
def getText(self) -> List[str]:
|
||||
return list(self._text)
|
||||
|
||||
def setContentDescription(self, desc: str) -> None:
|
||||
self._content_description = desc
|
||||
|
||||
def getContentDescription(self) -> Optional[str]:
|
||||
return self._content_description
|
||||
|
||||
def setItemCount(self, count: int) -> None:
|
||||
self._item_count = count
|
||||
|
||||
def getItemCount(self) -> int:
|
||||
return self._item_count
|
||||
|
||||
def setCurrentItemIndex(self, index: int) -> None:
|
||||
self._current_item_index = index
|
||||
|
||||
def getCurrentItemIndex(self) -> int:
|
||||
return self._current_item_index
|
||||
|
||||
def setFromIndex(self, index: int) -> None:
|
||||
self._from_index = index
|
||||
|
||||
def getFromIndex(self) -> int:
|
||||
return self._from_index
|
||||
|
||||
def setToIndex(self, index: int) -> None:
|
||||
self._to_index = index
|
||||
|
||||
def getToIndex(self) -> int:
|
||||
return self._to_index
|
||||
|
||||
def setScrollable(self, scrollable: bool) -> None:
|
||||
self._scrollable = scrollable
|
||||
|
||||
def isScrollable(self) -> bool:
|
||||
return self._scrollable
|
||||
|
||||
def setPassword(self, password: bool) -> None:
|
||||
self._password = password
|
||||
|
||||
def isPassword(self) -> bool:
|
||||
return self._password
|
||||
|
||||
def setChecked(self, checked: bool) -> None:
|
||||
self._checked = checked
|
||||
|
||||
def isChecked(self) -> bool:
|
||||
return self._checked
|
||||
|
||||
def setEnabled(self, enabled: bool) -> None:
|
||||
self._enabled = enabled
|
||||
|
||||
def isEnabled(self) -> bool:
|
||||
return self._enabled
|
||||
|
||||
def setClickable(self, clickable: bool) -> None:
|
||||
self._clickable = clickable
|
||||
|
||||
def isClickable(self) -> bool:
|
||||
return self._clickable
|
||||
|
||||
def setFocusable(self, focusable: bool) -> None:
|
||||
self._focusable = focusable
|
||||
|
||||
def isFocusable(self) -> bool:
|
||||
return self._focusable
|
||||
|
||||
def setFocused(self, focused: bool) -> None:
|
||||
self._focused = focused
|
||||
|
||||
def isFocused(self) -> bool:
|
||||
return self._focused
|
||||
|
||||
def setLongClickable(self, long_clickable: bool) -> None:
|
||||
self._long_clickable = long_clickable
|
||||
|
||||
def isLongClickable(self) -> bool:
|
||||
return self._long_clickable
|
||||
|
||||
def setSelected(self, selected: bool) -> None:
|
||||
self._selected = selected
|
||||
|
||||
def isSelected(self) -> bool:
|
||||
return self._selected
|
||||
|
||||
def setBeforeText(self, text: str) -> None:
|
||||
self._before_text = text
|
||||
|
||||
def getBeforeText(self) -> Optional[str]:
|
||||
return self._before_text
|
||||
|
||||
def setRemovedCount(self, count: int) -> None:
|
||||
self._removed_count = count
|
||||
|
||||
def getRemovedCount(self) -> int:
|
||||
return self._removed_count
|
||||
|
||||
def setAddedCount(self, count: int) -> None:
|
||||
self._added_count = count
|
||||
|
||||
def getAddedCount(self) -> int:
|
||||
return self._added_count
|
||||
|
||||
def setMaxScrollX(self, max_x: int) -> None:
|
||||
self._max_scroll_x = max_x
|
||||
|
||||
def getMaxScrollX(self) -> int:
|
||||
return self._max_scroll_x
|
||||
|
||||
def setMaxScrollY(self, max_y: int) -> None:
|
||||
self._max_scroll_y = max_y
|
||||
|
||||
def getMaxScrollY(self) -> int:
|
||||
return self._max_scroll_y
|
||||
|
||||
def setScrollX(self, x: int) -> None:
|
||||
self._scroll_x = x
|
||||
|
||||
def getScrollX(self) -> int:
|
||||
return self._scroll_x
|
||||
|
||||
def setScrollY(self, y: int) -> None:
|
||||
self._scroll_y = y
|
||||
|
||||
def getScrollY(self) -> int:
|
||||
return self._scroll_y
|
||||
|
||||
def toString(self) -> str:
|
||||
return (f"AccessibilityRecord(class={self._class_name}, "
|
||||
f"text={self._text})")
|
||||
|
||||
|
||||
class AccessibilityEvent(AccessibilityRecord):
|
||||
"""AccessibilityEvent — 无障碍事件"""
|
||||
|
||||
INVALID_POSITION = -1
|
||||
MAX_TEXT_LENGTH = 500
|
||||
|
||||
def __init__(self, event_type: int = 0):
|
||||
super().__init__()
|
||||
self._event_type = event_type
|
||||
self._event_type_int = event_type
|
||||
self._movement_granularity: int = 0
|
||||
self._action: int = 0
|
||||
self._content_change_types: int = 0
|
||||
self._window_changes: int = 0
|
||||
|
||||
@staticmethod
|
||||
def obtain(event_type: int = 0) -> "AccessibilityEvent":
|
||||
return AccessibilityEvent(event_type)
|
||||
|
||||
@staticmethod
|
||||
def obtain(event: "AccessibilityEvent") -> "AccessibilityEvent":
|
||||
e = AccessibilityEvent(event.getEventType())
|
||||
return e
|
||||
|
||||
def getEventType(self) -> int:
|
||||
return self._event_type
|
||||
|
||||
def setEventType(self, event_type: int) -> None:
|
||||
self._event_type = event_type
|
||||
|
||||
def setMovementGranularity(self, granularity: int) -> None:
|
||||
self._movement_granularity = granularity
|
||||
|
||||
def getMovementGranularity(self) -> int:
|
||||
return self._movement_granularity
|
||||
|
||||
def setAction(self, action: int) -> None:
|
||||
self._action = action
|
||||
|
||||
def getAction(self) -> int:
|
||||
return self._action
|
||||
|
||||
def setContentChangeTypes(self, types: int) -> None:
|
||||
self._content_change_types = types
|
||||
|
||||
def getContentChangeTypes(self) -> int:
|
||||
return self._content_change_types
|
||||
|
||||
def setWindowChanges(self, changes: int) -> None:
|
||||
self._window_changes = changes
|
||||
|
||||
def getWindowChanges(self) -> int:
|
||||
return self._window_changes
|
||||
|
||||
def recycle(self) -> None:
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"AccessibilityEvent(type={self._event_type})"
|
||||
|
||||
|
||||
class AccessibilityWindowInfo(Stub):
|
||||
"""AccessibilityWindowInfo — 无障碍窗口信息"""
|
||||
|
||||
TYPE_ACCESSIBILITY_OVERLAY = WINDOW_TYPE_ACCESSIBILITY_OVERLAY
|
||||
TYPE_APPLICATION = WINDOW_TYPE_APPLICATION
|
||||
TYPE_INPUT_METHOD = WINDOW_TYPE_INPUT_METHOD
|
||||
TYPE_SPLIT_SCREEN_DIVIDER = WINDOW_TYPE_SPLIT_SCREEN_DIVIDER
|
||||
TYPE_SYSTEM = WINDOW_TYPE_SYSTEM
|
||||
|
||||
UNDEFINED = -1
|
||||
ACTIVE = 0
|
||||
INACTIVE = 1
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._type: int = self.TYPE_APPLICATION
|
||||
self._id: int = -1
|
||||
self._layer: int = 0
|
||||
self._is_active = False
|
||||
self._is_focused = False
|
||||
self._is_accessibility_focused = False
|
||||
self._title: Optional[str] = None
|
||||
self._root: Optional[Any] = None
|
||||
self._parent: Optional["AccessibilityWindowInfo"] = None
|
||||
self._bounds: Tuple[int, int, int, int] = (0, 0, 0, 0)
|
||||
self._anchor: Optional[Any] = None
|
||||
self._picture_in_picture = False
|
||||
self._first_child: Optional["AccessibilityWindowInfo"] = None
|
||||
self._last_child: Optional["AccessibilityWindowInfo"] = None
|
||||
self._child_count: int = 0
|
||||
|
||||
def getType(self) -> int:
|
||||
return self._type
|
||||
|
||||
def setType(self, type_val: int) -> None:
|
||||
self._type = type_val
|
||||
|
||||
def getId(self) -> int:
|
||||
return self._id
|
||||
|
||||
def setId(self, id_val: int) -> None:
|
||||
self._id = id_val
|
||||
|
||||
def setLayer(self, layer: int) -> None:
|
||||
self._layer = layer
|
||||
|
||||
def getLayer(self) -> int:
|
||||
return self._layer
|
||||
|
||||
def isActive(self) -> bool:
|
||||
return self._is_active
|
||||
|
||||
def setActive(self, active: bool) -> None:
|
||||
self._is_active = active
|
||||
|
||||
def isFocused(self) -> bool:
|
||||
return self._is_focused
|
||||
|
||||
def setFocused(self, focused: bool) -> None:
|
||||
self._is_focused = focused
|
||||
|
||||
def isAccessibilityFocused(self) -> bool:
|
||||
return self._is_accessibility_focused
|
||||
|
||||
def setAccessibilityFocused(self, focused: bool) -> None:
|
||||
self._is_accessibility_focused = focused
|
||||
|
||||
def getTitle(self) -> Optional[str]:
|
||||
return self._title
|
||||
|
||||
def setTitle(self, title: str) -> None:
|
||||
self._title = title
|
||||
|
||||
def setBoundsInScreen(self, bounds: Tuple[int, int, int, int]) -> None:
|
||||
self._bounds = bounds
|
||||
|
||||
def getBoundsInScreen(self) -> Tuple[int, int, int, int]:
|
||||
return self._bounds
|
||||
|
||||
def setAnchorId(self, anchor: Any) -> None:
|
||||
self._anchor = anchor
|
||||
|
||||
def getAnchorId(self) -> Optional[Any]:
|
||||
return self._anchor
|
||||
|
||||
def isInPictureInPictureMode(self) -> bool:
|
||||
return self._picture_in_picture
|
||||
|
||||
def setPictureInPictureMode(self, pip: bool) -> None:
|
||||
self._picture_in_picture = pip
|
||||
|
||||
def getRoot(self) -> Optional[Any]:
|
||||
return self._root
|
||||
|
||||
def setRoot(self, root: Any) -> None:
|
||||
self._root = root
|
||||
|
||||
def getParent(self) -> Optional["AccessibilityWindowInfo"]:
|
||||
return self._parent
|
||||
|
||||
def getChild(self, index: int) -> Optional["AccessibilityWindowInfo"]:
|
||||
if index == 0:
|
||||
return self._first_child
|
||||
return None
|
||||
|
||||
def getChildCount(self) -> int:
|
||||
return self._child_count
|
||||
|
||||
@staticmethod
|
||||
def obtain() -> "AccessibilityWindowInfo":
|
||||
return AccessibilityWindowInfo()
|
||||
|
||||
@staticmethod
|
||||
def obtain(info: "AccessibilityWindowInfo") -> "AccessibilityWindowInfo":
|
||||
return AccessibilityWindowInfo()
|
||||
|
||||
def recycle(self) -> None:
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
types = {1: "APPLICATION", 2: "INPUT_METHOD", 3: "SYSTEM", 4: "OVERLAY"}
|
||||
return (f"AccessibilityWindowInfo(type={types.get(self._type, 'UNKNOWN')}, "
|
||||
f"id={self._id})")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AccessibilityManager 扩展
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AccessibilityManager(Stub):
|
||||
"""AccessibilityManager — 无障碍管理器扩展"""
|
||||
|
||||
FLAG_REPORT_VIEW_IDS = FLAG_REPORT_VIEW_IDS
|
||||
FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
|
||||
FLAG_REQUEST_FILTER_KEY_EVENTS = FLAG_REQUEST_FILTER_KEY_EVENTS
|
||||
FLAG_REQUEST_TOUCH_EXPLORATION_MODE = FLAG_REQUEST_TOUCH_EXPLORATION_MODE
|
||||
FLAG_RETRIEVE_INTERACTIVE_WINDOWS = FLAG_RETRIEVE_INTERACTIVE_WINDOWS
|
||||
FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
|
||||
FLAG_REQUEST_ACCESSIBILITY_BUTTON = FLAG_REQUEST_ACCESSIBILITY_BUTTON
|
||||
|
||||
class AccessibilityStateChangeListener(Stub):
|
||||
"""AccessibilityManager.AccessibilityStateChangeListener"""
|
||||
def onAccessibilityStateChanged(self, enabled: bool) -> None:
|
||||
pass
|
||||
|
||||
class TouchExplorationStateChangeListener(Stub):
|
||||
"""AccessibilityManager.TouchExplorationStateChangeListener"""
|
||||
def onTouchExplorationStateChanged(self, enabled: bool) -> None:
|
||||
pass
|
||||
|
||||
class HighTextContrastChangeListener(Stub):
|
||||
def onHighTextContrastStateChanged(self, enabled: bool) -> None:
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._enabled = False
|
||||
self._touch_exploration_enabled = False
|
||||
self._high_text_contrast_enabled = False
|
||||
self._state_listeners: List[AccessibilityStateChangeListener] = []
|
||||
self._touch_listeners: List[TouchExplorationStateChangeListener] = []
|
||||
self._contrast_listeners: List[Any] = []
|
||||
self._accessibility_button_available = False
|
||||
|
||||
def isEnabled(self) -> bool:
|
||||
return self._enabled
|
||||
|
||||
def setEnabled(self, enabled: bool) -> None:
|
||||
old = self._enabled
|
||||
self._enabled = enabled
|
||||
if old != enabled:
|
||||
for listener in list(self._state_listeners):
|
||||
listener.onAccessibilityStateChanged(enabled)
|
||||
|
||||
def isTouchExplorationEnabled(self) -> bool:
|
||||
return self._touch_exploration_enabled
|
||||
|
||||
def setTouchExplorationEnabled(self, enabled: bool) -> None:
|
||||
old = self._touch_exploration_enabled
|
||||
self._touch_exploration_enabled = enabled
|
||||
if old != enabled:
|
||||
for listener in list(self._touch_listeners):
|
||||
listener.onTouchExplorationStateChanged(enabled)
|
||||
|
||||
def isHighTextContrastEnabled(self) -> bool:
|
||||
return self._high_text_contrast_enabled
|
||||
|
||||
def addAccessibilityStateChangeListener(self, listener: AccessibilityStateChangeListener) -> None:
|
||||
if listener not in self._state_listeners:
|
||||
self._state_listeners.append(listener)
|
||||
|
||||
def removeAccessibilityStateChangeListener(self, listener: AccessibilityStateChangeListener) -> None:
|
||||
if listener in self._state_listeners:
|
||||
self._state_listeners.remove(listener)
|
||||
|
||||
def addTouchExplorationStateChangeListener(self, listener: TouchExplorationStateChangeListener) -> None:
|
||||
if listener not in self._touch_listeners:
|
||||
self._touch_listeners.append(listener)
|
||||
|
||||
def removeTouchExplorationStateChangeListener(self, listener: TouchExplorationStateChangeListener) -> None:
|
||||
if listener in self._touch_listeners:
|
||||
self._touch_listeners.remove(listener)
|
||||
|
||||
def addHighTextContrastStateChangeListener(self, listener: Any) -> None:
|
||||
if listener not in self._contrast_listeners:
|
||||
self._contrast_listeners.append(listener)
|
||||
|
||||
def removeHighTextContrastStateChangeListener(self, listener: Any) -> None:
|
||||
if listener in self._contrast_listeners:
|
||||
self._contrast_listeners.remove(listener)
|
||||
|
||||
def setAccessibilityButtonAvailable(self, available: bool) -> None:
|
||||
self._accessibility_button_available = available
|
||||
|
||||
def isAccessibilityButtonAvailable(self) -> bool:
|
||||
return self._accessibility_button_available
|
||||
|
||||
def sendAccessibilityEvent(self, event: AccessibilityEvent) -> None:
|
||||
pass
|
||||
|
||||
def interrupt(self) -> None:
|
||||
pass
|
||||
|
||||
def getInstalledAccessibilityServiceList(self) -> List[Any]:
|
||||
return []
|
||||
|
||||
def getEnabledAccessibilityServiceList(self) -> List[Any]:
|
||||
return []
|
||||
|
||||
def toString(self) -> str:
|
||||
return (f"AccessibilityManager(enabled={self._enabled}, "
|
||||
f"touchExploration={self._touch_exploration_enabled})")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# CaptioningManager
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class CaptioningManager(Stub):
|
||||
"""CaptioningManager — 字幕管理"""
|
||||
|
||||
CAPTIONING_TYPE_UNKNOWN = CAPTIONING_TYPE_UNKNOWN
|
||||
CAPTIONING_TYPE_FEATURE = CAPTIONING_TYPE_FEATURE
|
||||
CAPTIONING_TYPE_COUNTRY = CAPTIONING_TYPE_COUNTRY
|
||||
CAPTIONING_TYPE_SPOKEN = CAPTIONING_TYPE_SPOKEN
|
||||
CAPTIONING_TYPE_UNKNOWN_CHARACTER = CAPTIONING_TYPE_UNKNOWN_CHARACTER
|
||||
CAPTIONING_TYPE_MUSIC = CAPTIONING_TYPE_MUSIC
|
||||
CAPTIONING_TYPE_SFX = CAPTIONING_TYPE_SFX
|
||||
CAPTIONING_TYPE_VOICE = CAPTIONING_TYPE_VOICE
|
||||
|
||||
class CaptionStyle(Stub):
|
||||
"""CaptioningManager.CaptionStyle — 字幕风格"""
|
||||
|
||||
EDGE_TYPE_NONE = 0
|
||||
EDGE_TYPE_OUTLINE = 1
|
||||
EDGE_TYPE_DROP_SHADOW = 2
|
||||
EDGE_TYPE_RAISED = 3
|
||||
EDGE_TYPE_DEPRESSED = 4
|
||||
|
||||
PRESET_CUSTOM = CAPTIONING_PRESET_CUSTOM
|
||||
PRESET_WHITE_ON_BLACK = CAPTIONING_PRESET_WHITE_ON_BLACK
|
||||
PRESET_BLACK_ON_WHITE = CAPTIONING_PRESET_BLACK_ON_WHITE
|
||||
PRESET_YELLOW_ON_BLACK = CAPTIONING_PRESET_YELLOW_ON_BLACK
|
||||
PRESET_YELLOW_ON_BLUE = CAPTIONING_PRESET_YELLOW_ON_BLUE
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._foreground_color: int = 0xFFFFFFFF
|
||||
self._background_color: int = 0xFF000000
|
||||
self._edge_color: int = 0xFF000000
|
||||
self._edge_type: int = self.EDGE_TYPE_NONE
|
||||
self._window_color: int = 0xFF000000
|
||||
self._foreground_size: int = 1
|
||||
self._preset: int = CAPTIONING_PRESET_WHITE_ON_BLACK
|
||||
|
||||
def getForegroundColor(self) -> int:
|
||||
return self._foreground_color
|
||||
|
||||
def getBackgroundColor(self) -> int:
|
||||
return self._background_color
|
||||
|
||||
def getEdgeColor(self) -> int:
|
||||
return self._edge_color
|
||||
|
||||
def getEdgeType(self) -> int:
|
||||
return self._edge_type
|
||||
|
||||
def getWindowColor(self) -> int:
|
||||
return self._window_color
|
||||
|
||||
def getForegroundSize(self) -> int:
|
||||
return self._foreground_size
|
||||
|
||||
def getPreset(self) -> int:
|
||||
return self._preset
|
||||
|
||||
def hasBackgroundColor(self) -> bool:
|
||||
return (self._background_color >> 24) > 0
|
||||
|
||||
def hasForegroundColor(self) -> bool:
|
||||
return (self._foreground_color >> 24) > 0
|
||||
|
||||
def hasEdgeType(self) -> bool:
|
||||
return self._edge_type != self.EDGE_TYPE_NONE
|
||||
|
||||
def hasWindowColor(self) -> bool:
|
||||
return (self._window_color >> 24) > 0
|
||||
|
||||
@staticmethod
|
||||
def getCustomStyle(style_id: int) -> "CaptioningManager.CaptionStyle":
|
||||
return CaptioningManager.CaptionStyle()
|
||||
|
||||
@staticmethod
|
||||
def getPresetStyle(preset: int) -> "CaptioningManager.CaptionStyle":
|
||||
return CaptioningManager.CaptionStyle()
|
||||
|
||||
def applyStyle(self, style: "CaptioningManager.CaptionStyle") -> None:
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"CaptionStyle(preset={self._preset})"
|
||||
|
||||
class CaptioningChangeListener(Stub):
|
||||
"""CaptioningManager.CaptioningChangeListener"""
|
||||
|
||||
def onEnabledChanged(self, enabled: bool) -> None:
|
||||
pass
|
||||
|
||||
def onUserStyleChanged(self, style: "CaptioningManager.CaptionStyle") -> None:
|
||||
pass
|
||||
|
||||
def onLocaleChanged(self, locale: Any) -> None:
|
||||
pass
|
||||
|
||||
def onFontScaleChanged(self, scale: float) -> None:
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._enabled = False
|
||||
self._user_style: Optional[CaptioningManager.CaptionStyle] = None
|
||||
self._font_scale: float = 1.0
|
||||
self._locale: Optional[Any] = None
|
||||
self._listeners: List[CaptioningManager.CaptioningChangeListener] = []
|
||||
|
||||
def isEnabled(self) -> bool:
|
||||
return self._enabled
|
||||
|
||||
def getFontScale(self) -> float:
|
||||
return self._font_scale
|
||||
|
||||
def getLocale(self) -> Optional[Any]:
|
||||
return self._locale
|
||||
|
||||
def getUserStyle(self) -> CaptionStyle:
|
||||
return self._user_style or CaptioningManager.CaptionStyle()
|
||||
|
||||
def addCaptioningChangeListener(self, listener: CaptioningChangeListener) -> None:
|
||||
if listener not in self._listeners:
|
||||
self._listeners.append(listener)
|
||||
|
||||
def removeCaptioningChangeListener(self, listener: CaptioningChangeListener) -> None:
|
||||
if listener in self._listeners:
|
||||
self._listeners.remove(listener)
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"CaptioningManager(enabled={self._enabled})"
|
||||
|
||||
|
||||
IllegalArgumentException = type("IllegalStateException", (RuntimeException,), {})
|
||||
Reference in new issue
Block a user