@glassly/bluetooth-sdk 0.1.0-dev.98 → 0.2.8-dev.444

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 (155) hide show
  1. package/README.md +47 -6
  2. package/android/build.gradle +7 -7
  3. package/android/lc3Lib/build.gradle +2 -2
  4. package/android/src/main/assets/G2Firmware/README.md +27 -2
  5. package/android/src/main/assets/G2Firmware/{g2-stock-2.2.9.22.evenota.bin → g2-glassly-cfw-2.3.0.24.evenota.bin} +0 -0
  6. package/android/src/main/assets/G2Firmware/{g2-glassly-cfw-2.2.9.22.evenota.bin → g2-stock-2.3.0.24.evenota.bin} +0 -0
  7. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdk.kt +38 -0
  8. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkModule.kt +50 -14
  9. package/android/src/main/java/com/glassly/bluetoothsdk/Bridge.kt +18 -0
  10. package/android/src/main/java/com/glassly/bluetoothsdk/DeviceManager.kt +139 -10
  11. package/android/src/main/java/com/glassly/bluetoothsdk/DeviceStore.kt +28 -1
  12. package/android/src/main/java/com/glassly/bluetoothsdk/DisplayPacer.kt +199 -0
  13. package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedChangelogCatalog.kt +10 -1
  14. package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedReleaseMetadata.kt +4 -4
  15. package/android/src/main/java/com/glassly/bluetoothsdk/GlassesNotifications.kt +155 -0
  16. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2.kt +1075 -257
  17. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2BleLink.kt +119 -0
  18. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwClassification.kt +29 -28
  19. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwRenderer.kt +138 -33
  20. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwScene.kt +673 -0
  21. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwTextureCache.kt +235 -162
  22. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwTransport.kt +402 -0
  23. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2DisplayDiagnostics.kt +84 -0
  24. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2FlashProtocol.kt +3 -3
  25. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2Flasher.kt +9 -9
  26. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2Keyboard.kt +689 -0
  27. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2KeyboardBridge.kt +452 -0
  28. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2KeyboardHid.kt +208 -0
  29. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2NotificationFile.kt +181 -0
  30. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2RingBattery.kt +20 -0
  31. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2Sensors.kt +67 -0
  32. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2TouchInput.kt +39 -0
  33. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLive.kt +5 -5
  34. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraNex.kt +14 -14
  35. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/{GlasslyBle.java → NexProto.java} +6462 -7618
  36. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/NotificationMessageIds.kt +58 -0
  37. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/SGCManager.kt +77 -2
  38. package/android/src/main/java/com/glassly/bluetoothsdk/speakerid/SpeakerIdEngine.kt +1 -1
  39. package/android/src/main/java/com/glassly/bluetoothsdk/status/DeviceStatus.kt +55 -0
  40. package/android/src/main/java/com/glassly/bluetoothsdk/stt/STTTools.kt +1 -1
  41. package/android/src/main/java/com/glassly/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +1 -1
  42. package/android/src/main/java/com/glassly/bluetoothsdk/tts/TTSTools.kt +1 -1
  43. package/android/src/main/java/com/glassly/bluetoothsdk/utils/NexSGCUtils.kt +24 -149
  44. package/android/src/test/java/com/glassly/bluetoothsdk/DisplayPacerTest.kt +277 -0
  45. package/android/src/test/java/com/glassly/bluetoothsdk/G2BleLinkTest.kt +70 -0
  46. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwClassificationTest.kt +45 -56
  47. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwRendererTest.kt +78 -5
  48. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwSceneTest.kt +489 -0
  49. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwTextureCacheTest.kt +100 -43
  50. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwTransportTest.kt +252 -0
  51. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2DisplayDiagnosticsTest.kt +64 -0
  52. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2KeyboardTest.kt +271 -0
  53. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2NotificationFileTest.kt +204 -0
  54. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2RingBatteryTest.kt +56 -0
  55. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2SensorsTest.kt +56 -0
  56. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2TouchInputTest.kt +60 -0
  57. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/NexProtoDescriptorTest.kt +32 -0
  58. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/NotificationMessageIdsTest.kt +58 -0
  59. package/build/BluetoothSdk.types.d.ts +209 -20
  60. package/build/BluetoothSdk.types.d.ts.map +1 -1
  61. package/build/BluetoothSdk.types.js.map +1 -1
  62. package/build/_internal.d.ts +1 -1
  63. package/build/_internal.d.ts.map +1 -1
  64. package/build/_internal.js.map +1 -1
  65. package/build/_private/BluetoothSdkModule.d.ts +30 -1
  66. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  67. package/build/_private/BluetoothSdkModule.js.map +1 -1
  68. package/build/generated/changelogCatalog.d.ts +28 -1
  69. package/build/generated/changelogCatalog.d.ts.map +1 -1
  70. package/build/generated/changelogCatalog.js +37 -1
  71. package/build/generated/changelogCatalog.js.map +1 -1
  72. package/build/generated/releaseMetadata.js +4 -4
  73. package/build/generated/releaseMetadata.js.map +1 -1
  74. package/build/index.d.ts +1 -1
  75. package/build/index.d.ts.map +1 -1
  76. package/build/index.js +14 -0
  77. package/build/index.js.map +1 -1
  78. package/ios/BluetoothSdkModule.swift +102 -13
  79. package/ios/GlasslyBluetoothSDK.podspec +1 -1
  80. package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +8 -3
  81. package/ios/Source/BluetoothSDK.swift +53 -0
  82. package/ios/Source/BluetoothSdkDefaults.swift +1 -1
  83. package/ios/Source/Bridge.swift +13 -0
  84. package/ios/Source/DeviceManager.swift +151 -33
  85. package/ios/Source/DeviceStore.swift +28 -14
  86. package/ios/Source/DisplayPacer.swift +180 -0
  87. package/ios/Source/GeneratedChangelogCatalog.swift +10 -1
  88. package/ios/Source/GeneratedReleaseMetadata.swift +4 -4
  89. package/ios/Source/GlassesNotifications.swift +181 -0
  90. package/ios/Source/ObservableStore.swift +14 -2
  91. package/ios/Source/Resources/G2Firmware/README.md +27 -2
  92. package/ios/Source/Resources/G2Firmware/{g2-stock-2.2.9.22.evenota.bin → g2-glassly-cfw-2.3.0.24.evenota.bin} +0 -0
  93. package/ios/Source/Resources/G2Firmware/{g2-glassly-cfw-2.2.9.22.evenota.bin → g2-stock-2.3.0.24.evenota.bin} +0 -0
  94. package/ios/Source/controllers/R1.swift +0 -1
  95. package/ios/Source/internal/BluetoothAvailability.swift +31 -0
  96. package/ios/Source/sgcs/G2.swift +1434 -504
  97. package/ios/Source/sgcs/G2AncsRelay.swift +268 -0
  98. package/ios/Source/sgcs/G2BleLink.swift +102 -0
  99. package/ios/Source/sgcs/G2CfwClassification.swift +45 -27
  100. package/ios/Source/sgcs/G2CfwRenderer.swift +166 -33
  101. package/ios/Source/sgcs/G2CfwScene.swift +779 -0
  102. package/ios/Source/sgcs/G2CfwTextureCache.swift +244 -117
  103. package/ios/Source/sgcs/G2CfwTransport.swift +485 -0
  104. package/ios/Source/sgcs/G2DisplayDiagnostics.swift +154 -0
  105. package/ios/Source/sgcs/G2FlashProtocol.swift +2 -2
  106. package/ios/Source/sgcs/G2Flasher.swift +9 -9
  107. package/ios/Source/sgcs/G2Keyboard.swift +780 -0
  108. package/ios/Source/sgcs/G2KeyboardBridge.swift +438 -0
  109. package/ios/Source/sgcs/G2KeyboardHid.swift +290 -0
  110. package/ios/Source/sgcs/G2NotificationTuning.swift +24 -0
  111. package/ios/Source/sgcs/G2RingBattery.swift +22 -0
  112. package/ios/Source/sgcs/G2Sensors.swift +75 -0
  113. package/ios/Source/sgcs/G2TouchInput.swift +51 -0
  114. package/ios/Source/sgcs/G2WritePacing.swift +18 -0
  115. package/ios/Source/sgcs/MentraNex.swift +44 -44
  116. package/ios/Source/sgcs/SGCManager.swift +120 -13
  117. package/ios/Source/sgcs/{glassly_ble.pb.swift → nex_ble.pb.swift} +405 -465
  118. package/ios/Source/speakerid/SpeakerIdEngine.swift +2 -2
  119. package/ios/Source/status/DeviceStatus.swift +27 -0
  120. package/ios/Source/stt/SherpaOnnxTranscriber.swift +15 -14
  121. package/ios/Source/utils/Enums.swift +0 -1
  122. package/ios/Source/utils/G1Text.swift +0 -1
  123. package/ios/Source/utils/G2NotifyFile.swift +20 -10
  124. package/ios/Source/utils/JSCExperiment.swift +6 -6
  125. package/ios/Source/utils/Models.swift +0 -1
  126. package/ios/Tests/BluetoothSDKTests/BluetoothAvailabilityTests.swift +29 -0
  127. package/ios/Tests/BluetoothSDKTests/DisplayPacerTests.swift +255 -0
  128. package/ios/Tests/BluetoothSDKTests/G2AncsRelayTests.swift +186 -0
  129. package/ios/Tests/BluetoothSDKTests/G2BleLinkTests.swift +52 -0
  130. package/ios/Tests/BluetoothSDKTests/G2CfwClassificationTests.swift +46 -51
  131. package/ios/Tests/BluetoothSDKTests/G2CfwRendererTests.swift +164 -5
  132. package/ios/Tests/BluetoothSDKTests/G2CfwSceneTests.swift +497 -0
  133. package/ios/Tests/BluetoothSDKTests/G2CfwTextureCacheTests.swift +108 -44
  134. package/ios/Tests/BluetoothSDKTests/G2CfwTransportTests.swift +259 -0
  135. package/ios/Tests/BluetoothSDKTests/G2DisplayDiagnosticsTests.swift +89 -0
  136. package/ios/Tests/BluetoothSDKTests/G2FlashProtocolTests.swift +3 -2
  137. package/ios/Tests/BluetoothSDKTests/G2ImageAckTests.swift +104 -0
  138. package/ios/Tests/BluetoothSDKTests/G2KeyboardTests.swift +274 -0
  139. package/ios/Tests/BluetoothSDKTests/G2NotifyFileTests.swift +21 -5
  140. package/ios/Tests/BluetoothSDKTests/G2RingBatteryTests.swift +56 -0
  141. package/ios/Tests/BluetoothSDKTests/G2SensorsTests.swift +56 -0
  142. package/ios/Tests/BluetoothSDKTests/G2TouchInputTests.swift +71 -0
  143. package/ios/Tests/BluetoothSDKTests/G2WritePacingTests.swift +35 -0
  144. package/ios/Tests/BluetoothSDKTests/GlassesNotificationTests.swift +95 -0
  145. package/package.json +1 -1
  146. package/plugin/build/withAndroid.js +2 -2
  147. package/plugin/build/withIos.js +1 -1
  148. package/scripts/gen-nex-proto.sh +12 -0
  149. package/scripts/inject-ios-sdk-version.mjs +1 -1
  150. package/src/BluetoothSdk.types.ts +214 -19
  151. package/src/_internal.ts +1 -1
  152. package/src/_private/BluetoothSdkModule.ts +40 -0
  153. package/src/generated/changelogCatalog.ts +37 -1
  154. package/src/generated/releaseMetadata.ts +4 -4
  155. package/src/index.ts +24 -0
@@ -20,10 +20,12 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
20
20
  "button_press",
21
21
  "touch_event",
22
22
  "accel_event",
23
+ "light_sensor",
23
24
  "compass_heading",
24
25
  "compass_calibration",
25
26
  "navigation_mode_change",
26
27
  "navigation_view_change",
28
+ "scene_frame_presented",
27
29
  "head_up",
28
30
  "voice_activity_detection_status",
29
31
  "speaking_status",
@@ -61,6 +63,9 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
61
63
  "speaker_enroll_result",
62
64
  "phone_notification",
63
65
  "phone_notification_dismissed",
66
+ "notification_app_seen",
67
+ "glasses_notification_status",
68
+ "notification_upload_result",
64
69
  "ws_text",
65
70
  "ws_bin",
66
71
  "mic_pcm",
@@ -79,7 +84,10 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
79
84
  "receive_command_from_ble",
80
85
  "miniapp_selected",
81
86
  "captions_tester_incident",
82
- "extraction_progress"
87
+ "extraction_progress",
88
+ "keyboard_key",
89
+ "keyboard_advert",
90
+ "keyboard_pairing"
83
91
  )
84
92
 
85
93
  OnCreate {
@@ -145,6 +153,10 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
145
153
 
146
154
  // MARK: - Native Navigation Commands (glasses-rendered nav UI)
147
155
 
156
+ AsyncFunction("glassesSensorControl") { (sensor: String, operation: String, options: [String: Double]) in
157
+ await self.bluetoothSdk().glassesSensorControl(sensor: sensor, operation: operation, options: options)
158
+ }
159
+
148
160
  AsyncFunction("navigationModeStart") {
149
161
  await MainActor.run {
150
162
  self.bluetoothSdk().navigationModeStart()
@@ -279,6 +291,29 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
279
291
  }
280
292
  }
281
293
 
294
+ AsyncFunction("setGlassesNotificationConfig") { (values: [String: Any]) in
295
+ let config = try GlassesNotificationConfig(dictionary: values)
296
+ try await MainActor.run {
297
+ try self.bluetoothSdk().setGlassesNotificationConfig(config)
298
+ }
299
+ }
300
+
301
+ AsyncFunction("getGlassesNotificationStatus") { () -> [String: Any] in
302
+ await MainActor.run {
303
+ self.bluetoothSdk().getGlassesNotificationStatus().dictionary
304
+ }
305
+ }
306
+
307
+ AsyncFunction("uploadPhoneNotification") { (values: [String: Any]) in
308
+ let upload = PhoneNotificationUpload(dictionary: values)
309
+ try await MainActor.run {
310
+ guard let sgc = DeviceManager.shared.sgc else {
311
+ throw GlassesNotificationError.notConnected
312
+ }
313
+ try sgc.uploadPhoneNotification(upload)
314
+ }
315
+ }
316
+
282
317
  AsyncFunction("ping") {
283
318
  await MainActor.run {
284
319
  DeviceManager.shared.ping()
@@ -299,6 +334,18 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
299
334
  }
300
335
  }
301
336
 
337
+ AsyncFunction("dbg3") {
338
+ await MainActor.run {
339
+ DeviceManager.shared.sgc?.dbg3()
340
+ }
341
+ }
342
+
343
+ AsyncFunction("dbg4") {
344
+ await MainActor.run {
345
+ DeviceManager.shared.sgc?.dbg4()
346
+ }
347
+ }
348
+
302
349
  Function("getMemoryMB") { () -> Double in
303
350
  MemoryMonitor.currentMemoryMB()
304
351
  }
@@ -583,6 +630,48 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
583
630
  return try await sdk.startG2FirmwareFlash(target: target)
584
631
  }
585
632
 
633
+ // MARK: - BLE keyboard bridge (G2 Glassly CFW revision 39+)
634
+
635
+ AsyncFunction("g2KeyboardScan") {
636
+ let sdk = await MainActor.run { self.bluetoothSdk() }
637
+ return try await sdk.g2KeyboardScan()
638
+ }
639
+
640
+ AsyncFunction("g2KeyboardConnect") { (address: String, addressType: Int, name: String) in
641
+ let sdk = await MainActor.run { self.bluetoothSdk() }
642
+ try await sdk.g2KeyboardConnect(address: address, addressType: addressType, name: name)
643
+ }
644
+
645
+ AsyncFunction("g2KeyboardReconnect") {
646
+ let sdk = await MainActor.run { self.bluetoothSdk() }
647
+ try await sdk.g2KeyboardReconnect()
648
+ }
649
+
650
+ AsyncFunction("g2KeyboardDisconnect") {
651
+ let sdk = await MainActor.run { self.bluetoothSdk() }
652
+ try await sdk.g2KeyboardDisconnect()
653
+ }
654
+
655
+ AsyncFunction("g2KeyboardForget") {
656
+ let sdk = await MainActor.run { self.bluetoothSdk() }
657
+ await sdk.g2KeyboardForget()
658
+ }
659
+
660
+ AsyncFunction("g2KeyboardPasskey") { (pin: Int) in
661
+ let sdk = await MainActor.run { self.bluetoothSdk() }
662
+ try await sdk.g2KeyboardPasskey(pin)
663
+ }
664
+
665
+ AsyncFunction("g2KeyboardCompare") { (accept: Bool) in
666
+ let sdk = await MainActor.run { self.bluetoothSdk() }
667
+ try await sdk.g2KeyboardCompare(accept)
668
+ }
669
+
670
+ AsyncFunction("g2KeyboardStatus") {
671
+ let sdk = await MainActor.run { self.bluetoothSdk() }
672
+ return await sdk.g2KeyboardStatus()
673
+ }
674
+
586
675
  // MARK: - Power Control Commands
587
676
 
588
677
  AsyncFunction("sendShutdown") {
@@ -737,8 +826,8 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
737
826
  }
738
827
 
739
828
  AsyncFunction("restartTranscriber") {
740
- await MainActor.run {
741
- DeviceManager.shared.restartTranscriber()
829
+ try await MainActor.run {
830
+ try DeviceManager.shared.restartTranscriber()
742
831
  }
743
832
  }
744
833
 
@@ -757,7 +846,7 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
757
846
  }
758
847
 
759
848
  AsyncFunction("checkSpeakerIdModelAvailable") { () -> Bool in
760
- return SpeakerIdEngine.isModelAvailable()
849
+ SpeakerIdEngine.isModelAvailable()
761
850
  }
762
851
 
763
852
  AsyncFunction("setSpeakerProfiles") { (profiles: [[String: Any]]) in
@@ -793,19 +882,19 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
793
882
  }
794
883
 
795
884
  AsyncFunction("getSttModelPath") { () -> String in
796
- return STTTools.getSttModelPath()
885
+ STTTools.getSttModelPath()
797
886
  }
798
887
 
799
888
  AsyncFunction("checkSttModelAvailable") { () -> Bool in
800
- return STTTools.checkSTTModelAvailable()
889
+ STTTools.checkSTTModelAvailable()
801
890
  }
802
891
 
803
892
  AsyncFunction("validateSttModel") { (path: String) -> Bool in
804
- return STTTools.validateSTTModel(path)
893
+ STTTools.validateSTTModel(path)
805
894
  }
806
895
 
807
896
  AsyncFunction("extractTarBz2") { (sourcePath: String, destinationPath: String) -> Bool in
808
- return STTTools.extractTarBz2(sourcePath: sourcePath, destinationPath: destinationPath)
897
+ STTTools.extractTarBz2(sourcePath: sourcePath, destinationPath: destinationPath)
809
898
  }
810
899
 
811
900
  // MARK: - TTS Model Management
@@ -815,24 +904,24 @@ public class BluetoothSdkModule: Module, BluetoothSDKDelegate {
815
904
  }
816
905
 
817
906
  AsyncFunction("getTtsModelPath") { () -> String in
818
- return TTSTools.getTtsModelPath()
907
+ TTSTools.getTtsModelPath()
819
908
  }
820
909
 
821
910
  AsyncFunction("getTtsModelLanguage") { () -> String in
822
- return TTSTools.getTtsModelLanguage()
911
+ TTSTools.getTtsModelLanguage()
823
912
  }
824
913
 
825
914
  AsyncFunction("checkTtsModelAvailable") { () -> Bool in
826
- return TTSTools.checkTTSModelAvailable()
915
+ TTSTools.checkTTSModelAvailable()
827
916
  }
828
917
 
829
918
  AsyncFunction("validateTtsModel") { (path: String) -> Bool in
830
- return TTSTools.validateTTSModel(path)
919
+ TTSTools.validateTTSModel(path)
831
920
  }
832
921
 
833
922
  AsyncFunction("generateTtsAudio") {
834
923
  (text: String, modelPath: String, outputPath: String, speakerId: Int, speed: Double) -> Bool in
835
- return TTSTools.generateTtsAudio(
924
+ TTSTools.generateTtsAudio(
836
925
  text: text,
837
926
  modelPath: modelPath,
838
927
  outputPath: outputPath,
@@ -1,7 +1,7 @@
1
1
  require 'json'
2
2
 
3
3
  package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
4
- include_expo_adapter = ENV['GLASSLY_BLUETOOTH_SDK_INCLUDE_EXPO_ADAPTER'] == '1'
4
+ include_expo_adapter = ENV['BLUETOOTH_SDK_INCLUDE_EXPO_ADAPTER'] == '1'
5
5
 
6
6
  Pod::Spec.new do |s|
7
7
  s.name = 'GlasslyBluetoothSDK'
@@ -348,11 +348,16 @@ class SherpaOnnxRecognizer {
348
348
  private let lock = NSLock() // for thread-safe stream replacement
349
349
 
350
350
  /// Constructor taking a model config
351
- init(
351
+ init?(
352
352
  config: UnsafePointer<SherpaOnnxOnlineRecognizerConfig>
353
353
  ) {
354
- recognizer = SherpaOnnxCreateOnlineRecognizer(config)
355
- stream = SherpaOnnxCreateOnlineStream(recognizer)
354
+ guard let recognizer = SherpaOnnxCreateOnlineRecognizer(config) else { return nil }
355
+ guard let stream = SherpaOnnxCreateOnlineStream(recognizer) else {
356
+ SherpaOnnxDestroyOnlineRecognizer(recognizer)
357
+ return nil
358
+ }
359
+ self.recognizer = recognizer
360
+ self.stream = stream
356
361
  }
357
362
 
358
363
  deinit {
@@ -470,6 +470,10 @@ public final class BluetoothSDK {
470
470
 
471
471
  // MARK: - Native navigation (glasses-rendered nav UI)
472
472
 
473
+ func glassesSensorControl(sensor: String, operation: String, options: [String: Double]) async -> Bool {
474
+ await DeviceManager.shared.glassesSensorControl(sensor: sensor, operation: operation, options: options)
475
+ }
476
+
473
477
  func navigationModeStart() {
474
478
  DeviceManager.shared.navigationModeStart()
475
479
  }
@@ -491,6 +495,7 @@ public final class BluetoothSDK {
491
495
  }
492
496
 
493
497
  public func clearDisplay() async throws {
498
+ DeviceManager.shared.cancelPendingDisplay()
494
499
  DeviceManager.shared.sgc?.clearDisplay()
495
500
  }
496
501
 
@@ -502,6 +507,17 @@ public final class BluetoothSDK {
502
507
  DeviceManager.shared.showNotificationsPanel()
503
508
  }
504
509
 
510
+ public func setGlassesNotificationConfig(_ config: GlassesNotificationConfig) throws {
511
+ guard let sgc = DeviceManager.shared.sgc else {
512
+ throw GlassesNotificationError.notConnected
513
+ }
514
+ try sgc.setGlassesNotificationConfig(config)
515
+ }
516
+
517
+ public func getGlassesNotificationStatus() -> GlassesNotificationStatus {
518
+ DeviceManager.shared.sgc?.glassesNotificationStatus() ?? .unsupported
519
+ }
520
+
505
521
  func setBrightness(_ level: Int, autoMode: Bool? = nil) async throws {
506
522
  if let autoMode {
507
523
  DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "auto_brightness", autoMode)
@@ -1256,6 +1272,43 @@ public final class BluetoothSDK {
1256
1272
  return try await DeviceManager.shared.startG2FirmwareFlash(target: target)
1257
1273
  }
1258
1274
 
1275
+ // MARK: - BLE keyboard bridge (G2 Glassly CFW revision 39+)
1276
+
1277
+ public func g2KeyboardScan() async throws -> [[String: Any]] {
1278
+ try requireGlassesConnected(operation: "scan for a keyboard")
1279
+ return try await DeviceManager.shared.g2KeyboardScan()
1280
+ }
1281
+
1282
+ public func g2KeyboardConnect(address: String, addressType: Int, name: String) async throws {
1283
+ try requireGlassesConnected(operation: "connect a keyboard")
1284
+ try await DeviceManager.shared.g2KeyboardConnect(address: address, addressType: addressType, name: name)
1285
+ }
1286
+
1287
+ public func g2KeyboardReconnect() async throws {
1288
+ try requireGlassesConnected(operation: "reconnect the keyboard")
1289
+ try await DeviceManager.shared.g2KeyboardReconnect()
1290
+ }
1291
+
1292
+ public func g2KeyboardDisconnect() async throws {
1293
+ try await DeviceManager.shared.g2KeyboardDisconnect()
1294
+ }
1295
+
1296
+ public func g2KeyboardForget() async {
1297
+ await DeviceManager.shared.g2KeyboardForget()
1298
+ }
1299
+
1300
+ public func g2KeyboardPasskey(_ pin: Int) async throws {
1301
+ try await DeviceManager.shared.g2KeyboardPasskey(pin)
1302
+ }
1303
+
1304
+ public func g2KeyboardCompare(_ accept: Bool) async throws {
1305
+ try await DeviceManager.shared.g2KeyboardCompare(accept)
1306
+ }
1307
+
1308
+ public func g2KeyboardStatus() async -> [String: Any] {
1309
+ await DeviceManager.shared.g2KeyboardStatus()
1310
+ }
1311
+
1259
1312
  /// Select the HTTP(S) manifest used by subsequent OTA checks and installs.
1260
1313
  public func setOtaVersionUrl(_ otaVersionUrl: String) throws {
1261
1314
  configuredOtaVersionUrl = try OtaManifestChecker.normalizeHttpUrl(otaVersionUrl)
@@ -11,7 +11,7 @@ enum BluetoothSdkDefaults {
11
11
  static let voiceActivityDetectionEnabled = false
12
12
  static let loudnessGateEnabled = true
13
13
  private static let infoSdkVersionKey = "BluetoothSdkVersion"
14
- private static let swiftPackageSdkVersion = "0.1.0-dev.98"
14
+ private static let swiftPackageSdkVersion = "0.2.8-dev.444"
15
15
  private static let swiftPackageSdkVersionPlaceholder = "__GLASSLY" + "_BLUETOOTH_SDK_VERSION__"
16
16
 
17
17
  private static func normalizedSdkVersion(_ value: String?) -> String? {
@@ -88,6 +88,19 @@ class Bridge {
88
88
  Bridge.sendTypedMessage("extraction_progress", body: body)
89
89
  }
90
90
 
91
+ /// display.render() frame outcome; seq 0 frames are native-originated and never reported.
92
+ static func sendSceneFramePresented(seq: Int, appId: String, presented: Bool, reason: String?) {
93
+ guard seq > 0 else { return }
94
+ var body: [String: Any] = ["seq": seq, "appId": appId, "presented": presented]
95
+ if let reason { body["reason"] = reason }
96
+ sendTypedMessage("scene_frame_presented", body: body)
97
+ }
98
+
99
+ /// The glasses finished every animation a tagged scene commit started (tag = frame seq & 0xFFFF).
100
+ static func sendSceneSettled(tag: Int) {
101
+ sendTypedMessage("scene_settled", body: ["tag": tag])
102
+ }
103
+
91
104
  static func sendHeadUp(_ isUp: Bool) {
92
105
  let data = ["up": isUp]
93
106
  Bridge.sendTypedMessage("head_up", body: data)