类继承冲突修复 (7个文件, 8组冲突): - view_ext.py: 16个类继承view.py基础版本 (ViewOutlineProvider, ViewPropertyAnimator, ViewTreeObserver, ViewConfiguration, ViewParent, WindowInsets, Display, DragEvent, GestureDetector, ScaleGestureDetector, SoundEffectConstants, Surface, SurfaceView, TextureView, VelocityTracker, WindowInsetsController) - hardware_sensor_ext.py: 3个类继承hardware.py (Sensor, SensorEvent, SensorEventListener) - app_fragment.py: 3个类继承app.py (Fragment, FragmentManager, FragmentTransaction) - content_intent.py: 3个类继承content.py/app.py (Intent, PendingIntent, IntentFilter) - widget_ext.py: 29个类继承widget.py (18个单继承+11个多继承, 修复super()链) - os_power.py: 2个类继承os.py (BatteryManager, PowerManager) - net_ext.py: 12个类继承net.py (11个单继承+1个多继承) __all__导出补全 (36个类): - java.net: InterfaceAddress - android.database: MatrixCursor, SQLiteStatement - android.view: GestureDetector, ScaleGestureDetector, SurfaceHolder, Surface, SurfaceView, TextureView, ViewOutlineProvider, WindowManager, Window, LayoutInflater, Menu, MenuItem, ContextMenu, Display, DisplayMetrics - android.graphics: Region, PathMeasure, NinePatch, Picture, PictureDrawable, Camera, PorterDuff, PorterDuffXfermode, Shader, LinearGradient, RadialGradient, SweepGradient, BitmapShader, ComposeShader, CornerPathEffect, DashPathEffect, PathDashPathEffect, SumPathEffect - android.widget: LinearLayout, FrameLayout, RelativeLayout, TableLayout, TableRow, BaseAdapter, ArrayAdapter, SimpleAdapter, CursorAdapter, ImageButton, ToggleButton, RadioButton, SeekBar, RatingBar, ViewSwitcher, TextSwitcher, ImageSwitcher, SearchView, NumberPicker, Chronometer, TabHost, TabWidget, ViewAnimator, ZoomControls, DigitalClock, AnalogClock 统计: 221模块, 3666类, 31005方法, 183629行
831 lines
31 KiB
Python
831 lines
31 KiB
Python
"""
|
|
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 |