""" Android hardware sensor 扩展组件 — Sensor (扩展), SensorEvent, SensorDirectChannel, SensorPrivacyManager, SensorOffload, SensorRequest 等 方法签名完全对齐 Android SDK """ from __future__ import annotations import math import time import random from typing import Any, Callable, Dict, List, Optional, Tuple from .._core import Stub, AndroidOnlyError from .hardware import SensorManager as _BaseSensorManager from .hardware import Sensor as _BaseSensor from .hardware import SensorEvent as _BaseSensorEvent from .hardware import SensorEventListener as _BaseSensorEventListener __all__ = [ "Sensor", "SensorEvent", "SensorEventListener", "SensorManager", "SensorDirectChannel", "SensorDirectChannelConfig", "SensorPrivacyManager", "SensorAvailability", "SensorAdditionalInfo", "SensorDynamicSensorCallback", "SensorOffload", "SensorOffloadSession", "SensorRequest", ] # ═══════════════════════════════════════════════════════════════ # 传感器常量 # ═══════════════════════════════════════════════════════════════ TYPE_ACCELEROMETER = 1 TYPE_MAGNETIC_FIELD = 2 TYPE_ORIENTATION = 3 TYPE_GYROSCOPE = 4 TYPE_LIGHT = 5 TYPE_PRESSURE = 6 TYPE_TEMPERATURE = 7 TYPE_PROXIMITY = 8 TYPE_GRAVITY = 9 TYPE_LINEAR_ACCELERATION = 10 TYPE_ROTATION_VECTOR = 11 TYPE_RELATIVE_HUMIDITY = 12 TYPE_AMBIENT_TEMPERATURE = 13 TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14 TYPE_GAME_ROTATION_VECTOR = 15 TYPE_GYROSCOPE_UNCALIBRATED = 16 TYPE_SIGNIFICANT_MOTION = 17 TYPE_STEP_DETECTOR = 18 TYPE_STEP_COUNTER = 19 TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20 TYPE_HEART_RATE = 21 TYPE_TILT_DETECTOR = 22 TYPE_WAKE_GESTURE = 23 TYPE_GLANCE_GESTURE = 24 TYPE_PICK_UP_GESTURE = 25 TYPE_WRIST_TILT_GESTURE = 26 TYPE_DEVICE_ORIENTATION = 27 TYPE_STATIONARY_DETECT = 28 TYPE_POSE_6DOF = 28 TYPE_STATIONARY_DETECT_EXT = 29 TYPE_MOTION_DETECT = 30 TYPE_HEART_BEAT = 31 TYPE_LOW_LATENCY_OFFBODY_DETECT = 34 TYPE_ACCELEROMETER_LIMITED_AXES = 35 TYPE_GYROSCOPE_LIMITED_AXES = 36 TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED = 37 TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED = 38 TYPE_HEAD_TRACKER = 39 TYPE_ACCELEROMETER_UNCALIBRATED = 40 TYPE_HINGE_ANGLE = 41 REPORTING_MODE_CONTINUOUS = 0 REPORTING_MODE_ON_CHANGE = 1 REPORTING_MODE_ONE_SHOT = 2 REPORTING_MODE_SPECIAL_TRIGGER = 3 DIRECT_RATE_NONE = 0 DIRECT_RATE_NORMAL = 1 DIRECT_RATE_FAST = 2 DIRECT_RATE_VERY_FAST = 3 DIRECT_CHANNEL_TYPE_HARDWARE = 1 DIRECT_CHANNEL_TYPE_SOFTWARE = 2 DIRECT_CHANNEL_SENSOR_NONE = 0 SENSOR_STATUS_NO_CONTACT = -1 SENSOR_STATUS_UNRELIABLE = 0 SENSOR_STATUS_ACCURACY_LOW = 1 SENSOR_STATUS_ACCURACY_MEDIUM = 2 SENSOR_STATUS_ACCURACY_HIGH = 3 AXIS_X = 1 AXIS_Y = 2 AXIS_Z = 3 AXIS_MINUS_X = 4 AXIS_MINUS_Y = 5 AXIS_MINUS_Z = 6 # ═══════════════════════════════════════════════════════════════ # Sensor (扩展) # ═══════════════════════════════════════════════════════════════ class Sensor(_BaseSensor): """Sensor — 传感器 (完整版,继承 hardware.Sensor 的所有方法)""" TYPE_ACCELEROMETER = TYPE_ACCELEROMETER TYPE_MAGNETIC_FIELD = TYPE_MAGNETIC_FIELD TYPE_ORIENTATION = TYPE_ORIENTATION TYPE_GYROSCOPE = TYPE_GYROSCOPE TYPE_LIGHT = TYPE_LIGHT TYPE_PRESSURE = TYPE_PRESSURE TYPE_PROXIMITY = TYPE_PROXIMITY TYPE_GRAVITY = TYPE_GRAVITY TYPE_LINEAR_ACCELERATION = TYPE_LINEAR_ACCELERATION TYPE_ROTATION_VECTOR = TYPE_ROTATION_VECTOR TYPE_RELATIVE_HUMIDITY = TYPE_RELATIVE_HUMIDITY TYPE_AMBIENT_TEMPERATURE = TYPE_AMBIENT_TEMPERATURE TYPE_STEP_COUNTER = TYPE_STEP_COUNTER TYPE_STEP_DETECTOR = TYPE_STEP_DETECTOR TYPE_HEART_RATE = TYPE_HEART_RATE TYPE_SIGNIFICANT_MOTION = TYPE_SIGNIFICANT_MOTION TYPE_GAME_ROTATION_VECTOR = TYPE_GAME_ROTATION_VECTOR TYPE_GEOMAGNETIC_ROTATION_VECTOR = TYPE_GEOMAGNETIC_ROTATION_VECTOR TYPE_DEVICE_ORIENTATION = TYPE_DEVICE_ORIENTATION TYPE_STATIONARY_DETECT = TYPE_STATIONARY_DETECT TYPE_MOTION_DETECT = TYPE_MOTION_DETECT TYPE_HEART_BEAT = TYPE_HEART_BEAT TYPE_LOW_LATENCY_OFFBODY_DETECT = TYPE_LOW_LATENCY_OFFBODY_DETECT TYPE_HINGE_ANGLE = TYPE_HINGE_ANGLE TYPE_HEAD_TRACKER = TYPE_HEAD_TRACKER REPORTING_MODE_CONTINUOUS = REPORTING_MODE_CONTINUOUS REPORTING_MODE_ON_CHANGE = REPORTING_MODE_ON_CHANGE REPORTING_MODE_ONE_SHOT = REPORTING_MODE_ONE_SHOT REPORTING_MODE_SPECIAL_TRIGGER = REPORTING_MODE_SPECIAL_TRIGGER SENSOR_STATUS_NO_CONTACT = SENSOR_STATUS_NO_CONTACT SENSOR_STATUS_UNRELIABLE = SENSOR_STATUS_UNRELIABLE SENSOR_STATUS_ACCURACY_LOW = SENSOR_STATUS_ACCURACY_LOW SENSOR_STATUS_ACCURACY_MEDIUM = SENSOR_STATUS_ACCURACY_MEDIUM SENSOR_STATUS_ACCURACY_HIGH = SENSOR_STATUS_ACCURACY_HIGH def __init__(self, type_: int = TYPE_ACCELEROMETER, name: str = "Simulated Sensor", vendor: str = "Android-pyApi", version: int = 1, resolution: float = 1.0, max_range: float = 100.0, power: float = 0.5, min_delay: int = 10000, max_delay: int = 1000000, reporting_mode: int = REPORTING_MODE_CONTINUOUS, is_wake_up: bool = False, is_dynamic: bool = False, fifo_reserved_event_count: int = 0, fifo_max_event_count: int = 0, id_: int = 0): super().__init__(type_, name, vendor, version, resolution, max_range, power, min_delay) self._type = type_ self._name = name self._vendor = vendor self._version = version self._resolution = resolution self._max_range = max_range self._power = power self._min_delay = min_delay self._max_delay = max_delay self._reporting_mode = reporting_mode self._is_wake_up = is_wake_up self._is_dynamic = is_dynamic self._fifo_reserved_event_count = fifo_reserved_event_count self._fifo_max_event_count = fifo_max_event_count self._id = id_ self._string_type = "" def getType(self) -> int: return self._type def getName(self) -> str: return self._name def getVendor(self) -> str: return self._vendor def getVersion(self) -> int: return self._version def getMaximumRange(self) -> float: return self._max_range def getResolution(self) -> float: return self._resolution def getPower(self) -> float: return self._power def getMinDelay(self) -> int: return self._min_delay def getMaxDelay(self) -> int: return self._max_delay def getReportingMode(self) -> int: return self._reporting_mode def isWakeUpSensor(self) -> bool: return self._is_wake_up def isDynamicSensor(self) -> bool: return self._is_dynamic def getFifoReservedEventCount(self) -> int: return self._fifo_reserved_event_count def getFifoMaxEventCount(self) -> int: return self._fifo_max_event_count def getId(self) -> int: return self._id def getStringType(self) -> str: if self._string_type: return self._string_type type_names = { 1: "android.sensor.accelerometer", 2: "android.sensor.magnetic_field", 3: "android.sensor.orientation", 4: "android.sensor.gyroscope", 5: "android.sensor.light", 6: "android.sensor.pressure", 8: "android.sensor.proximity", 9: "android.sensor.gravity", 10: "android.sensor.linear_acceleration", 11: "android.sensor.rotation_vector", 12: "android.sensor.relative_humidity", 13: "android.sensor.ambient_temperature", 19: "android.sensor.step_counter", 18: "android.sensor.step_detector", 21: "android.sensor.heart_rate", } return type_names.get(self._type, f"android.sensor.type_{self._type}") def toString(self) -> str: return (f"Sensor(name={self._name}, type={self._type}, " f"vendor={self._vendor})") def equals(self, other: Any) -> bool: if not isinstance(other, Sensor): return False return self._type == other._type and self._name == other._name def hashCode(self) -> int: return hash((self._type, self._name)) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SensorEvent # ═══════════════════════════════════════════════════════════════ class SensorEvent(_BaseSensorEvent): """SensorEvent — 传感器事件 (继承 hardware.SensorEvent 的所有方法)""" def __init__(self, sensor: Optional[Sensor] = None, values: List[float] = None, accuracy: int = SENSOR_STATUS_ACCURACY_HIGH, timestamp: int = 0): if sensor is not None: super().__init__(sensor, accuracy) else: Stub.__init__(self) self.sensor = sensor self.values = values or [0.0, 0.0, 0.0] self.accuracy = accuracy self.timestamp = timestamp or int(time.time() * 1000000) def getSensor(self) -> Optional[Sensor]: return self.sensor def getValues(self) -> List[float]: return list(self.values) def getAccuracy(self) -> int: return self.accuracy def getTimestamp(self) -> int: return self.timestamp def toString(self) -> str: return (f"SensorEvent(sensor={self.sensor}, " f"values={self.values}, accuracy={self.accuracy})") def equals(self, other: Any) -> bool: if not isinstance(other, SensorEvent): return False return self.timestamp == other.timestamp def hashCode(self) -> int: return self.timestamp & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SensorEventListener # ═══════════════════════════════════════════════════════════════ class SensorEventListener(_BaseSensorEventListener): """SensorEventListener — 传感器事件监听器 (继承 hardware.SensorEventListener 的所有方法)""" def onSensorChanged(self, event: SensorEvent): pass def onAccuracyChanged(self, sensor: Sensor, accuracy: int): pass def toString(self) -> str: return f"SensorEventListener@{hex(id(self))}" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SensorManager (扩展) # ═══════════════════════════════════════════════════════════════ class SensorManager(_BaseSensorManager): """SensorManager — 传感器管理器 (完整版,继承 hardware.SensorManager)""" AXIS_X = AXIS_X AXIS_Y = AXIS_Y AXIS_Z = AXIS_Z AXIS_MINUS_X = AXIS_MINUS_X AXIS_MINUS_Y = AXIS_MINUS_Y AXIS_MINUS_Z = AXIS_MINUS_Z SENSOR_DELAY_FASTEST = 0 SENSOR_DELAY_GAME = 1 SENSOR_DELAY_UI = 2 SENSOR_DELAY_NORMAL = 3 DIRECT_RATE_NONE = DIRECT_RATE_NONE DIRECT_RATE_NORMAL = DIRECT_RATE_NORMAL DIRECT_RATE_FAST = DIRECT_RATE_FAST DIRECT_RATE_VERY_FAST = DIRECT_RATE_VERY_FAST def __init__(self): super().__init__() self._sensors: Dict[int, Sensor] = {} self._listeners: Dict[int, Tuple[SensorEventListener, Sensor, int]] = {} self._dynamic_sensor_callbacks: Dict[int, SensorDynamicSensorCallback] = {} self._privacy_manager = SensorPrivacyManager() self._direct_channels: Dict[int, SensorDirectChannel] = {} self._platform_sensors() def _platform_sensors(self): types = [ (Sensor.TYPE_ACCELEROMETER, "Accelerometer", 0.01, 39.24, 3.0, 10000), (Sensor.TYPE_GYROSCOPE, "Gyroscope", 0.001, 34.91, 6.1, 10000), (Sensor.TYPE_MAGNETIC_FIELD, "Magnetic Field", 0.01, 2000.0, 4.0, 10000), (Sensor.TYPE_LIGHT, "Light", 1.0, 40000.0, 0.5, 10000), (Sensor.TYPE_PROXIMITY, "Proximity", 1.0, 10.0, 0.5, 10000), (Sensor.TYPE_PRESSURE, "Pressure", 0.01, 1100.0, 1.0, 10000), (Sensor.TYPE_GRAVITY, "Gravity", 0.01, 39.24, 3.0, 10000), (Sensor.TYPE_LINEAR_ACCELERATION, "Linear Acceleration", 0.01, 39.24, 3.0, 10000), (Sensor.TYPE_ROTATION_VECTOR, "Rotation Vector", 0.0001, 1.0, 5.0, 10000), (Sensor.TYPE_RELATIVE_HUMIDITY, "Relative Humidity", 0.1, 100.0, 0.5, 10000), (Sensor.TYPE_AMBIENT_TEMPERATURE, "Ambient Temperature", 0.01, 80.0, 0.5, 10000), (Sensor.TYPE_STEP_COUNTER, "Step Counter", 1.0, 100000.0, 0.1, 100000), (Sensor.TYPE_STEP_DETECTOR, "Step Detector", 1.0, 1.0, 0.1, 100000), (Sensor.TYPE_HEART_RATE, "Heart Rate", 1.0, 220.0, 0.5, 100000), (Sensor.TYPE_SIGNIFICANT_MOTION, "Significant Motion", 1.0, 1.0, 0.1, 100000), (Sensor.TYPE_DEVICE_ORIENTATION, "Device Orientation", 1.0, 360.0, 0.5, 10000), (Sensor.TYPE_STATIONARY_DETECT, "Stationary Detect", 1.0, 1.0, 0.1, 100000), (Sensor.TYPE_MOTION_DETECT, "Motion Detect", 1.0, 1.0, 0.1, 100000), (Sensor.TYPE_LOW_LATENCY_OFFBODY_DETECT, "Off-Body Detect", 1.0, 1.0, 0.1, 100000), (Sensor.TYPE_HINGE_ANGLE, "Hinge Angle", 0.1, 360.0, 0.1, 10000), (Sensor.TYPE_HEAD_TRACKER, "Head Tracker", 0.01, 360.0, 1.0, 5000), ] for i, (t, n, r, mr, p, md) in enumerate(types): self._sensors[t] = Sensor( type_=t, name=n, resolution=r, max_range=mr, power=p, min_delay=md, id_=i, ) def getDefaultSensor(self, type_: int) -> Optional[Sensor]: return self._sensors.get(type_) def getSensorList(self, type_: int) -> List[Sensor]: if type_ == -1: return list(self._sensors.values()) return [s for s in self._sensors.values() if s.getType() == type_] def registerListener(self, listener: SensorEventListener, sensor: Sensor, samplingPeriodUs: int = SENSOR_DELAY_NORMAL, maxReportLatencyUs: int = 0) -> bool: lid = id(listener) self._listeners[lid] = (listener, sensor, samplingPeriodUs) return True def unregisterListener(self, listener: SensorEventListener, sensor: Sensor = None): lid = id(listener) if sensor and lid in self._listeners: _, reg_sensor, _ = self._listeners[lid] if reg_sensor == sensor: del self._listeners[lid] else: self._listeners.pop(lid, None) def registerDynamicSensorCallback(self, callback: SensorDynamicSensorCallback, handler: Any = None): lid = id(callback) self._dynamic_sensor_callbacks[lid] = callback def unregisterDynamicSensorCallback(self, callback: SensorDynamicSensorCallback): lid = id(callback) self._dynamic_sensor_callbacks.pop(lid, None) def createDirectChannel(self, config: "SensorDirectChannelConfig") -> Optional["SensorDirectChannel"]: channel = SensorDirectChannel(config=config, manager=self) cid = id(channel) self._direct_channels[cid] = channel return channel def destroyDirectChannel(self, channel: "SensorDirectChannel"): cid = id(channel) self._direct_channels.pop(cid, None) def getSensorPrivacyManager(self) -> "SensorPrivacyManager": return self._privacy_manager def flush(self, listener: SensorEventListener) -> bool: return True def getDynamicSensorList(self, type_: int) -> List[Sensor]: return [s for s in self._sensors.values() if s.isDynamicSensor() and (type_ == -1 or s.getType() == type_)] def requestSensor(self, request: "SensorRequest") -> bool: return True def getSensorAvailability(self, type_: int) -> "SensorAvailability": return SensorAvailability(available=type_ in self._sensors) def createOffloadSession(self) -> "SensorOffloadSession": return SensorOffloadSession() def getSensorOffload(self) -> "SensorOffload": return SensorOffload() def toString(self) -> str: return f"SensorManager(sensors={len(self._sensors)})" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SensorDirectChannelConfig # ═══════════════════════════════════════════════════════════════ class SensorDirectChannelConfig(Stub): """SensorDirectChannelConfig — 传感器直连通道配置""" def __init__(self, type_: int = DIRECT_CHANNEL_TYPE_SOFTWARE, size: int = 4096, rate: int = DIRECT_RATE_NORMAL, shared_mem_fd: int = -1): super().__init__() self._type = type_ self._size = size self._rate = rate self._shared_mem_fd = shared_mem_fd def getType(self) -> int: return self._type def getSize(self) -> int: return self._size def getRate(self) -> int: return self._rate def getSharedMemFd(self) -> int: return self._shared_mem_fd def toString(self) -> str: return f"SensorDirectChannelConfig(type={self._type}, size={self._size})" # ═══════════════════════════════════════════════════════════════ # SensorDirectChannel # ═══════════════════════════════════════════════════════════════ class SensorDirectChannel(Stub): """SensorDirectChannel — 传感器直连通道""" TYPE_HARDWARE = DIRECT_CHANNEL_TYPE_HARDWARE TYPE_SOFTWARE = DIRECT_CHANNEL_TYPE_SOFTWARE RATE_NONE = DIRECT_RATE_NONE RATE_NORMAL = DIRECT_RATE_NORMAL RATE_FAST = DIRECT_RATE_FAST RATE_VERY_FAST = DIRECT_RATE_VERY_FAST def __init__(self, config: Optional[SensorDirectChannelConfig] = None, manager: Optional[SensorManager] = None): super().__init__() self._config = config self._manager = manager self._configured_sensors: List[Sensor] = [] self._is_valid = True def isOpen(self) -> bool: return self._is_valid def close(self): self._is_valid = False if self._manager: self._manager.destroyDirectChannel(self) def configure(self, sensor: Sensor, rate: int) -> int: if not self._is_valid: return -1 self._configured_sensors.append(sensor) return 0 def getConfiguredSensors(self) -> List[Sensor]: return list(self._configured_sensors) def toString(self) -> str: return f"SensorDirectChannel(open={self._is_valid})" # ═══════════════════════════════════════════════════════════════ # SensorPrivacyManager # ═══════════════════════════════════════════════════════════════ class SensorPrivacyManager(Stub): """SensorPrivacyManager — 传感器隐私管理器""" SOURCE_MICROPHONE = 1 SOURCE_CAMERA = 2 SOURCE_LOCATION = 3 SOURCE_ALL = -1 STATE_DISABLED = 0 STATE_ENABLED = 1 def __init__(self): super().__init__() self._mic_muted = False self._camera_disabled = False self._listeners: Dict[int, Callable] = {} def isSensorPrivacyEnabled(self, source: int) -> bool: if source == SensorPrivacyManager.SOURCE_MICROPHONE: return self._mic_muted if source == SensorPrivacyManager.SOURCE_CAMERA: return self._camera_disabled return False def setSensorPrivacy(self, source: int, enabled: bool): if source == SensorPrivacyManager.SOURCE_MICROPHONE: self._mic_muted = enabled elif source == SensorPrivacyManager.SOURCE_CAMERA: self._camera_disabled = enabled elif source == SensorPrivacyManager.SOURCE_ALL: self._mic_muted = enabled self._camera_disabled = enabled def addSensorPrivacyListener(self, source: int, callback: Callable): lid = id(callback) self._listeners[lid] = callback def removeSensorPrivacyListener(self, source: int, callback: Callable): lid = id(callback) self._listeners.pop(lid, None) def toString(self) -> str: return f"SensorPrivacyManager(micMuted={self._mic_muted})" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SensorAvailability # ═══════════════════════════════════════════════════════════════ class SensorAvailability(Stub): """SensorAvailability — 传感器可用性""" def __init__(self, available: bool = True, type_: int = TYPE_ACCELEROMETER, reason: str = ""): super().__init__() self._available = available self._type = type_ self._reason = reason def isAvailable(self) -> bool: return self._available def getType(self) -> int: return self._type def getReason(self) -> str: return self._reason def toString(self) -> str: return f"SensorAvailability(type={self._type}, available={self._available})" # ═══════════════════════════════════════════════════════════════ # SensorAdditionalInfo # ═══════════════════════════════════════════════════════════════ class SensorAdditionalInfo(Stub): """SensorAdditionalInfo — 传感器附加信息""" TYPE_FRAME_BEGIN = 0 TYPE_FRAME_END = 1 TYPE_UNTRACKED_DELAY = 65536 TYPE_INTERNAL_TEMPERATURE = 65537 TYPE_VEC3_CALIBRATION = 65538 TYPE_SENSOR_PLACEMENT = 65539 TYPE_SAMPLE_0 = 65540 TYPE_LOCAL_GEOMAGNETIC_FIELD = 65541 TYPE_LOCAL_GRAVITY = 65542 TYPE_DOCK_STATE = 65543 TYPE_HIGH_LEVEL_EVENT = 65544 TYPE_MAGNETIC_FIELD_CALIBRATION = 65545 def __init__(self, sensor: Optional[Sensor] = None, type_: int = TYPE_FRAME_BEGIN, serialized: List[int] = None, values: List[float] = None): super().__init__() self.sensor = sensor self.type = type_ self.serialized = serialized or [] self.values = values or [] def getSensor(self) -> Optional[Sensor]: return self.sensor def getType(self) -> int: return self.type def getSerialized(self) -> List[int]: return list(self.serialized) def getValues(self) -> List[float]: return list(self.values) def toString(self) -> str: return f"SensorAdditionalInfo(type={self.type})" # ═══════════════════════════════════════════════════════════════ # SensorDynamicSensorCallback # ═══════════════════════════════════════════════════════════════ class SensorDynamicSensorCallback(Stub): """SensorDynamicSensorCallback — 动态传感器回调""" def onDynamicSensorConnected(self, sensor: Sensor): pass def onDynamicSensorDisconnected(self, sensor: Sensor): pass def toString(self) -> str: return f"SensorDynamicSensorCallback@{hex(id(self))}" def equals(self, other: Any) -> bool: return self is other def hashCode(self) -> int: return id(self) & 0x7FFFFFFF # ═══════════════════════════════════════════════════════════════ # SensorOffload / SensorOffloadSession # ═══════════════════════════════════════════════════════════════ class SensorOffload(Stub): """SensorOffload — 传感器卸载""" def __init__(self): super().__init__() def createSession(self) -> "SensorOffloadSession": return SensorOffloadSession() def getMaxSensorsPerSession(self) -> int: return 16 def isSupported(self) -> bool: return True def toString(self) -> str: return "SensorOffload()" class SensorOffloadSession(Stub): """SensorOffloadSession — 传感器卸载会话""" STATE_IDLE = 0 STATE_ACTIVE = 1 STATE_SUSPENDED = 2 STATE_ERROR = 3 def __init__(self): super().__init__() self._state = SensorOffloadSession.STATE_IDLE self._sensors: List[Sensor] = [] self._sampling_period_us = 0 self._max_report_latency_us = 0 def getState(self) -> int: return self._state def start(self, sensors: List[Sensor], samplingPeriodUs: int, maxReportLatencyUs: int = 0): self._sensors = list(sensors) self._sampling_period_us = samplingPeriodUs self._max_report_latency_us = maxReportLatencyUs self._state = SensorOffloadSession.STATE_ACTIVE def stop(self): self._state = SensorOffloadSession.STATE_IDLE self._sensors.clear() def suspend(self): self._state = SensorOffloadSession.STATE_SUSPENDED def resume(self): if self._state == SensorOffloadSession.STATE_SUSPENDED: self._state = SensorOffloadSession.STATE_ACTIVE def getSensors(self) -> List[Sensor]: return list(self._sensors) def getSamplingPeriodUs(self) -> int: return self._sampling_period_us def getMaxReportLatencyUs(self) -> int: return self._max_report_latency_us def toString(self) -> str: return f"SensorOffloadSession(state={self._state}, sensors={len(self._sensors)})" # ═══════════════════════════════════════════════════════════════ # SensorRequest / SensorRequest.Builder # ═══════════════════════════════════════════════════════════════ class SensorRequest(Stub): """SensorRequest — 传感器请求""" def __init__(self, sensor: Optional[Sensor] = None, samplingPeriodUs: int = 100000, maxReportLatencyUs: int = 0, isWakeUp: bool = False): super().__init__() self._sensor = sensor self._sampling_period_us = samplingPeriodUs self._max_report_latency_us = maxReportLatencyUs self._is_wake_up = isWakeUp def getSensor(self) -> Optional[Sensor]: return self._sensor def getSamplingPeriodUs(self) -> int: return self._sampling_period_us def getMaxReportLatencyUs(self) -> int: return self._max_report_latency_us def isWakeUp(self) -> bool: return self._is_wake_up class Builder(Stub): """SensorRequest.Builder — 传感器请求构建器""" def __init__(self): super().__init__() self._sensor: Optional[Sensor] = None self._sampling_period_us = 100000 self._max_report_latency_us = 0 self._is_wake_up = False def setSensor(self, sensor: Sensor) -> "SensorRequest.Builder": self._sensor = sensor return self def setSamplingPeriodUs(self, periodUs: int) -> "SensorRequest.Builder": self._sampling_period_us = periodUs return self def setMaxReportLatencyUs(self, latencyUs: int) -> "SensorRequest.Builder": self._max_report_latency_us = latencyUs return self def setWakeUp(self, wakeUp: bool) -> "SensorRequest.Builder": self._is_wake_up = wakeUp return self def build(self) -> "SensorRequest": return SensorRequest( sensor=self._sensor, samplingPeriodUs=self._sampling_period_us, maxReportLatencyUs=self._max_report_latency_us, isWakeUp=self._is_wake_up, ) def toString(self) -> str: return (f"SensorRequest(sensor={self._sensor}, " f"period={self._sampling_period_us}us)") def equals(self, other: Any) -> bool: if not isinstance(other, SensorRequest): return False return (self._sensor == other._sensor and self._sampling_period_us == other._sampling_period_us) def hashCode(self) -> int: return hash((id(self._sensor), self._sampling_period_us)) & 0x7FFFFFFF