@mentra/bluetooth-sdk 0.1.9 → 0.1.11
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 +116 -18
- package/android/build.gradle +289 -16
- package/android/gradle.properties.example +9 -0
- package/android/lc3Lib/build.gradle +95 -6
- package/android/settings.gradle +3 -0
- package/android/silero/LICENSE.md +17 -0
- package/android/silero/build.gradle +42 -0
- package/android/silero/proguard-rules.pro +24 -0
- package/android/silero/src/androidTest/assets/hello.wav +0 -0
- package/android/silero/src/androidTest/java/com/konovalov/vad/silero/VadSileroTest.kt +79 -0
- package/android/silero/src/main/assets/LICENSE +21 -0
- package/android/silero/src/main/assets/silero_vad.onnx +0 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/Vad.kt +160 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/VadSilero.kt +449 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/config/FrameSize.kt +15 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/config/Mode.kt +14 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/config/SampleRate.kt +12 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/utils/AudioUtils.kt +47 -0
- package/android/silero/src/main/java/com/konovalov/vad/silero/utils/TensorMap.kt +41 -0
- package/android/silero/src/test/java/com/konovalov/vad/silero/utils/AudioUtilsTest.kt +44 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkDefaults.kt +6 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +195 -34
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +103 -21
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +210 -18
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +30 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +787 -85
- package/android/src/main/java/com/mentra/bluetoothsdk/audio/AudioModels.kt +6 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +125 -11
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +12 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +8 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/debug/BleTraceLogger.kt +33 -17
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +101 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/internal/MapParsing.kt +8 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistry.java +108 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoUploadServer.kt +399 -74
- package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/MentraPhotoReceiverModule.kt +100 -17
- package/android/src/main/java/com/mentra/bluetoothsdk/requests/DisplayRequests.kt +17 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +1293 -758
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +271 -66
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +197 -149
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +12753 -27036
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +64 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +16 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +60 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +12 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +87 -36
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +13 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +229 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/tts/TTSTools.kt +180 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AvifExifStripper.java +573 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +488 -50
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/HeifExifTagReader.java +199 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunkReassembler.java +18 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +64 -18
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +48 -39
- package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +23 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistryTest.java +75 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/utils/AvifExifStripperTest.java +30 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadServiceTest.java +98 -0
- package/android/src/test/resources/avif_with_exif.avif +0 -0
- package/build/BluetoothSdk.types.d.ts +253 -44
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js +11 -10
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +37 -23
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +43 -52
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/_private/photoRequestPayload.d.ts +4 -0
- package/build/_private/photoRequestPayload.d.ts.map +1 -0
- package/build/_private/photoRequestPayload.js +25 -0
- package/build/_private/photoRequestPayload.js.map +1 -0
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +25 -0
- package/build/index.js.map +1 -1
- package/build/react/useMentraBluetooth.d.ts +2 -2
- package/build/react/useMentraBluetooth.d.ts.map +1 -1
- package/build/react/useMentraBluetooth.js +3 -3
- package/build/react/useMentraBluetooth.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +177 -70
- package/ios/LocalPhotoUploadServer.swift +370 -105
- package/ios/MentraBluetoothSDK.podspec +3 -1
- package/ios/MentraPhotoReceiverModule.swift +62 -10
- package/ios/Packages/CoreObjC/include/PcmConverter.h +22 -0
- package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +668 -26
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +13 -9
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/c-api.h +4551 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/cxx-api.h +1745 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/c-api.h +4551 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/cxx-api.h +1745 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
- package/ios/Source/BluetoothSdkDefaults.swift +6 -0
- package/ios/Source/Bridge.swift +68 -19
- package/ios/Source/DeviceManager.swift +167 -32
- package/ios/Source/DeviceStore.swift +24 -8
- package/ios/Source/MentraBluetoothSDK.swift +803 -47
- package/ios/Source/ObservableStore.swift +6 -0
- package/ios/Source/{Audio → audio}/AudioModels.swift +9 -7
- package/ios/Source/{Camera → camera}/CameraModels.swift +226 -16
- package/ios/Source/controllers/ControllerManager.swift +4 -3
- package/ios/Source/controllers/R1.swift +3 -3
- package/ios/Source/{Events → events}/BluetoothEvents.swift +183 -1
- package/ios/Source/{Internal → internal}/ValueParsing.swift +10 -1
- package/ios/Source/{Requests → requests}/DisplayRequests.swift +28 -4
- package/ios/Source/services/PhoneMic.swift +1 -0
- package/ios/Source/sgcs/G1.swift +5 -5
- package/ios/Source/sgcs/G2.swift +1494 -870
- package/ios/Source/sgcs/Mach1.swift +4 -4
- package/ios/Source/sgcs/MentraLive.swift +814 -321
- package/ios/Source/sgcs/MentraNex.swift +604 -244
- package/ios/Source/sgcs/SGCManager.swift +68 -5
- package/ios/Source/sgcs/Simulated.swift +9 -5
- package/ios/Source/sgcs/mentraos_ble.pb.swift +3073 -3134
- package/ios/Source/status/DeviceStatus.swift +974 -0
- package/ios/Source/{Status → status}/WifiHotspotStatus.swift +4 -4
- package/ios/Source/{Streaming → streaming}/StreamModels.swift +24 -9
- package/ios/Source/stt/STTTools.swift +27 -12
- package/ios/Source/stt/SherpaOnnxTranscriber.swift +31 -8
- package/ios/Source/tts/TTSTools.swift +164 -0
- package/ios/Source/utils/JSCExperiment.swift +7 -7
- package/ios/Source/utils/MessageChunkReassembler.swift +20 -1
- package/ios/Source/utils/MessageChunker.swift +78 -21
- package/ios/Source/utils/TarBz2Extractor.swift +53 -2
- package/package.json +1 -1
- package/plugin/build/withAndroid.js +68 -4
- package/src/BluetoothSdk.types.ts +344 -60
- package/src/_private/BluetoothSdkModule.ts +132 -102
- package/src/_private/photoRequestPayload.ts +28 -0
- package/src/index.ts +61 -15
- package/src/react/useMentraBluetooth.ts +6 -4
- package/android/.project +0 -28
- package/android/lc3Lib/.project +0 -28
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +0 -162
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +0 -1852
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +0 -674
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
- package/ios/Source/Status/DeviceStatus.swift +0 -471
- /package/ios/Source/{Connection → connection}/ScanSession.swift +0 -0
- /package/ios/Source/{Errors → errors}/BluetoothError.swift +0 -0
- /package/ios/Source/{Internal → internal}/BluetoothAvailability.swift +0 -0
- /package/ios/Source/{Status → status}/RuntimeState.swift +0 -0
- /package/ios/Source/{Types → types}/DeviceModels.swift +0 -0
|
@@ -18,15 +18,20 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
18
18
|
"glasses_not_ready",
|
|
19
19
|
"button_press",
|
|
20
20
|
"touch_event",
|
|
21
|
+
"accel_event",
|
|
22
|
+
"CompassHeadingEvent",
|
|
23
|
+
"CompassCalibrationEvent",
|
|
21
24
|
"head_up",
|
|
22
25
|
"voice_activity_detection_status",
|
|
23
26
|
"speaking_status",
|
|
24
27
|
"battery_status",
|
|
25
28
|
"wifi_status_change",
|
|
29
|
+
"wifi_scan_result",
|
|
26
30
|
"hotspot_status_change",
|
|
27
31
|
"hotspot_error",
|
|
28
32
|
"photo_response",
|
|
29
33
|
"photo_status",
|
|
34
|
+
"video_recording_status",
|
|
30
35
|
"gallery_status",
|
|
31
36
|
"compatible_glasses_search_stop",
|
|
32
37
|
"heartbeat_sent",
|
|
@@ -34,6 +39,8 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
34
39
|
"swipe_volume_status",
|
|
35
40
|
"switch_status",
|
|
36
41
|
"rgb_led_control_response",
|
|
42
|
+
"settings_ack",
|
|
43
|
+
"version_info",
|
|
37
44
|
"pair_failure",
|
|
38
45
|
"audio_pairing_needed",
|
|
39
46
|
"audio_connected",
|
|
@@ -56,7 +63,8 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
56
63
|
"send_command_to_ble",
|
|
57
64
|
"receive_command_from_ble",
|
|
58
65
|
"miniapp_selected",
|
|
59
|
-
"captions_tester_incident"
|
|
66
|
+
"captions_tester_incident",
|
|
67
|
+
"extraction_progress"
|
|
60
68
|
)
|
|
61
69
|
|
|
62
70
|
OnCreate {
|
|
@@ -241,7 +249,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
241
249
|
JSCExperiment.spawn(count: count)
|
|
242
250
|
}
|
|
243
251
|
|
|
244
|
-
Function("jscKillAll") { ()
|
|
252
|
+
Function("jscKillAll") { () in
|
|
245
253
|
JSCExperiment.killAll()
|
|
246
254
|
}
|
|
247
255
|
|
|
@@ -253,7 +261,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
253
261
|
JSCExperiment.spawnAndMeasure(count: count, baselineMB: baselineMB)
|
|
254
262
|
}
|
|
255
263
|
|
|
256
|
-
Function("jscRunBenchmark") { ()
|
|
264
|
+
Function("jscRunBenchmark") { () in
|
|
257
265
|
JSCExperiment.runBenchmark()
|
|
258
266
|
}
|
|
259
267
|
|
|
@@ -268,26 +276,39 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
268
276
|
// MARK: - WiFi Commands
|
|
269
277
|
|
|
270
278
|
AsyncFunction("requestWifiScan") {
|
|
271
|
-
await MainActor.run {
|
|
272
|
-
|
|
273
|
-
}
|
|
279
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
280
|
+
return try await sdk.requestWifiScan().map(\.dictionary)
|
|
274
281
|
}
|
|
275
282
|
|
|
276
283
|
AsyncFunction("sendWifiCredentials") { (ssid: String, password: String) in
|
|
277
|
-
await MainActor.run {
|
|
278
|
-
|
|
279
|
-
}
|
|
284
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
285
|
+
return try await sdk.sendWifiCredentials(ssid: ssid, password: password).values
|
|
280
286
|
}
|
|
281
287
|
|
|
282
288
|
AsyncFunction("forgetWifiNetwork") { (ssid: String) in
|
|
283
|
-
await MainActor.run {
|
|
284
|
-
|
|
285
|
-
}
|
|
289
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
290
|
+
return try await sdk.forgetWifiNetwork(ssid: ssid).values
|
|
286
291
|
}
|
|
287
292
|
|
|
288
293
|
AsyncFunction("setHotspotState") { (enabled: Bool) in
|
|
294
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
295
|
+
return try await sdk.setHotspotState(enabled: enabled).values
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
AsyncFunction("setSystemTime") { (timestampMs: Double) in
|
|
299
|
+
let maxTimestamp = Double(Int64.max).nextDown
|
|
300
|
+
guard timestampMs.isFinite,
|
|
301
|
+
timestampMs >= Double(Int64.min),
|
|
302
|
+
timestampMs <= maxTimestamp
|
|
303
|
+
else {
|
|
304
|
+
throw BluetoothError(
|
|
305
|
+
code: "invalid_timestamp",
|
|
306
|
+
message: "setSystemTime timestampMs must be a finite Int64 millisecond timestamp."
|
|
307
|
+
)
|
|
308
|
+
}
|
|
309
|
+
let timestamp = Int64(timestampMs)
|
|
289
310
|
await MainActor.run {
|
|
290
|
-
self.bluetoothSdk().
|
|
311
|
+
self.bluetoothSdk().setSystemTime(timestampMs: timestamp)
|
|
291
312
|
}
|
|
292
313
|
}
|
|
293
314
|
|
|
@@ -295,7 +316,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
295
316
|
|
|
296
317
|
AsyncFunction("setGalleryModeEnabled") { (enabled: Bool) in
|
|
297
318
|
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
298
|
-
try await sdk.setGalleryModeEnabled(enabled)
|
|
319
|
+
return try await sdk.setGalleryModeEnabled(enabled).values
|
|
299
320
|
}
|
|
300
321
|
|
|
301
322
|
AsyncFunction("setVoiceActivityDetectionEnabled") { (enabled: Bool) in
|
|
@@ -303,10 +324,38 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
303
324
|
try await sdk.setVoiceActivityDetectionEnabled(enabled)
|
|
304
325
|
}
|
|
305
326
|
|
|
327
|
+
AsyncFunction("setButtonPhotoSettings") { (size: String) in
|
|
328
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
329
|
+
return try await sdk.setButtonPhotoSettings(size: ButtonPhotoSize(rawValue: size) ?? .medium).values
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
AsyncFunction("setButtonVideoRecordingSettings") { (width: Int, height: Int, fps: Int) in
|
|
333
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
334
|
+
return try await sdk.setButtonVideoRecordingSettings(width: width, height: height, fps: fps).values
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
AsyncFunction("setButtonCameraLed") { (enabled: Bool) in
|
|
338
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
339
|
+
return try await sdk.setButtonCameraLed(enabled: enabled).values
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
AsyncFunction("setButtonMaxRecordingTime") { (minutes: Int) in
|
|
343
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
344
|
+
return try await sdk.setButtonMaxRecordingTime(minutes: minutes).values
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
AsyncFunction("setCameraFov") { (fov: [String: Any]) in
|
|
348
|
+
let value = intValue(fov["fov"]) ?? CameraFov.defaultFov
|
|
349
|
+
let roiPosition = CameraRoiPosition.from(
|
|
350
|
+
rawValue: intValue(fov["roiPosition"]) ?? intValue(fov["roi_position"])
|
|
351
|
+
)
|
|
352
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
353
|
+
return try await sdk.setCameraFov(CameraFov(fov: value, roiPosition: roiPosition)).values
|
|
354
|
+
}
|
|
355
|
+
|
|
306
356
|
AsyncFunction("queryGalleryStatus") {
|
|
307
|
-
await MainActor.run {
|
|
308
|
-
|
|
309
|
-
}
|
|
357
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
358
|
+
return try await sdk.queryGalleryStatus().values
|
|
310
359
|
}
|
|
311
360
|
|
|
312
361
|
AsyncFunction("requestPhoto") { (params: [String: Any]) in
|
|
@@ -320,6 +369,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
320
369
|
let authToken = params["authToken"] as? String ?? ""
|
|
321
370
|
let compress = params["compress"] as? String ?? "none"
|
|
322
371
|
let flash = params["flash"] as? Bool ?? true
|
|
372
|
+
let save = params["save"] as? Bool ?? params["saveToGallery"] as? Bool ?? false
|
|
323
373
|
let sound = params["sound"] as? Bool ?? true
|
|
324
374
|
let exposureTimeNs: Double?
|
|
325
375
|
switch params["exposureTimeNs"] {
|
|
@@ -337,7 +387,8 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
337
387
|
case let value as Int:
|
|
338
388
|
iso = value > 0 ? value : nil
|
|
339
389
|
case let value as Double:
|
|
340
|
-
|
|
390
|
+
// Guard against Int(Double) trapping on out-of-range values.
|
|
391
|
+
iso = (value.isFinite && value > 0 && value < Double(Int.max)) ? Int(value) : nil
|
|
341
392
|
case let value as NSNumber:
|
|
342
393
|
let intValue = value.intValue
|
|
343
394
|
iso = intValue > 0 ? intValue : nil
|
|
@@ -345,44 +396,46 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
345
396
|
iso = nil
|
|
346
397
|
}
|
|
347
398
|
|
|
348
|
-
await MainActor.run {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
399
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
400
|
+
return try await sdk.requestPhoto(
|
|
401
|
+
PhotoRequest(
|
|
402
|
+
requestId: requestId,
|
|
403
|
+
appId: appId,
|
|
404
|
+
size: PhotoSize(rawValue: size) ?? .medium,
|
|
405
|
+
webhookUrl: webhookUrl,
|
|
406
|
+
authToken: authToken,
|
|
407
|
+
compress: PhotoCompression(rawValue: compress),
|
|
408
|
+
flash: flash,
|
|
409
|
+
save: save,
|
|
410
|
+
sound: sound,
|
|
411
|
+
exposureTimeNs: exposureTimeNs,
|
|
412
|
+
iso: iso
|
|
362
413
|
)
|
|
363
|
-
|
|
414
|
+
).values
|
|
364
415
|
}
|
|
365
416
|
|
|
366
417
|
// MARK: - OTA Commands
|
|
367
418
|
|
|
368
419
|
AsyncFunction("sendOtaStart") {
|
|
369
|
-
await MainActor.run {
|
|
370
|
-
|
|
371
|
-
}
|
|
420
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
421
|
+
return try await sdk.sendOtaStart().values
|
|
372
422
|
}
|
|
373
423
|
|
|
374
424
|
AsyncFunction("sendOtaQueryStatus") {
|
|
375
|
-
await MainActor.run {
|
|
376
|
-
|
|
377
|
-
|
|
425
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
426
|
+
return try await sdk.sendOtaQueryStatus().values
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
AsyncFunction("retryOtaVersionCheck") {
|
|
430
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
431
|
+
return try await sdk.retryOtaVersionCheck().values
|
|
378
432
|
}
|
|
379
433
|
|
|
380
434
|
// MARK: - Version Info Commands
|
|
381
435
|
|
|
382
436
|
AsyncFunction("requestVersionInfo") {
|
|
383
|
-
await MainActor.run {
|
|
384
|
-
|
|
385
|
-
}
|
|
437
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
438
|
+
return try await sdk.requestVersionInfo().dictionary
|
|
386
439
|
}
|
|
387
440
|
|
|
388
441
|
// MARK: - Power Control Commands
|
|
@@ -401,37 +454,43 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
401
454
|
|
|
402
455
|
// MARK: - Video Recording Commands
|
|
403
456
|
|
|
404
|
-
AsyncFunction("startVideoRecording") {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
457
|
+
AsyncFunction("startVideoRecording") {
|
|
458
|
+
(requestId: String, save: Bool, sound: Bool, settings: [String: Any]?) in
|
|
459
|
+
// Optional per-recording {width,height,fps}. Absent fields stay 0, which
|
|
460
|
+
// the glasses treat as "use the saved button-video default". JS numbers
|
|
461
|
+
// arrive as Double across the bridge, so coerce to Int.
|
|
462
|
+
func dim(_ key: String) -> Int {
|
|
463
|
+
(settings?[key] as? NSNumber)?.intValue ?? 0
|
|
409
464
|
}
|
|
465
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
466
|
+
return try await sdk.startVideoRecording(
|
|
467
|
+
VideoRecordingRequest(
|
|
468
|
+
requestId: requestId, save: save, sound: sound,
|
|
469
|
+
width: dim("width"), height: dim("height"), fps: dim("fps")
|
|
470
|
+
)
|
|
471
|
+
).values
|
|
410
472
|
}
|
|
411
473
|
|
|
412
474
|
AsyncFunction("stopVideoRecording") { (requestId: String) in
|
|
413
|
-
await MainActor.run {
|
|
414
|
-
|
|
415
|
-
}
|
|
475
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
476
|
+
return try await sdk.stopVideoRecording(requestId: requestId).values
|
|
416
477
|
}
|
|
417
478
|
|
|
418
479
|
// MARK: - Stream Commands
|
|
419
480
|
|
|
420
481
|
AsyncFunction("startStream") { (params: [String: Any]) in
|
|
421
|
-
await MainActor.run {
|
|
422
|
-
|
|
423
|
-
}
|
|
482
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
483
|
+
return try await sdk.startStream(StreamRequest(values: params)).values
|
|
424
484
|
}
|
|
425
485
|
|
|
426
486
|
AsyncFunction("stopStream") {
|
|
427
|
-
await MainActor.run {
|
|
428
|
-
|
|
429
|
-
}
|
|
487
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
488
|
+
return try await sdk.stopStream().values
|
|
430
489
|
}
|
|
431
490
|
|
|
432
|
-
AsyncFunction("
|
|
491
|
+
AsyncFunction("sendExternallyManagedStreamKeepAlive") { (params: [String: Any]) in
|
|
433
492
|
await MainActor.run {
|
|
434
|
-
self.bluetoothSdk().
|
|
493
|
+
self.bluetoothSdk().sendExternallyManagedStreamKeepAlive(StreamKeepAliveRequest(values: params))
|
|
435
494
|
}
|
|
436
495
|
}
|
|
437
496
|
|
|
@@ -458,19 +517,18 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
458
517
|
requestId: String, packageName: String?, action: String, color: String?,
|
|
459
518
|
onDurationMs: Int, offDurationMs: Int, count: Int
|
|
460
519
|
) in
|
|
461
|
-
await MainActor.run {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
)
|
|
520
|
+
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
521
|
+
return try await sdk.rgbLedControl(
|
|
522
|
+
RgbLedRequest(
|
|
523
|
+
requestId: requestId,
|
|
524
|
+
packageName: packageName,
|
|
525
|
+
action: RgbLedAction(rawValue: action) ?? .off,
|
|
526
|
+
color: color.flatMap(RgbLedColor.init(rawValue:)),
|
|
527
|
+
onDurationMs: onDurationMs,
|
|
528
|
+
offDurationMs: offDurationMs,
|
|
529
|
+
count: count
|
|
472
530
|
)
|
|
473
|
-
|
|
531
|
+
).values
|
|
474
532
|
}
|
|
475
533
|
|
|
476
534
|
// MARK: - Microphone Commands
|
|
@@ -525,6 +583,39 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
525
583
|
AsyncFunction("extractTarBz2") { (sourcePath: String, destinationPath: String) -> Bool in
|
|
526
584
|
return STTTools.extractTarBz2(sourcePath: sourcePath, destinationPath: destinationPath)
|
|
527
585
|
}
|
|
586
|
+
|
|
587
|
+
// MARK: - TTS Model Management
|
|
588
|
+
|
|
589
|
+
AsyncFunction("setTtsModelDetails") { (path: String, languageCode: String) in
|
|
590
|
+
TTSTools.setTtsModelDetails(path, languageCode)
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
AsyncFunction("getTtsModelPath") { () -> String in
|
|
594
|
+
return TTSTools.getTtsModelPath()
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
AsyncFunction("getTtsModelLanguage") { () -> String in
|
|
598
|
+
return TTSTools.getTtsModelLanguage()
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
AsyncFunction("checkTtsModelAvailable") { () -> Bool in
|
|
602
|
+
return TTSTools.checkTTSModelAvailable()
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
AsyncFunction("validateTtsModel") { (path: String) -> Bool in
|
|
606
|
+
return TTSTools.validateTTSModel(path)
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
AsyncFunction("generateTtsAudio") {
|
|
610
|
+
(text: String, modelPath: String, outputPath: String, speakerId: Int, speed: Double) -> Bool in
|
|
611
|
+
return TTSTools.generateTtsAudio(
|
|
612
|
+
text: text,
|
|
613
|
+
modelPath: modelPath,
|
|
614
|
+
outputPath: outputPath,
|
|
615
|
+
speakerId: speakerId,
|
|
616
|
+
speed: speed
|
|
617
|
+
)
|
|
618
|
+
}
|
|
528
619
|
}
|
|
529
620
|
|
|
530
621
|
@MainActor
|
|
@@ -610,10 +701,26 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
610
701
|
sendEvent("photo_response", response.values)
|
|
611
702
|
case let .photoStatus(status):
|
|
612
703
|
sendEvent("photo_status", status.values)
|
|
704
|
+
case let .videoRecordingStatus(status):
|
|
705
|
+
sendEvent("video_recording_status", status.values)
|
|
706
|
+
case let .rgbLedControlResponse(response):
|
|
707
|
+
sendEvent("rgb_led_control_response", response.values)
|
|
613
708
|
case let .streamStatus(status):
|
|
614
709
|
sendEvent("stream_status", status.values)
|
|
615
710
|
case let .keepAliveAck(ack):
|
|
616
711
|
sendEvent("keep_alive_ack", ack.values)
|
|
712
|
+
case let .otaUpdateAvailable(event):
|
|
713
|
+
sendEvent("ota_update_available", event.values)
|
|
714
|
+
case let .otaStartAck(event):
|
|
715
|
+
sendEvent("ota_start_ack", event.values)
|
|
716
|
+
case let .otaStatus(event):
|
|
717
|
+
sendEvent("ota_status", event.values)
|
|
718
|
+
case let .settingsAck(event):
|
|
719
|
+
sendEvent("settings_ack", event.values)
|
|
720
|
+
case let .versionInfo(event):
|
|
721
|
+
var values = event.dictionary
|
|
722
|
+
values["type"] = "version_info"
|
|
723
|
+
sendEvent("version_info", values)
|
|
617
724
|
case let .localTranscription(transcription):
|
|
618
725
|
sendEvent("local_transcription", transcription.values)
|
|
619
726
|
case let .raw(name, values):
|