""" Android accessibilityservice 组件 — AccessibilityService, AccessibilityServiceInfo, GestureDescription 等 方法签名完全对齐 Android SDK """ from __future__ import annotations import threading from typing import Any, Callable, Dict, List, Optional, Set, Tuple from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) # ═══════════════════════════════════════════════════════════════ # AccessibilityServiceInfo # ═══════════════════════════════════════════════════════════════ class AccessibilityServiceInfo(Stub): """AccessibilityServiceInfo — 无障碍服务信息""" # Flags FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 0x00000001 FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000002 FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000004 FLAG_REPORT_VIEW_IDS = 0x00000010 FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000020 FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x00000040 FLAG_REQUEST_ACCESSIBILITY_BUTTON = 0x00000100 FLAG_SERVICE_HANDLES_DOUBLETAP = 0x00000200 FLAG_REQUEST_MULTI_FINGER_GESTURES = 0x00000400 FLAG_REQUEST_SHORTCUT_WARN_DIALOG = 0x00000800 FLAG_SEND_TRACE_TO_DEBUG_TOOL = 0x00001000 # Feedback types FEEDBACK_SPOKEN = 0x00000001 FEEDBACK_HAPTIC = 0x00000002 FEEDBACK_AUDIBLE = 0x00000004 FEEDBACK_VISUAL = 0x00000008 FEEDBACK_GENERIC = 0x00000010 FEEDBACK_BRAILLE = 0x00000020 # Capabilities CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 0x00000001 CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 0x00000002 CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000004 CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS = 0x00000008 CAPABILITY_CAN_CONTROL_MAGNIFICATION = 0x00000010 CAPABILITY_CAN_PERFORM_GESTURES = 0x00000020 CAPABILITY_CAN_TAKE_SCREENSHOT = 0x00000040 def __init__(self): super().__init__() self.eventTypes: int = 0 self.feedbackType: int = self.FEEDBACK_GENERIC self.flags: int = 0 self.notificationTimeout: int = 0 self.fetchDescription: Optional[str] = None self.capabilities: int = 0 self.packageNames: Optional[List[str]] = None def toString(self) -> str: return (f"AccessibilityServiceInfo{{eventTypes={self.eventTypes}, " f"feedbackType={self.feedbackType}, flags={self.flags}}}") # ═══════════════════════════════════════════════════════════════ # GestureDescription # ═══════════════════════════════════════════════════════════════ class GestureDescription(Stub): """GestureDescription — 手势描述""" class StrokeDescription(Stub): """GestureDescription.StrokeDescription — 笔画描述""" def __init__(self, path: Any, startTime: int, duration: int): super().__init__() self._path = path self._start_time = startTime self._duration = duration def getPath(self) -> Any: return self._path def getStartTime(self) -> int: return self._start_time def getDuration(self) -> int: return self._duration def toString(self) -> str: return f"StrokeDescription{{startTime={self._start_time}, duration={self._duration}}}" _MAX_STROKE_COUNT = 10 @staticmethod def getMaxStrokeCount() -> int: return GestureDescription._MAX_STROKE_COUNT def __init__(self): super().__init__() self._strokes: List[GestureDescription.StrokeDescription] = [] class Builder(Stub): """GestureDescription.Builder — 构建器""" def __init__(self): super().__init__() self._strokes: List[GestureDescription.StrokeDescription] = [] def addStroke(self, stroke: GestureDescription.StrokeDescription) -> "GestureDescription.Builder": if len(self._strokes) < GestureDescription.getMaxStrokeCount(): self._strokes.append(stroke) return self def build(self) -> "GestureDescription": desc = GestureDescription() desc._strokes = list(self._strokes) return desc # ═══════════════════════════════════════════════════════════════ # GestureResultCallback # ═══════════════════════════════════════════════════════════════ class GestureResultCallback(Stub): """GestureResultCallback — 手势结果回调""" def onCompleted(self, gestureDescription: GestureDescription): pass def onCancelled(self, gestureDescription: GestureDescription): pass def onGestureCancelled(self, gestureDescription: GestureDescription): self.onCancelled(gestureDescription) def onGestureCompleted(self, gestureDescription: GestureDescription): self.onCompleted(gestureDescription) # ═══════════════════════════════════════════════════════════════ # MagnificationConfig # ═══════════════════════════════════════════════════════════════ class MagnificationConfig(Stub): """MagnificationConfig — 放大配置""" MAGNIFICATION_MODE_FULLSCREEN = 1 MAGNIFICATION_MODE_WINDOW = 2 def __init__(self): super().__init__() self._mode: int = self.MAGNIFICATION_MODE_FULLSCREEN self._center_x: float = 0.0 self._center_y: float = 0.0 self._scale: float = 1.0 def getMode(self) -> int: return self._mode def getCenterX(self) -> float: return self._center_x def getCenterY(self) -> float: return self._center_y def getScale(self) -> float: return self._scale def setMode(self, mode: int): self._mode = mode def setCenterX(self, centerX: float): self._center_x = centerX def setCenterY(self, centerY: float): self._center_y = centerY def setScale(self, scale: float): self._scale = scale def toString(self) -> str: return f"MagnificationConfig{{mode={self._mode}, scale={self._scale}}}" # ═══════════════════════════════════════════════════════════════ # SoftKeyboardController # ═══════════════════════════════════════════════════════════════ class SoftKeyboardController(Stub): """SoftKeyboardController — 软键盘控制器""" SHOW_MODE_AUTO = 0 SHOW_MODE_HIDDEN = 1 SHOW_MODE_IGNORE_HARD_KEYBOARD = 2 SHOW_MODE_HIDDEN_IDLE_TIMEOUT = 3 def __init__(self): super().__init__() self._show_mode: int = self.SHOW_MODE_AUTO self._listeners: List[Callable[[int], None]] = [] def setShowMode(self, showMode: int): self._show_mode = showMode def getShowMode(self) -> int: return self._show_mode def addOnShowModeChangedListener(self, listener: Callable[[int], None]): if listener not in self._listeners: self._listeners.append(listener) def removeOnShowModeChangedListener(self, listener: Callable[[int], None]): if listener in self._listeners: self._listeners.remove(listener) def toString(self) -> str: return f"SoftKeyboardController@{hex(id(self))}" # ═══════════════════════════════════════════════════════════════ # FingerprintGestureController # ═══════════════════════════════════════════════════════════════ class FingerprintGestureController(Stub): """FingerprintGestureController — 指纹手势控制器""" def __init__(self): super().__init__() self._callbacks: List[Any] = [] def isGestureAvailable(self) -> bool: return False def onGestureDetectionActiveChange(self, active: bool): pass def registerFingerprintGestureCallback(self, callback: Any, handler: Any = None): if callback not in self._callbacks: self._callbacks.append(callback) def unregisterFingerprintGestureCallback(self, callback: Any): if callback in self._callbacks: self._callbacks.remove(callback) def toString(self) -> str: return f"FingerprintGestureController@{hex(id(self))}" # ═══════════════════════════════════════════════════════════════ # TouchInteractionController # ═══════════════════════════════════════════════════════════════ class TouchInteractionController(Stub): """TouchInteractionController — 触控交互控制器""" def __init__(self): super().__init__() def performClick(self, x: int, y: int) -> bool: return True def performLongClick(self, x: int, y: int) -> bool: return True def requestDefer(self, timeout: int): pass def clearCache(self): pass def toString(self) -> str: return f"TouchInteractionController@{hex(id(self))}" # ═══════════════════════════════════════════════════════════════ # AccessibilityService # ═══════════════════════════════════════════════════════════════ class AccessibilityService(Stub): """AccessibilityService — 无障碍服务""" # Global actions GLOBAL_ACTION_BACK = 1 GLOBAL_ACTION_HOME = 2 GLOBAL_ACTION_RECENTS = 3 GLOBAL_ACTION_NOTIFICATIONS = 4 GLOBAL_ACTION_QUICK_SETTINGS = 5 GLOBAL_ACTION_POWER_DIALOG = 6 GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN = 7 GLOBAL_ACTION_LOCK_SCREEN = 8 GLOBAL_ACTION_TAKE_SCREENSHOT = 9 # Show modes SHOW_MODE_AUTO = SoftKeyboardController.SHOW_MODE_AUTO SHOW_MODE_HIDDEN = SoftKeyboardController.SHOW_MODE_HIDDEN SHOW_MODE_IGNORE_HARD_KEYBOARD = SoftKeyboardController.SHOW_MODE_IGNORE_HARD_KEYBOARD SHOW_MODE_HIDDEN_IDLE_TIMEOUT = SoftKeyboardController.SHOW_MODE_HIDDEN_IDLE_TIMEOUT # Flags FLAG_REQUEST_TOUCH_EXPLORATION_MODE = AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY FLAG_REQUEST_FILTER_KEY_EVENTS = AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS FLAG_REPORT_VIEW_IDS = AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS FLAG_RETRIEVE_INTERACTIVE_WINDOWS = AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS FLAG_REQUEST_ACCESSIBILITY_BUTTON = AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON FLAG_SERVICE_HANDLES_DOUBLETAP = AccessibilityServiceInfo.FLAG_SERVICE_HANDLES_DOUBLETAP FLAG_REQUEST_MULTI_FINGER_GESTURES = AccessibilityServiceInfo.FLAG_REQUEST_MULTI_FINGER_GESTURES FLAG_REQUEST_SHORTCUT_WARN_DIALOG = AccessibilityServiceInfo.FLAG_REQUEST_SHORTCUT_WARN_DIALOG FLAG_SEND_TRACE_TO_DEBUG_TOOL = AccessibilityServiceInfo.FLAG_SEND_TRACE_TO_DEBUG_TOOL def __init__(self): super().__init__() self._service_info = AccessibilityServiceInfo() self._soft_keyboard_controller = SoftKeyboardController() self._fingerprint_gesture_controller = FingerprintGestureController() self._touch_interaction_controller = TouchInteractionController() # ── Lifecycle ── def onAccessibilityEvent(self, event: Any): pass def onInterrupt(self): pass def onServiceConnected(self): pass def setServiceInfo(self, info: AccessibilityServiceInfo): self._service_info = info def getServiceInfo(self) -> AccessibilityServiceInfo: return self._service_info # ── Window ── def getWindows(self) -> List[Any]: return [] def getRootInActiveWindow(self) -> Any: return None def findFocus(self, focusType: int) -> Any: return None # ── Actions ── def performGlobalAction(self, action: int) -> bool: return True # ── Controllers ── def getSoftKeyboardController(self) -> SoftKeyboardController: return self._soft_keyboard_controller def setGestureDetectionPassthrough(self, passthrough: bool): pass def toString(self) -> str: return f"AccessibilityService@{hex(id(self))}" # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "AccessibilityService", "AccessibilityServiceInfo", "GestureDescription", "GestureResultCallback", "MagnificationConfig", "SoftKeyboardController", "FingerprintGestureController", "TouchInteractionController", ]