@mentra/bluetooth-sdk 0.1.14 → 0.1.16
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 +4 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +22 -9
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +5 -20
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +358 -261
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +3 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +133 -52
- package/android/src/main/java/com/mentra/bluetoothsdk/OtaManifest.kt +12 -12
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +22 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +1 -22
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.kt +50 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +1184 -795
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +422 -78
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +3 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Nimo.kt +2532 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +15 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +5 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +2 -1
- package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +60 -1
- package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoProtocolTest.kt +333 -0
- package/build/BluetoothSdk.types.d.ts +39 -14
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js +1 -0
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_internal.d.ts +4 -4
- package/build/_internal.js +4 -4
- package/build/_internal.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +11 -3
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +5 -0
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/_private/cameraRequestPayload.d.ts +4 -0
- package/build/_private/cameraRequestPayload.d.ts.map +1 -0
- package/build/_private/cameraRequestPayload.js +25 -0
- package/build/_private/cameraRequestPayload.js.map +1 -0
- package/build/_private/photoRequestPayload.d.ts.map +1 -1
- package/build/_private/photoRequestPayload.js +8 -2
- 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 +72 -54
- package/build/index.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +40 -12
- package/ios/Source/Bridge.swift +4 -16
- package/ios/Source/DeviceManager.swift +72 -12
- package/ios/Source/MentraBluetoothSDK.swift +120 -50
- package/ios/Source/OtaManifest.swift +13 -13
- package/ios/Source/camera/CameraModels.swift +75 -9
- package/ios/Source/errors/{BluetoothError.swift → BluetoothSdkError.swift} +1 -1
- package/ios/Source/events/BluetoothEvents.swift +5 -27
- package/ios/Source/internal/BluetoothAvailability.swift +5 -5
- package/ios/Source/sgcs/G1.swift +51 -1
- package/ios/Source/sgcs/G2.swift +643 -203
- package/ios/Source/sgcs/MentraLive.swift +53 -39
- package/ios/Source/sgcs/Nimo.swift +1928 -0
- package/ios/Source/sgcs/SGCManager.swift +12 -5
- package/ios/Source/stt/STTTools.swift +1 -1
- package/ios/Source/types/DeviceModels.swift +5 -0
- package/ios/Source/utils/Constants.swift +2 -0
- package/package.json +6 -1
- package/src/BluetoothSdk.types.ts +42 -17
- package/src/_internal.ts +4 -4
- package/src/_private/BluetoothSdkModule.ts +18 -2
- package/src/_private/cameraRequestPayload.ts +29 -0
- package/src/_private/photoRequestPayload.ts +9 -2
- package/src/index.ts +76 -58
|
@@ -39,27 +39,6 @@ data class SpeakingStatusEvent(
|
|
|
39
39
|
val values: Map<String, Any>,
|
|
40
40
|
)
|
|
41
41
|
|
|
42
|
-
data class OtaUpdateAvailableEvent(
|
|
43
|
-
val versionCode: Long?,
|
|
44
|
-
val versionName: String?,
|
|
45
|
-
val updates: List<String>,
|
|
46
|
-
val totalSize: Long?,
|
|
47
|
-
val cacheReady: Boolean?,
|
|
48
|
-
val values: Map<String, Any>,
|
|
49
|
-
) {
|
|
50
|
-
companion object {
|
|
51
|
-
internal fun fromMap(values: Map<String, Any>): OtaUpdateAvailableEvent =
|
|
52
|
-
OtaUpdateAvailableEvent(
|
|
53
|
-
versionCode = longValue(values, "version_code"),
|
|
54
|
-
versionName = stringValue(values, "version_name"),
|
|
55
|
-
updates = (values["updates"] as? List<*>)?.filterIsInstance<String>() ?: emptyList(),
|
|
56
|
-
totalSize = longValue(values, "total_size"),
|
|
57
|
-
cacheReady = boolValue(values, "cache_ready"),
|
|
58
|
-
values = values,
|
|
59
|
-
)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
42
|
data class OtaStartAckEvent(
|
|
64
43
|
val timestamp: Long?,
|
|
65
44
|
val values: Map<String, Any>,
|
|
@@ -153,12 +132,12 @@ interface MentraBluetoothSdkListener {
|
|
|
153
132
|
fun onGalleryStatus(event: GalleryStatusEvent) {}
|
|
154
133
|
fun onPhotoResponse(event: PhotoResponseEvent) {}
|
|
155
134
|
fun onPhotoStatus(event: PhotoStatusEvent) {}
|
|
135
|
+
fun onCameraStatus(event: CameraStatusEvent) {}
|
|
156
136
|
fun onVideoRecordingStatus(event: VideoRecordingStatusEvent) {}
|
|
157
137
|
fun onMediaUpload(event: MediaUploadEvent) {}
|
|
158
138
|
fun onRgbLedControlResponse(event: RgbLedControlResponseEvent) {}
|
|
159
139
|
fun onStreamStatus(event: StreamStatusEvent) {}
|
|
160
140
|
fun onKeepAliveAck(event: KeepAliveAckEvent) {}
|
|
161
|
-
fun onOtaUpdateAvailable(event: OtaUpdateAvailableEvent) {}
|
|
162
141
|
fun onOtaStartAck(event: OtaStartAckEvent) {}
|
|
163
142
|
fun onOtaStatus(event: OtaStatusEvent) {}
|
|
164
143
|
fun onSettingsAck(event: SettingsAckEvent) {}
|
|
@@ -1614,25 +1614,72 @@ class G1 : SGCManager() {
|
|
|
1614
1614
|
|
|
1615
1615
|
override fun clearDisplay() {
|
|
1616
1616
|
Bridge.log("G1: clearDisplay() - sending space")
|
|
1617
|
-
|
|
1617
|
+
// Bypass the throttle (a clear must always land) and drop any pending caption so it can't
|
|
1618
|
+
// overwrite the clear after the fact.
|
|
1619
|
+
cancelPendingThrottledText()
|
|
1620
|
+
displayTextWall(" ")
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
// G1-specific display throttle (300ms, last-wins) — see G1.swift. G1 firmware can't absorb
|
|
1624
|
+
// rapid text-wall updates; coalesce to the latest within a 300ms window. Belongs in the G1 SGC
|
|
1625
|
+
// (G1 hardware quirk); G2 deliberately does NOT throttle (it must show every caption). The
|
|
1626
|
+
// trailing flush always sends the most recent text, so the final caption is never dropped —
|
|
1627
|
+
// only intermediate frames within a window are coalesced.
|
|
1628
|
+
private val textThrottleHandler = Handler(Looper.getMainLooper())
|
|
1629
|
+
private var textThrottlePending: String? = null
|
|
1630
|
+
private var textThrottleLastSent: Long = 0L
|
|
1631
|
+
private var textThrottleScheduled = false
|
|
1632
|
+
private val TEXT_THROTTLE_WINDOW_MS = 300L
|
|
1633
|
+
|
|
1634
|
+
/** Drop any pending throttled text-wall flush so it can't later overwrite a newer, non-text
|
|
1635
|
+
* display write (a clear, double-text-wall, or bitmap). The posted flush no-ops when
|
|
1636
|
+
* `textThrottlePending` is null. Called from every G1 display path that bypasses the throttle. */
|
|
1637
|
+
private fun cancelPendingThrottledText() {
|
|
1638
|
+
textThrottlePending = null
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
private fun throttledTextWall(text: String) {
|
|
1642
|
+
val now = android.os.SystemClock.uptimeMillis()
|
|
1643
|
+
val sinceLast = now - textThrottleLastSent
|
|
1644
|
+
if (sinceLast >= TEXT_THROTTLE_WINDOW_MS) {
|
|
1645
|
+
// Past the window — send now.
|
|
1646
|
+
textThrottleLastSent = now
|
|
1647
|
+
textThrottlePending = null
|
|
1648
|
+
displayTextWall(text)
|
|
1649
|
+
} else {
|
|
1650
|
+
// Inside the window — keep only the latest and schedule one trailing flush.
|
|
1651
|
+
textThrottlePending = text
|
|
1652
|
+
if (!textThrottleScheduled) {
|
|
1653
|
+
textThrottleScheduled = true
|
|
1654
|
+
textThrottleHandler.postDelayed({
|
|
1655
|
+
textThrottleScheduled = false
|
|
1656
|
+
val pending = textThrottlePending ?: return@postDelayed
|
|
1657
|
+
textThrottlePending = null
|
|
1658
|
+
textThrottleLastSent = android.os.SystemClock.uptimeMillis()
|
|
1659
|
+
displayTextWall(pending)
|
|
1660
|
+
}, TEXT_THROTTLE_WINDOW_MS - sinceLast)
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1618
1663
|
}
|
|
1619
1664
|
|
|
1620
1665
|
override fun sendText(text: String) {
|
|
1621
1666
|
Bridge.log("G1: sendText() - text: " + text)
|
|
1622
|
-
|
|
1667
|
+
throttledTextWall(text)
|
|
1623
1668
|
}
|
|
1624
1669
|
|
|
1625
1670
|
override fun sendTextWall(text: String) {
|
|
1626
1671
|
// Bridge.log("G1: sendTextWall() - text: " + text);
|
|
1627
|
-
|
|
1672
|
+
throttledTextWall(text)
|
|
1628
1673
|
}
|
|
1629
1674
|
|
|
1630
1675
|
override fun sendDoubleTextWall(top: String, bottom: String) {
|
|
1676
|
+
cancelPendingThrottledText() // a newer layout supersedes any pending caption text
|
|
1631
1677
|
Bridge.log("G1: sendDoubleTextWall() - top: " + top + ", bottom: " + bottom)
|
|
1632
1678
|
displayDoubleTextWall(top, bottom)
|
|
1633
1679
|
}
|
|
1634
1680
|
|
|
1635
1681
|
override fun displayBitmap(base64ImageData: String, x: Int?, y: Int?, width: Int?, height: Int?): Boolean {
|
|
1682
|
+
cancelPendingThrottledText() // a bitmap supersedes any pending caption text
|
|
1636
1683
|
try {
|
|
1637
1684
|
// Decode base64 to byte array
|
|
1638
1685
|
val bmpData = android.util.Base64.decode(base64ImageData, android.util.Base64.DEFAULT)
|