@mentra/bluetooth-sdk 0.1.19 → 0.1.21-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +239 -52
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +65 -14
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +47 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +6 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +381 -97
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraLocalNetworkModule.kt +333 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +16 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.kt +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1TextSanitizer.kt +38 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +16 -9
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +293 -174
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Nimo.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +4 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/status/WifiHotspotStatus.kt +19 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +15 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/tts/TTSTools.kt +115 -47
- package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +2 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +65 -8
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/K900ProtocolUtils.java +6 -5
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/PcmStreamPlayer.kt +328 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/BluetoothSdkExceptionTest.kt +18 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +31 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/G1TextSanitizerTest.kt +31 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadServiceTest.java +9 -0
- package/build/BluetoothSdk.types.d.ts +71 -1
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_internal.d.ts +2 -0
- package/build/_internal.d.ts.map +1 -1
- package/build/_internal.js +2 -0
- package/build/_internal.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +27 -2
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +20 -0
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/_private/MentraLocalNetworkModule.d.ts +37 -0
- package/build/_private/MentraLocalNetworkModule.d.ts.map +1 -0
- package/build/_private/MentraLocalNetworkModule.js +3 -0
- package/build/_private/MentraLocalNetworkModule.js.map +1 -0
- package/build/_private/cameraRequestPayload.d.ts.map +1 -1
- package/build/_private/cameraRequestPayload.js +1 -0
- package/build/_private/cameraRequestPayload.js.map +1 -1
- package/build/_private/photoRequestPayload.d.ts.map +1 -1
- package/build/_private/photoRequestPayload.js +2 -0
- package/build/_private/photoRequestPayload.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +9 -0
- package/build/index.js.map +1 -1
- package/expo-module.config.json +1 -0
- package/ios/BluetoothSdkModule.swift +72 -0
- package/ios/Source/BluetoothSdkDefaults.swift +1 -1
- package/ios/Source/Bridge.swift +72 -18
- package/ios/Source/DeviceManager.swift +52 -3
- package/ios/Source/DeviceStore.swift +6 -1
- package/ios/Source/MentraBluetoothSDK.swift +298 -21
- package/ios/Source/audio/PcmStreamPlayer.swift +410 -0
- package/ios/Source/camera/CameraModels.swift +22 -3
- package/ios/Source/sgcs/G1.swift +2 -2
- package/ios/Source/sgcs/G2.swift +19 -7
- package/ios/Source/sgcs/Mach1.swift +1 -1
- package/ios/Source/sgcs/MentraLive.swift +456 -52
- package/ios/Source/sgcs/MentraLiveL2capChannel.swift +183 -0
- package/ios/Source/sgcs/MentraNex.swift +1 -1
- package/ios/Source/sgcs/Nimo.swift +1 -1
- package/ios/Source/sgcs/SGCManager.swift +5 -2
- package/ios/Source/sgcs/Simulated.swift +1 -1
- package/ios/Source/status/WifiHotspotStatus.swift +21 -2
- package/ios/Source/streaming/StreamModels.swift +9 -0
- package/ios/Source/tts/TTSTools.swift +1 -1
- package/ios/Source/utils/G1Text.swift +30 -1
- package/package.json +1 -2
- package/src/BluetoothSdk.types.ts +75 -0
- package/src/_internal.ts +2 -0
- package/src/_private/BluetoothSdkModule.ts +68 -13
- package/src/_private/MentraLocalNetworkModule.ts +50 -0
- package/src/_private/cameraRequestPayload.ts +1 -0
- package/src/_private/photoRequestPayload.ts +3 -3
- package/src/index.ts +10 -0
|
@@ -329,6 +329,11 @@ class DeviceManager {
|
|
|
329
329
|
return
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
+
if (sgc?.isMicSuspendedForAudio == true) {
|
|
333
|
+
Bridge.log("MAN: Glasses mic intentionally suspended for phone audio; skipping mic recovery")
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
|
|
332
337
|
// When no frame has ever been received, treat elapsed as "forever" so we
|
|
333
338
|
// actually attempt recovery (was 0 before, which made the watchdog a no-op).
|
|
334
339
|
val timeSinceLastLc3Event = System.currentTimeMillis() - (lastLc3Event ?: 0L)
|
|
@@ -1556,10 +1561,10 @@ class DeviceManager {
|
|
|
1556
1561
|
sgc?.sendStreamKeepAlive(message)
|
|
1557
1562
|
}
|
|
1558
1563
|
|
|
1559
|
-
fun requestWifiScan() {
|
|
1564
|
+
fun requestWifiScan(scanId: String? = null) {
|
|
1560
1565
|
Bridge.log("MAN: Requesting wifi scan")
|
|
1561
1566
|
DeviceStore.apply("bluetooth", "wifiScanResults", emptyList<Any>())
|
|
1562
|
-
sgc?.requestWifiScan()
|
|
1567
|
+
sgc?.requestWifiScan(scanId)
|
|
1563
1568
|
}
|
|
1564
1569
|
|
|
1565
1570
|
fun sendIncidentId(incidentId: String, apiBaseUrl: String? = null) {
|
|
@@ -1649,6 +1654,38 @@ class DeviceManager {
|
|
|
1649
1654
|
live.sendCameraFovSetting(requestId, fov, roiPosition)
|
|
1650
1655
|
}
|
|
1651
1656
|
|
|
1657
|
+
/** Sends the pre-lease FOV command used by ASG clients that do not send an acknowledgement. */
|
|
1658
|
+
fun sendLegacyCameraFovSetting(fov: Int, roiPosition: Int) {
|
|
1659
|
+
val glassesConnected = DeviceStore.get("glasses", "connected") as? Boolean ?: false
|
|
1660
|
+
if (!glassesConnected) throw IllegalStateException("not_connected")
|
|
1661
|
+
val live = sgc as? MentraLive ?: throw IllegalStateException("unsupported_device")
|
|
1662
|
+
live.sendCameraFovSetting(null, fov, roiPosition)
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
/** Replays the persistent base FOV without waiting for an acknowledgement. */
|
|
1666
|
+
fun restoreLegacyCameraFovSetting() {
|
|
1667
|
+
val glassesConnected = DeviceStore.get("glasses", "connected") as? Boolean ?: false
|
|
1668
|
+
if (!glassesConnected) throw IllegalStateException("not_connected")
|
|
1669
|
+
val live = sgc as? MentraLive ?: throw IllegalStateException("unsupported_device")
|
|
1670
|
+
live.sendCameraFovSetting()
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
fun sendCameraFovOverride(
|
|
1674
|
+
requestId: String,
|
|
1675
|
+
leaseId: String,
|
|
1676
|
+
fov: Int,
|
|
1677
|
+
roiPosition: Int,
|
|
1678
|
+
ttlMs: Int,
|
|
1679
|
+
) {
|
|
1680
|
+
val live = sgc as? MentraLive ?: throw IllegalStateException("unsupported_device")
|
|
1681
|
+
live.sendCameraFovOverride(requestId, leaseId, fov, roiPosition, ttlMs)
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
fun releaseCameraFovOverride(requestId: String, leaseId: String) {
|
|
1685
|
+
val live = sgc as? MentraLive ?: throw IllegalStateException("unsupported_device")
|
|
1686
|
+
live.releaseCameraFovOverride(requestId, leaseId)
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1652
1689
|
fun sendCameraTuningConfig(requestId: String, anrOn: Boolean, gainOn: Boolean) {
|
|
1653
1690
|
val live = sgc as? MentraLive ?: throw IllegalStateException("unsupported_device")
|
|
1654
1691
|
live.sendCameraTuningConfig(requestId, anrOn, gainOn)
|
|
@@ -1657,6 +1694,7 @@ class DeviceManager {
|
|
|
1657
1694
|
fun warmUpCamera(
|
|
1658
1695
|
requestId: String,
|
|
1659
1696
|
size: PhotoSize,
|
|
1697
|
+
mode: PhotoMode = PhotoMode.PHOTO,
|
|
1660
1698
|
exposureTimeNs: Long?,
|
|
1661
1699
|
durationMs: Int,
|
|
1662
1700
|
) {
|
|
@@ -1668,7 +1706,12 @@ class DeviceManager {
|
|
|
1668
1706
|
"unsupported_device",
|
|
1669
1707
|
"This command requires Mentra Live glasses.",
|
|
1670
1708
|
)
|
|
1671
|
-
live.warmUpCamera(requestId, size, exposureTimeNs, durationMs)
|
|
1709
|
+
live.warmUpCamera(requestId, size, mode, exposureTimeNs, durationMs)
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
fun stopCameraWarmUp(requestId: String) {
|
|
1713
|
+
val live = sgc as? MentraLive ?: throw IllegalStateException("unsupported_device")
|
|
1714
|
+
live.stopCameraWarmUp(requestId)
|
|
1672
1715
|
}
|
|
1673
1716
|
|
|
1674
1717
|
/**
|
|
@@ -1800,7 +1843,7 @@ class DeviceManager {
|
|
|
1800
1843
|
iso = manualIso,
|
|
1801
1844
|
)
|
|
1802
1845
|
Bridge.log(
|
|
1803
|
-
"MAN: PHOTO PIPELINE [4/6] DeviceManager.requestPhoto requestId=${routed.requestId} size=${routed.size.value} compress=${routed.compress.value} save=${routed.save} sound=${routed.sound} exposureTimeNs=$exposureNs iso=${manualIso ?: "auto"} aeDivisor=${routed.aeExposureDivisor} isoCap=${routed.isoCap} sgc=${sgc?.javaClass?.simpleName ?: "null"}"
|
|
1846
|
+
"MAN: PHOTO PIPELINE [4/6] DeviceManager.requestPhoto requestId=${routed.requestId} size=${routed.size.value} mode=${routed.mode.value} compress=${routed.compress.value} save=${routed.save} sound=${routed.sound} exposureTimeNs=$exposureNs iso=${manualIso ?: "auto"} aeDivisor=${routed.aeExposureDivisor} isoCap=${routed.isoCap} sgc=${sgc?.javaClass?.simpleName ?: "null"}"
|
|
1804
1847
|
)
|
|
1805
1848
|
val activeSgc = sgc
|
|
1806
1849
|
if (activeSgc == null) {
|
|
@@ -128,7 +128,7 @@ object DeviceStore {
|
|
|
128
128
|
store.set("bluetooth", "screen_disabled", false)
|
|
129
129
|
store.set("bluetooth", "button_photo_size", "max")
|
|
130
130
|
store.set("bluetooth", "button_max_recording_time", 10)
|
|
131
|
-
store.set("bluetooth", "camera_fov", mapOf("fov" to
|
|
131
|
+
store.set("bluetooth", "camera_fov", mapOf("fov" to 102, "roi_position" to 0))
|
|
132
132
|
store.set("bluetooth", "button_video_width", 1280)
|
|
133
133
|
store.set("bluetooth", "button_video_height", 720)
|
|
134
134
|
store.set("bluetooth", "button_video_fps", 30)
|
|
@@ -292,6 +292,11 @@ object DeviceStore {
|
|
|
292
292
|
"bluetooth" to "camera_fov" -> {
|
|
293
293
|
DeviceManager.getInstance().sgc?.sendCameraFovSetting()
|
|
294
294
|
}
|
|
295
|
+
"bluetooth" to "button_video_settings" -> {
|
|
296
|
+
DeviceManager.getInstance().sgc?.sendButtonVideoRecordingSettings()
|
|
297
|
+
}
|
|
298
|
+
// Legacy scalar keys remain supported for older hosts. New code should write the
|
|
299
|
+
// canonical button_video_settings object so width/height/fps update atomically.
|
|
295
300
|
"bluetooth" to "button_video_width",
|
|
296
301
|
"bluetooth" to "button_video_height",
|
|
297
302
|
"bluetooth" to "button_video_fps" -> {
|