@mentra/bluetooth-sdk 3.2.1-beta.319 → 3.2.1-beta.355

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.
Files changed (83) hide show
  1. package/README.md +1 -1
  2. package/android/src/debug/java/com/mentra/bluetoothsdk/sgcs/NimoDiagnostics.kt +368 -0
  3. package/android/src/debug/java/com/mentra/bluetoothsdk/sgcs/NimoFramebufferProtocol.kt +156 -0
  4. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkDefaults.kt +3 -0
  5. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +4 -0
  6. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +2 -1
  7. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +67 -12
  8. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +37 -13
  9. package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedChangelogCatalog.kt +1 -1
  10. package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedReleaseMetadata.kt +5 -5
  11. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +4 -0
  12. package/android/src/main/java/com/mentra/bluetoothsdk/VersionInfoResponseAccumulator.kt +13 -2
  13. package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +33 -0
  14. package/android/src/main/java/com/mentra/bluetoothsdk/services/G2ConnectionRecovery.kt +47 -0
  15. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +64 -14
  16. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +73 -3
  17. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Nimo.kt +257 -395
  18. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCodec.kt +245 -0
  19. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCoordinator.kt +225 -0
  20. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasEncoder.kt +58 -0
  21. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasSession.kt +168 -0
  22. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +11 -0
  23. package/android/src/main/java/com/mentra/bluetoothsdk/utils/G2Text.kt +7 -0
  24. package/android/src/release/java/com/mentra/bluetoothsdk/sgcs/NimoDiagnostics.kt +20 -0
  25. package/android/src/test/java/com/mentra/bluetoothsdk/DeviceManagerSceneHandoffTest.kt +557 -0
  26. package/android/src/test/java/com/mentra/bluetoothsdk/G2TextTest.kt +13 -0
  27. package/android/src/test/java/com/mentra/bluetoothsdk/VersionInfoResponseAccumulatorTest.kt +71 -0
  28. package/android/src/test/java/com/mentra/bluetoothsdk/services/G2ConnectionRecoveryTest.kt +51 -0
  29. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/G2DisplayThreadTest.kt +120 -0
  30. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoBitmapAcceptanceTest.kt +105 -0
  31. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCodecTest.kt +220 -0
  32. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCoordinatorTest.kt +308 -0
  33. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasSessionTest.kt +270 -0
  34. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoDiagnosticsTest.kt +287 -0
  35. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoFramebufferProtocolTest.kt +127 -0
  36. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoLifecycleTest.kt +194 -0
  37. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoReadinessDriverTest.kt +199 -0
  38. package/build/BluetoothSdk.types.d.ts +11 -0
  39. package/build/BluetoothSdk.types.d.ts.map +1 -1
  40. package/build/BluetoothSdk.types.js.map +1 -1
  41. package/build/_private/BluetoothSdkModule.d.ts +2 -0
  42. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  43. package/build/_private/BluetoothSdkModule.js +3 -0
  44. package/build/_private/BluetoothSdkModule.js.map +1 -1
  45. package/build/generated/changelogCatalog.d.ts +1 -1
  46. package/build/generated/changelogCatalog.js +1 -1
  47. package/build/generated/changelogCatalog.js.map +1 -1
  48. package/build/generated/releaseMetadata.js +5 -5
  49. package/build/generated/releaseMetadata.js.map +1 -1
  50. package/build/index.d.ts.map +1 -1
  51. package/build/index.js +1 -0
  52. package/build/index.js.map +1 -1
  53. package/ios/BluetoothSdkModule.swift +5 -0
  54. package/ios/MentraBluetoothSDK.podspec +3 -2
  55. package/ios/Source/BluetoothSdkDefaults.swift +6 -1
  56. package/ios/Source/Bridge.swift +15 -2
  57. package/ios/Source/DeviceManager.swift +23 -10
  58. package/ios/Source/DeviceStore.swift +26 -7
  59. package/ios/Source/GeneratedChangelogCatalog.swift +1 -1
  60. package/ios/Source/GeneratedReleaseMetadata.swift +5 -5
  61. package/ios/Source/MentraBluetoothSDK.swift +4 -0
  62. package/ios/Source/requests/VersionInfoResponseAccumulator.swift +11 -1
  63. package/ios/Source/sgcs/G2.swift +2 -2
  64. package/ios/Source/sgcs/MentraLive.swift +66 -3
  65. package/ios/Source/sgcs/Nimo.swift +182 -371
  66. package/ios/Source/sgcs/NimoCanvasCodec.swift +269 -0
  67. package/ios/Source/sgcs/NimoCanvasCoordinator.swift +219 -0
  68. package/ios/Source/sgcs/NimoCanvasImage.swift +53 -0
  69. package/ios/Source/sgcs/NimoCanvasSession.swift +150 -0
  70. package/ios/Source/sgcs/SGCManager.swift +24 -0
  71. package/ios/Source/utils/G2Text.swift +11 -0
  72. package/ios/Tests/DashboardRenderingTests.swift +31 -0
  73. package/ios/Tests/G2TextTests.swift +10 -0
  74. package/ios/Tests/NimoCanvasCodecTests.swift +204 -0
  75. package/ios/Tests/NimoCanvasSessionTests.swift +112 -0
  76. package/ios/Tests/NimoCanvasTransportTests.swift +161 -0
  77. package/ios/Tests/VersionInfoResponseAccumulatorTests.swift +65 -0
  78. package/package.json +2 -2
  79. package/src/BluetoothSdk.types.ts +11 -0
  80. package/src/_private/BluetoothSdkModule.ts +6 -0
  81. package/src/generated/changelogCatalog.ts +1 -1
  82. package/src/generated/releaseMetadata.ts +5 -5
  83. package/src/index.ts +1 -0
@@ -141,6 +141,7 @@ class MentraLive : SGCManager() {
141
141
  private const val LC3_FRAME_SIZE = 40
142
142
  private const val VOICE_ACTIVITY_DETECTION_SWITCH_TYPE = 8
143
143
  private const val LOUDNESS_GATE_SWITCH_TYPE = 10
144
+ private const val AUTO_POWER_OFF_SWITCH_TYPE = 11
144
145
  // Mic tuning field names, matching the BES cs_mictun body.
145
146
  private val MIC_TUNING_FIELDS =
146
147
  listOf("gain", "open", "close", "attack", "hang", "sp_open", "sp_close", "sp_hold")
@@ -5548,7 +5549,9 @@ class MentraLive : SGCManager() {
5548
5549
  if (bodyObj != null) {
5549
5550
  val type = bodyObj.optInt("type", -1)
5550
5551
  val value = bodyObj.optInt("switch", -1)
5551
- handleSwitchStatus(type, value, System.currentTimeMillis())
5552
+ // K900 replies carry result in "S"; 0 is RC_SUCCESS.
5553
+ val resultCode = json.optInt("S", -1)
5554
+ handleSwitchStatus(type, value, System.currentTimeMillis(), resultCode)
5552
5555
  }
5553
5556
  } catch (e: Exception) {
5554
5557
  Log.e(TAG, "Error parsing sr_swit response", e)
@@ -5578,7 +5581,13 @@ class MentraLive : SGCManager() {
5578
5581
  try {
5579
5582
  val bodyObj = optK900Body(json)
5580
5583
  if (bodyObj != null) {
5581
- Bridge.sendWearState(bodyObj.optInt("on", 0) != 0)
5584
+ val extras = HashMap<String, Any>()
5585
+ if (bodyObj.has("elapsed_ms")) extras["elapsedMs"] = bodyObj.optInt("elapsed_ms")
5586
+ if (bodyObj.has("timeout_ms")) extras["timeoutMs"] = bodyObj.optInt("timeout_ms")
5587
+ if (bodyObj.has("enabled")) extras["enabled"] = bodyObj.optInt("enabled") != 0
5588
+ if (bodyObj.has("armed")) extras["armed"] = bodyObj.optInt("armed") != 0
5589
+ if (bodyObj.has("inhibited")) extras["inhibited"] = bodyObj.optInt("inhibited") != 0
5590
+ Bridge.sendWearState(bodyObj.optInt("on", 0) != 0, extras)
5582
5591
  }
5583
5592
  } catch (e: Exception) {
5584
5593
  Log.e(TAG, "Error parsing sr_wrst response", e)
@@ -5933,8 +5942,20 @@ class MentraLive : SGCManager() {
5933
5942
  Bridge.sendWearTuningState(state)
5934
5943
  }
5935
5944
 
5936
- private fun handleSwitchStatus(switchType: Int, switchValue: Int, timestamp: Long) {
5945
+ private fun handleSwitchStatus(
5946
+ switchType: Int,
5947
+ switchValue: Int,
5948
+ timestamp: Long,
5949
+ resultCode: Int = -1
5950
+ ) {
5937
5951
  Bridge.sendSwitchStatus(switchType, switchValue, timestamp)
5952
+ if (switchType == AUTO_POWER_OFF_SWITCH_TYPE) {
5953
+ val ok = resultCode == 0
5954
+ Bridge.log(
5955
+ "LIVE: 🔋 auto power-off sr_swit reply type=$switchType switch=$switchValue" +
5956
+ " result=$resultCode ok=$ok"
5957
+ )
5958
+ }
5938
5959
  if (switchType == VOICE_ACTIVITY_DETECTION_SWITCH_TYPE &&
5939
5960
  (switchValue == 0 || switchValue == 1)
5940
5961
  ) {
@@ -10825,6 +10846,9 @@ class MentraLive : SGCManager() {
10825
10846
  // Send glasses-side loudness / Barrier gate setting.
10826
10847
  sendLoudnessGateSetting()
10827
10848
 
10849
+ // Send glasses-side auto power-off setting.
10850
+ sendAutoPowerOffSetting()
10851
+
10828
10852
  // Send mic tuning. With nothing authorized this sends a reset, which is
10829
10853
  // what returns a freshly connected pair of glasses to stock behaviour.
10830
10854
  sendMicTuningSetting()
@@ -11108,6 +11132,52 @@ class MentraLive : SGCManager() {
11108
11132
  }
11109
11133
  }
11110
11134
 
11135
+ override fun sendAutoPowerOffSetting() {
11136
+ val value = DeviceStore.get("bluetooth", "auto_power_off_enabled")
11137
+ val enabled =
11138
+ if (value is Boolean) value
11139
+ else BluetoothSdkDefaults.AUTO_POWER_OFF_ENABLED
11140
+
11141
+ Bridge.log(
11142
+ "LIVE: 🔋 Sending auto power-off setting to glasses: enabled=$enabled" +
11143
+ " (cs_swit type=$AUTO_POWER_OFF_SWITCH_TYPE)"
11144
+ )
11145
+
11146
+ if (!isConnected) {
11147
+ Bridge.log("LIVE: Cannot send auto power-off setting - not connected")
11148
+ return
11149
+ }
11150
+
11151
+ try {
11152
+ val body = JSONObject()
11153
+ body.put("type", AUTO_POWER_OFF_SWITCH_TYPE)
11154
+ body.put("switch", if (enabled) 1 else 0)
11155
+
11156
+ val cmdObject = JSONObject()
11157
+ cmdObject.put("C", "cs_swit")
11158
+ cmdObject.put("V", 1)
11159
+ cmdObject.put("B", body.toString())
11160
+
11161
+ val packedData =
11162
+ K900ProtocolUtils.packDataToK900(
11163
+ cmdObject.toString().toByteArray(StandardCharsets.UTF_8),
11164
+ K900ProtocolUtils.CMD_TYPE_STRING,
11165
+ k900LengthEndian()
11166
+ )
11167
+ if (packedData == null) {
11168
+ Bridge.log("LIVE: Failed to pack auto power-off setting command")
11169
+ return
11170
+ }
11171
+ queueData(packedData)
11172
+ Bridge.log(
11173
+ "LIVE: 🔋 Queued auto power-off cs_swit type=$AUTO_POWER_OFF_SWITCH_TYPE" +
11174
+ " switch=${if (enabled) 1 else 0}"
11175
+ )
11176
+ } catch (e: JSONException) {
11177
+ Log.e(TAG, "Error creating auto power-off setting command", e)
11178
+ }
11179
+ }
11180
+
11111
11181
  /** Send button photo settings to glasses, replaying all stored scan-tuning fields. */
11112
11182
  override fun sendButtonPhotoSettings() {
11113
11183
  val legacyZslMfnr =