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 行代码
This commit is contained in:
shuiyu1123 committed 2026-06-24 12:00:28 +00:00
1 parent 8ad62be068
commit 506f9ac725
43 files changed
+16704 -23

No files matched your search

+254
View File
@@ -0,0 +1,254 @@
"""
Android hardware.input 组件 — InputManager, InputDevice, MotionRange 等
方法签名完全对齐 Android SDK
"""
import sys
from typing import Any, Callable, Dict, List, Optional
from .._core import Stub, AndroidOnlyError
# ═══════════════════════════════════════════════════════════════
# InputManager
# ═══════════════════════════════════════════════════════════════
class InputManager(Stub):
"""InputManager — 输入管理器"""
ACTION_QUERY_KEYBOARD_LAYOUTS = "android.hardware.input.action.QUERY_KEYBOARD_LAYOUTS"
# ═══════════════════════════════════════════════════════════
# InputDeviceListener
# ═══════════════════════════════════════════════════════════
class InputDeviceListener(Stub):
"""InputManager.InputDeviceListener — 输入设备监听器"""
def onInputDeviceAdded(self, deviceId: int):
pass
def onInputDeviceRemoved(self, deviceId: int):
pass
def onInputDeviceChanged(self, deviceId: int):
pass
def __init__(self):
super().__init__()
self._devices: Dict[int, InputDevice] = {}
self._listeners: Dict[int, InputManager.InputDeviceListener] = {}
self._next_id = 1
self._init_default_devices()
def _init_default_devices(self):
# Keyboard
kb = InputDevice(
deviceId=0, name="Virtual Keyboard",
descriptor="keyboard_v1", sources=InputDevice.SOURCE_KEYBOARD,
vendorId=0x1, productId=0x1,
keyboardType=InputDevice.KEYBOARD_TYPE_ALPHABETIC,
hasMicrophone=False, isVirtual=True
)
self._devices[0] = kb
# Mouse
mouse = InputDevice(
deviceId=1, name="Virtual Mouse",
descriptor="mouse_v1", sources=InputDevice.SOURCE_MOUSE,
vendorId=0x2, productId=0x2,
keyboardType=InputDevice.KEYBOARD_TYPE_NONE,
hasMicrophone=False, isVirtual=True
)
self._devices[1] = mouse
# Trackpad
tp = InputDevice(
deviceId=2, name="Virtual Trackpad",
descriptor="trackpad_v1", sources=InputDevice.SOURCE_TOUCHPAD,
vendorId=0x3, productId=0x3,
keyboardType=InputDevice.KEYBOARD_TYPE_NONE,
hasMicrophone=False, isVirtual=False
)
self._devices[2] = tp
def getDevice(self, deviceId: int) -> Optional["InputDevice"]:
return self._devices.get(deviceId)
def getDeviceIds(self) -> List[int]:
return list(self._devices.keys())
def registerInputDeviceListener(self, listener: InputDeviceListener, handler: Any = None):
lid = id(listener)
self._listeners[lid] = listener
def unregisterInputDeviceListener(self, listener: InputDeviceListener):
lid = id(listener)
self._listeners.pop(lid, None)
def getInputDevice(self, deviceId: int) -> Optional["InputDevice"]:
return self.getDevice(deviceId)
def isInTabletMode(self) -> bool:
return False
def getCurrentKeyboardLayoutForInputDevice(self, device: "InputDevice") -> Optional[str]:
return None
def setKeyboardLayoutForInputDevice(self, device: "InputDevice",
keyboardLayoutDescriptor: str):
pass
# ═══════════════════════════════════════════════════════════════
# InputDevice
# ═══════════════════════════════════════════════════════════════
class InputDevice(Stub):
"""InputDevice — 输入设备"""
KEYBOARD_TYPE_ALPHABETIC = 2
KEYBOARD_TYPE_NON_ALPHABETIC = 1
KEYBOARD_TYPE_NONE = 0
SOURCE_CLASS_JOYSTICK = 16
SOURCE_CLASS_MASK = 0x000000FF
SOURCE_CLASS_NONE = 0x00000000
SOURCE_CLASS_POINTER = 0x00000002
SOURCE_CLASS_POSITION = 0x00000008
SOURCE_CLASS_TRACKBALL = 0x00000004
SOURCE_CLASS_BUTTON = 0x00000001
SOURCE_GAMEPAD = 0x00000401
SOURCE_HDMI = 0x02000000
SOURCE_JOYSTICK = 0x01000010
SOURCE_KEYBOARD = 0x00000101
SOURCE_MOUSE = 0x00002002
SOURCE_MOUSE_RELATIVE = 0x00002000
SOURCE_ROTARY_ENCODER = 0x00800000
SOURCE_STYLUS = 0x00004002
SOURCE_TOUCHPAD = 0x00100008
SOURCE_TOUCHSCREEN = 0x00001002
SOURCE_TOUCH_NAVIGATION = 0x00200008
SOURCE_TRACKBALL = 0x00010004
SOURCE_UNKNOWN = 0x00000000
SOURCE_ANY = 0xFFFFFFFE
# ═══════════════════════════════════════════════════════════
# MotionRange
# ═══════════════════════════════════════════════════════════
class MotionRange(Stub):
"""InputDevice.MotionRange — 运动范围"""
def __init__(self, axis: int = 0, source: int = 0,
min: float = 0.0, max: float = 1.0,
flat: float = 0.0, fuzz: float = 0.0,
resolution: float = 0.0):
super().__init__()
self._axis = axis
self._source = source
self._min = min
self._max = max
self._flat = flat
self._fuzz = fuzz
self._resolution = resolution
def getAxis(self) -> int:
return self._axis
def getSource(self) -> int:
return self._source
def getMin(self) -> float:
return self._min
def getMax(self) -> float:
return self._max
def getFlat(self) -> float:
return self._flat
def getFuzz(self) -> float:
return self._fuzz
def getRange(self) -> float:
return self._max - self._min
def getResolution(self) -> float:
return self._resolution
def toString(self) -> str:
return f"MotionRange(axis={self._axis}, source={self._source}," \
f" range=[{self._min}, {self._max}])"
def __init__(self, deviceId: int = 0, name: str = "", descriptor: str = "",
sources: int = 0, vendorId: int = 0, productId: int = 0,
controllerNumber: int = 0, keyboardType: int = KEYBOARD_TYPE_NONE,
hasMicrophone: bool = False, isVirtual: bool = False):
super().__init__()
self._device_id = deviceId
self._name = name
self._descriptor = descriptor
self._sources = sources
self._vendor_id = vendorId
self._product_id = productId
self._controller_number = controllerNumber
self._keyboard_type = keyboardType
self._has_microphone = hasMicrophone
self._is_virtual = isVirtual
self._motion_ranges: List[InputDevice.MotionRange] = []
def getId(self) -> int:
return self._device_id
def getName(self) -> str:
return self._name
def getDescriptor(self) -> str:
return self._descriptor
def getSources(self) -> int:
return self._sources
def getVendorId(self) -> int:
return self._vendor_id
def getProductId(self) -> int:
return self._product_id
def getControllerNumber(self) -> int:
return self._controller_number
def getKeyCharacterMap(self) -> Any:
return None
def getMotionRange(self, axis: int = -1, source: int = -1) -> List[MotionRange]:
results = []
for mr in self._motion_ranges:
if axis >= 0 and mr.getAxis() != axis:
continue
if source >= 0 and mr.getSource() != source:
continue
results.append(mr)
return results
def hasMicrophone(self) -> bool:
return self._has_microphone
def isVirtual(self) -> bool:
return self._is_virtual
def toString(self) -> str:
return f"InputDevice(id={self._device_id}, name={self._name}," \
f" sources={self._sources:#x})"
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"InputManager",
"InputDevice",
]