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:
1 parent
8ad62be068
commit
506f9ac725
43 files changed
+16704
-23
No files matched your search
@@ -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",
|
||||
]
|
||||
Reference in new issue
Block a user