Skip to content

Commit 26573ac

Browse files
committed
Add SensorManager
1 parent c8766eb commit 26573ac

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
//
2+
// SensorManager.swift
3+
// SwiftAndroid
4+
//
5+
// Created by Alsey Coleman Miller on 7/6/25.
6+
//
7+
8+
#if os(Android)
9+
import Android
10+
import AndroidNDK
11+
#endif
12+
import AndroidLooper
13+
14+
/// Manages access to the device's hardware sensors.
15+
///
16+
/// Obtain an instance via ``init(package:)``, then enumerate available sensors
17+
/// or create event queues for receiving data.
18+
public struct SensorManager: @unchecked Sendable {
19+
20+
internal let pointer: OpaquePointer
21+
22+
internal init(_ pointer: OpaquePointer) {
23+
self.pointer = pointer
24+
}
25+
}
26+
27+
// MARK: - Initialization
28+
29+
public extension SensorManager {
30+
31+
/// Returns the sensor manager for the given package name.
32+
///
33+
/// - Parameter package: The package name of the calling application
34+
/// (e.g. `"com.example.myapp"`).
35+
/// - Throws: `AndroidSensorError.invalidManager` if the system could not
36+
/// return a sensor manager for the provided package.
37+
init(package: String) throws(AndroidSensorError) {
38+
guard let pointer = package.withCString({ ASensorManager_getInstanceForPackage($0) }) else {
39+
throw .invalidManager
40+
}
41+
self.init(pointer)
42+
}
43+
}
44+
45+
// MARK: - Sensors
46+
47+
public extension SensorManager {
48+
49+
/// Returns all sensors available on the device.
50+
var sensors: [Sensor] {
51+
var list: UnsafePointer<OpaquePointer>?
52+
let count = ASensorManager_getSensorList(pointer, &list)
53+
guard count > 0, let list else { return [] }
54+
return (0 ..< Int(count)).map { Sensor(list[$0]) }
55+
}
56+
57+
/// Returns the default sensor of the given type, or `nil` if none exists.
58+
func defaultSensor(type: SensorType) -> Sensor? {
59+
ASensorManager_getDefaultSensor(pointer, type.rawValue).map { Sensor($0) }
60+
}
61+
62+
/// Returns the default sensor of the given type with optional wake-up support.
63+
///
64+
/// - Parameters:
65+
/// - type: The sensor type.
66+
/// - wakeUp: Pass `true` to request a wake-up sensor variant.
67+
func defaultSensor(type: SensorType, wakeUp: Bool) -> Sensor? {
68+
ASensorManager_getDefaultSensorEx(pointer, type.rawValue, wakeUp).map { Sensor($0) }
69+
}
70+
}
71+
72+
// MARK: - Event Queue
73+
74+
public extension SensorManager {
75+
76+
/// Creates an event queue associated with the given looper.
77+
///
78+
/// Events will be delivered to `callback` (if non-nil) on the looper's
79+
/// thread; otherwise your code must call `SensorEventQueue.getEvents()`
80+
/// in response to looper activity signalled on `ident`.
81+
///
82+
/// - Parameters:
83+
/// - looper: The looper that will receive sensor events.
84+
/// - ident: Identifier returned by `ALooper_pollOnce` when events are
85+
/// available and `callback` is `nil`. Must be ≥ 0 in that case.
86+
/// - callback: Optional C callback invoked on each event batch.
87+
/// - data: User data pointer passed to `callback`.
88+
func createEventQueue(
89+
looper: borrowing Looper,
90+
ident: Int32 = 0,
91+
callback: ALooper_callbackFunc? = nil,
92+
data: UnsafeMutableRawPointer? = nil
93+
) throws(AndroidSensorError) -> SensorEventQueue {
94+
let queuePointer = looper.withUnsafePointer { looperPtr in
95+
ASensorManager_createEventQueue(pointer, looperPtr, ident, callback, data)
96+
}
97+
guard let queuePointer else {
98+
throw .createEventQueue
99+
}
100+
return SensorEventQueue(queue: queuePointer, manager: pointer)
101+
}
102+
}

0 commit comments

Comments
 (0)