@mentra/bluetooth-sdk 0.1.2 → 0.1.4
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 +75 -19
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +13 -13
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +42 -18
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +19 -21
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +4 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +118 -103
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +110 -38
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +4 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +6 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +18 -18
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +4 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +6 -6
- package/app.plugin.js +3 -1
- package/build/BluetoothSdk.types.d.ts +126 -27
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_internal.d.ts +12 -0
- package/build/_internal.d.ts.map +1 -0
- package/build/_internal.js +11 -0
- package/build/_internal.js.map +1 -0
- package/build/{BluetoothSdkModule.d.ts → _private/BluetoothSdkModule.d.ts} +19 -8
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -0
- package/build/{BluetoothSdkModule.js → _private/BluetoothSdkModule.js} +41 -26
- package/build/_private/BluetoothSdkModule.js.map +1 -0
- package/build/index.d.ts +4 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -4
- package/build/index.js.map +1 -1
- package/build/react/index.d.ts +5 -0
- package/build/react/index.d.ts.map +1 -0
- package/build/react/index.js +5 -0
- package/build/react/index.js.map +1 -0
- package/build/react/useBluetoothEvent.d.ts +6 -0
- package/build/react/useBluetoothEvent.d.ts.map +1 -0
- package/build/react/useBluetoothEvent.js +21 -0
- package/build/react/useBluetoothEvent.js.map +1 -0
- package/build/react/useBluetoothScan.d.ts +22 -0
- package/build/react/useBluetoothScan.d.ts.map +1 -0
- package/build/react/useBluetoothScan.js +135 -0
- package/build/react/useBluetoothScan.js.map +1 -0
- package/build/react/useBluetoothStatus.d.ts +16 -0
- package/build/react/useBluetoothStatus.d.ts.map +1 -0
- package/build/react/useBluetoothStatus.js +137 -0
- package/build/react/useBluetoothStatus.js.map +1 -0
- package/build/react/useGlassesConnection.d.ts +29 -0
- package/build/react/useGlassesConnection.d.ts.map +1 -0
- package/build/react/useGlassesConnection.js +140 -0
- package/build/react/useGlassesConnection.js.map +1 -0
- package/ios/BluetoothSdkModule.swift +14 -9
- package/ios/Source/Bridge.swift +44 -12
- package/ios/Source/DeviceManager.swift +27 -26
- package/ios/Source/DeviceStore.swift +4 -4
- package/ios/Source/MentraBluetoothSDK.swift +250 -132
- package/ios/Source/controllers/ControllerManager.swift +5 -5
- package/ios/Source/controllers/R1.swift +3 -3
- package/ios/Source/services/PhoneMic.swift +5 -5
- package/ios/Source/sgcs/Frame.swift +1 -1
- package/ios/Source/sgcs/G1.swift +1 -1
- package/ios/Source/sgcs/G2.swift +3 -3
- package/ios/Source/sgcs/Mach1.swift +1 -1
- package/ios/Source/sgcs/MentraLive.swift +31 -33
- package/ios/Source/sgcs/MentraNex.swift +2 -2
- package/ios/Source/sgcs/SGCManager.swift +5 -5
- package/ios/Source/sgcs/Simulated.swift +3 -3
- package/ios/Source/utils/Constants.swift +6 -6
- package/ios/Source/utils/JSCExperiment.swift +8 -8
- package/ios/Source/utils/TarBz2Extractor.swift +2 -2
- package/package.json +19 -1
- package/src/BluetoothSdk.types.ts +186 -28
- package/src/_internal.ts +11 -0
- package/src/{BluetoothSdkModule.ts → _private/BluetoothSdkModule.ts} +71 -38
- package/src/index.ts +80 -4
- package/src/react/index.ts +22 -0
- package/src/react/useBluetoothEvent.ts +38 -0
- package/src/react/useBluetoothScan.ts +173 -0
- package/src/react/useBluetoothStatus.ts +180 -0
- package/src/react/useGlassesConnection.ts +194 -0
- package/build/BluetoothSdkModule.d.ts.map +0 -1
- package/build/BluetoothSdkModule.js.map +0 -1
|
@@ -52,10 +52,10 @@ data class Device(
|
|
|
52
52
|
|
|
53
53
|
companion object {
|
|
54
54
|
internal fun fromMap(values: Map<String, Any>): Device? {
|
|
55
|
-
val model = stringValue(values, "model"
|
|
56
|
-
val name = stringValue(values, "name"
|
|
57
|
-
val address = stringValue(values, "address"
|
|
58
|
-
val rssi = numberValue(values, "rssi"
|
|
55
|
+
val model = stringValue(values, "model") ?: return null
|
|
56
|
+
val name = stringValue(values, "name") ?: return null
|
|
57
|
+
val address = stringValue(values, "address")?.takeIf { it.isNotBlank() }
|
|
58
|
+
val rssi = numberValue(values, "rssi")
|
|
59
59
|
val id = stringValue(values, "id")?.takeIf { it.isNotBlank() } ?: address ?: "${model}:$name"
|
|
60
60
|
return Device(
|
|
61
61
|
model = DeviceModel.fromDeviceType(model),
|
|
@@ -94,9 +94,8 @@ data class WifiScanResult(
|
|
|
94
94
|
internal fun fromMap(values: Map<String, Any>): WifiScanResult =
|
|
95
95
|
WifiScanResult(
|
|
96
96
|
ssid = stringValue(values, "ssid") ?: "",
|
|
97
|
-
requiresPassword =
|
|
98
|
-
|
|
99
|
-
signalStrength = numberValue(values, "signalStrength", "signal_strength", "rssi") ?: -1,
|
|
97
|
+
requiresPassword = boolValue(values, "requiresPassword") ?: false,
|
|
98
|
+
signalStrength = numberValue(values, "signalStrength") ?: -1,
|
|
100
99
|
frequency = numberValue(values, "frequency"),
|
|
101
100
|
)
|
|
102
101
|
}
|
|
@@ -107,7 +106,7 @@ data class GlassesStatus(
|
|
|
107
106
|
val connected: Boolean,
|
|
108
107
|
val micEnabled: Boolean,
|
|
109
108
|
val connectionState: GlassesConnectionState,
|
|
110
|
-
val
|
|
109
|
+
val bluetoothClassicConnected: Boolean,
|
|
111
110
|
val signalStrength: Int,
|
|
112
111
|
val signalStrengthUpdatedAt: Long,
|
|
113
112
|
val deviceModel: String,
|
|
@@ -115,7 +114,7 @@ data class GlassesStatus(
|
|
|
115
114
|
val firmwareVersion: String,
|
|
116
115
|
val besFirmwareVersion: String,
|
|
117
116
|
val mtkFirmwareVersion: String,
|
|
118
|
-
val
|
|
117
|
+
val bluetoothMacAddress: String,
|
|
119
118
|
val leftMacAddress: String,
|
|
120
119
|
val rightMacAddress: String,
|
|
121
120
|
val macAddress: String,
|
|
@@ -146,15 +145,15 @@ data class GlassesStatus(
|
|
|
146
145
|
mapOf(
|
|
147
146
|
"connection" to connectionState.toStatusMap(connected, fullyBooted),
|
|
148
147
|
"micEnabled" to micEnabled,
|
|
149
|
-
"
|
|
148
|
+
"bluetoothClassicConnected" to bluetoothClassicConnected,
|
|
150
149
|
"signalStrength" to signalStrength,
|
|
151
150
|
"signalStrengthUpdatedAt" to signalStrengthUpdatedAt,
|
|
152
151
|
"deviceModel" to deviceModel,
|
|
153
152
|
"androidVersion" to androidVersion,
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
153
|
+
"firmwareVersion" to firmwareVersion,
|
|
154
|
+
"besFirmwareVersion" to besFirmwareVersion,
|
|
155
|
+
"mtkFirmwareVersion" to mtkFirmwareVersion,
|
|
156
|
+
"bluetoothMacAddress" to bluetoothMacAddress,
|
|
158
157
|
"leftMacAddress" to leftMacAddress,
|
|
159
158
|
"rightMacAddress" to rightMacAddress,
|
|
160
159
|
"macAddress" to macAddress,
|
|
@@ -189,15 +188,15 @@ data class GlassesStatus(
|
|
|
189
188
|
connected = boolValue(values, "connected") ?: false,
|
|
190
189
|
micEnabled = boolValue(values, "micEnabled") ?: false,
|
|
191
190
|
connectionState = GlassesConnectionState.fromValue(stringValue(values, "connectionState")),
|
|
192
|
-
|
|
191
|
+
bluetoothClassicConnected = boolValue(values, "bluetoothClassicConnected") ?: false,
|
|
193
192
|
signalStrength = numberValue(values, "signalStrength") ?: -1,
|
|
194
193
|
signalStrengthUpdatedAt = longValue(values, "signalStrengthUpdatedAt") ?: 0L,
|
|
195
194
|
deviceModel = stringValue(values, "deviceModel") ?: "",
|
|
196
195
|
androidVersion = stringValue(values, "androidVersion") ?: "",
|
|
197
|
-
firmwareVersion = stringValue(values, "firmwareVersion"
|
|
198
|
-
besFirmwareVersion = stringValue(values, "
|
|
199
|
-
mtkFirmwareVersion = stringValue(values, "
|
|
200
|
-
|
|
196
|
+
firmwareVersion = stringValue(values, "firmwareVersion") ?: "",
|
|
197
|
+
besFirmwareVersion = stringValue(values, "besFirmwareVersion") ?: "",
|
|
198
|
+
mtkFirmwareVersion = stringValue(values, "mtkFirmwareVersion") ?: "",
|
|
199
|
+
bluetoothMacAddress = stringValue(values, "bluetoothMacAddress") ?: "",
|
|
201
200
|
leftMacAddress = stringValue(values, "leftMacAddress") ?: "",
|
|
202
201
|
rightMacAddress = stringValue(values, "rightMacAddress") ?: "",
|
|
203
202
|
macAddress = stringValue(values, "macAddress") ?: "",
|
|
@@ -234,6 +233,11 @@ data class BluetoothStatus(
|
|
|
234
233
|
val micEnabled: Boolean,
|
|
235
234
|
val currentMic: String,
|
|
236
235
|
val micRanking: List<String>,
|
|
236
|
+
/**
|
|
237
|
+
* Nearby glasses in stable discovery order. Existing entries keep their array position as
|
|
238
|
+
* details refresh; new glasses append at the end, and removals should not reorder remaining
|
|
239
|
+
* entries.
|
|
240
|
+
*/
|
|
237
241
|
val searchResults: List<Device>,
|
|
238
242
|
val wifiScanResults: List<WifiScanResult>,
|
|
239
243
|
val lastLog: List<String>,
|
|
@@ -261,7 +265,7 @@ data class BluetoothStatus(
|
|
|
261
265
|
val buttonMaxRecordingTime: Int,
|
|
262
266
|
val buttonVideoWidth: Int,
|
|
263
267
|
val buttonVideoHeight: Int,
|
|
264
|
-
val
|
|
268
|
+
val buttonVideoFrameRate: Int,
|
|
265
269
|
val shouldSendPcm: Boolean,
|
|
266
270
|
val shouldSendLc3: Boolean,
|
|
267
271
|
val shouldSendTranscript: Boolean,
|
|
@@ -309,13 +313,13 @@ data class BluetoothStatus(
|
|
|
309
313
|
"dashboard_depth" to dashboardDepth,
|
|
310
314
|
"head_up_angle" to headUpAngle,
|
|
311
315
|
"contextual_dashboard" to contextualDashboard,
|
|
312
|
-
"
|
|
316
|
+
"galleryModeAuto" to galleryModeAuto,
|
|
313
317
|
"button_photo_size" to buttonPhotoSize.value,
|
|
314
318
|
"button_camera_led" to buttonCameraLed,
|
|
315
319
|
"button_max_recording_time" to buttonMaxRecordingTime,
|
|
316
320
|
"button_video_width" to buttonVideoWidth,
|
|
317
321
|
"button_video_height" to buttonVideoHeight,
|
|
318
|
-
"button_video_fps" to
|
|
322
|
+
"button_video_fps" to buttonVideoFrameRate,
|
|
319
323
|
"should_send_pcm" to shouldSendPcm,
|
|
320
324
|
"should_send_lc3" to shouldSendLc3,
|
|
321
325
|
"should_send_transcript" to shouldSendTranscript,
|
|
@@ -357,13 +361,13 @@ data class BluetoothStatus(
|
|
|
357
361
|
dashboardDepth = numberValue(values, "dashboard_depth") ?: 2,
|
|
358
362
|
headUpAngle = numberValue(values, "head_up_angle") ?: 30,
|
|
359
363
|
contextualDashboard = boolValue(values, "contextual_dashboard") ?: true,
|
|
360
|
-
galleryModeAuto = boolValue(values, "
|
|
364
|
+
galleryModeAuto = boolValue(values, "galleryModeAuto") ?: true,
|
|
361
365
|
buttonPhotoSize = ButtonPhotoSize.fromValue(stringValue(values, "button_photo_size")),
|
|
362
366
|
buttonCameraLed = boolValue(values, "button_camera_led") ?: true,
|
|
363
367
|
buttonMaxRecordingTime = numberValue(values, "button_max_recording_time") ?: 10,
|
|
364
368
|
buttonVideoWidth = numberValue(values, "button_video_width") ?: 1280,
|
|
365
369
|
buttonVideoHeight = numberValue(values, "button_video_height") ?: 720,
|
|
366
|
-
|
|
370
|
+
buttonVideoFrameRate = numberValue(values, "button_video_fps") ?: 30,
|
|
367
371
|
shouldSendPcm = boolValue(values, "should_send_pcm") ?: false,
|
|
368
372
|
shouldSendLc3 = boolValue(values, "should_send_lc3") ?: false,
|
|
369
373
|
shouldSendTranscript = boolValue(values, "should_send_transcript") ?: false,
|
|
@@ -380,7 +384,7 @@ data class GlassesStatusUpdate(
|
|
|
380
384
|
val connected: Boolean? = null,
|
|
381
385
|
val micEnabled: Boolean? = null,
|
|
382
386
|
val connectionState: GlassesConnectionState? = null,
|
|
383
|
-
val
|
|
387
|
+
val bluetoothClassicConnected: Boolean? = null,
|
|
384
388
|
val signalStrength: Int? = null,
|
|
385
389
|
val signalStrengthUpdatedAt: Long? = null,
|
|
386
390
|
val deviceModel: String? = null,
|
|
@@ -388,7 +392,7 @@ data class GlassesStatusUpdate(
|
|
|
388
392
|
val firmwareVersion: String? = null,
|
|
389
393
|
val besFirmwareVersion: String? = null,
|
|
390
394
|
val mtkFirmwareVersion: String? = null,
|
|
391
|
-
val
|
|
395
|
+
val bluetoothMacAddress: String? = null,
|
|
392
396
|
val leftMacAddress: String? = null,
|
|
393
397
|
val rightMacAddress: String? = null,
|
|
394
398
|
val macAddress: String? = null,
|
|
@@ -428,15 +432,15 @@ data class GlassesStatusUpdate(
|
|
|
428
432
|
put("connection", state.toStatusMap(connected == true, fullyBooted == true))
|
|
429
433
|
}
|
|
430
434
|
putIfNotNull("micEnabled", micEnabled)
|
|
431
|
-
putIfNotNull("
|
|
435
|
+
putIfNotNull("bluetoothClassicConnected", bluetoothClassicConnected)
|
|
432
436
|
putIfNotNull("signalStrength", signalStrength)
|
|
433
437
|
putIfNotNull("signalStrengthUpdatedAt", signalStrengthUpdatedAt)
|
|
434
438
|
putIfNotNull("deviceModel", deviceModel)
|
|
435
439
|
putIfNotNull("androidVersion", androidVersion)
|
|
436
|
-
putIfNotNull("
|
|
437
|
-
putIfNotNull("
|
|
438
|
-
putIfNotNull("
|
|
439
|
-
putIfNotNull("
|
|
440
|
+
putIfNotNull("firmwareVersion", firmwareVersion)
|
|
441
|
+
putIfNotNull("besFirmwareVersion", besFirmwareVersion)
|
|
442
|
+
putIfNotNull("mtkFirmwareVersion", mtkFirmwareVersion)
|
|
443
|
+
putIfNotNull("bluetoothMacAddress", bluetoothMacAddress)
|
|
440
444
|
putIfNotNull("leftMacAddress", leftMacAddress)
|
|
441
445
|
putIfNotNull("rightMacAddress", rightMacAddress)
|
|
442
446
|
putIfNotNull("macAddress", macAddress)
|
|
@@ -475,15 +479,15 @@ data class GlassesStatusUpdate(
|
|
|
475
479
|
connected = optionalBoolValue(values, "connected"),
|
|
476
480
|
micEnabled = optionalBoolValue(values, "micEnabled"),
|
|
477
481
|
connectionState = GlassesConnectionState.optionalFromValue(optionalStringValue(values, "connectionState")),
|
|
478
|
-
|
|
482
|
+
bluetoothClassicConnected = optionalBoolValue(values, "bluetoothClassicConnected"),
|
|
479
483
|
signalStrength = optionalNumberValue(values, "signalStrength"),
|
|
480
484
|
signalStrengthUpdatedAt = optionalLongValue(values, "signalStrengthUpdatedAt"),
|
|
481
485
|
deviceModel = optionalStringValue(values, "deviceModel"),
|
|
482
486
|
androidVersion = optionalStringValue(values, "androidVersion"),
|
|
483
|
-
firmwareVersion = optionalStringValue(values, "firmwareVersion"
|
|
484
|
-
besFirmwareVersion = optionalStringValue(values, "
|
|
485
|
-
mtkFirmwareVersion = optionalStringValue(values, "
|
|
486
|
-
|
|
487
|
+
firmwareVersion = optionalStringValue(values, "firmwareVersion"),
|
|
488
|
+
besFirmwareVersion = optionalStringValue(values, "besFirmwareVersion"),
|
|
489
|
+
mtkFirmwareVersion = optionalStringValue(values, "mtkFirmwareVersion"),
|
|
490
|
+
bluetoothMacAddress = optionalStringValue(values, "bluetoothMacAddress"),
|
|
487
491
|
leftMacAddress = optionalStringValue(values, "leftMacAddress"),
|
|
488
492
|
rightMacAddress = optionalStringValue(values, "rightMacAddress"),
|
|
489
493
|
macAddress = optionalStringValue(values, "macAddress"),
|
|
@@ -511,7 +515,7 @@ data class GlassesStatusUpdate(
|
|
|
511
515
|
hotspot =
|
|
512
516
|
if (hasAnyKey(values, "hotspot")) {
|
|
513
517
|
HotspotStatus.fromMap(values)
|
|
514
|
-
} else if (hasAnyKey(values, "hotspotEnabled", "hotspotSsid", "hotspotPassword", "hotspotGatewayIp"
|
|
518
|
+
} else if (hasAnyKey(values, "hotspotEnabled", "hotspotSsid", "hotspotPassword", "hotspotGatewayIp")) {
|
|
515
519
|
HotspotStatus.fromStoreMap(values)
|
|
516
520
|
} else {
|
|
517
521
|
null
|
|
@@ -534,6 +538,11 @@ data class BluetoothStatusUpdate(
|
|
|
534
538
|
val micEnabled: Boolean? = null,
|
|
535
539
|
val currentMic: String? = null,
|
|
536
540
|
val micRanking: List<String>? = null,
|
|
541
|
+
/**
|
|
542
|
+
* Nearby glasses in stable discovery order when included in an update. Existing entries keep
|
|
543
|
+
* their array position as details refresh; new glasses append at the end, and removals should
|
|
544
|
+
* not reorder remaining entries.
|
|
545
|
+
*/
|
|
537
546
|
val searchResults: List<Device>? = null,
|
|
538
547
|
val wifiScanResults: List<WifiScanResult>? = null,
|
|
539
548
|
val lastLog: List<String>? = null,
|
|
@@ -561,7 +570,7 @@ data class BluetoothStatusUpdate(
|
|
|
561
570
|
val buttonMaxRecordingTime: Int? = null,
|
|
562
571
|
val buttonVideoWidth: Int? = null,
|
|
563
572
|
val buttonVideoHeight: Int? = null,
|
|
564
|
-
val
|
|
573
|
+
val buttonVideoFrameRate: Int? = null,
|
|
565
574
|
val shouldSendPcm: Boolean? = null,
|
|
566
575
|
val shouldSendLc3: Boolean? = null,
|
|
567
576
|
val shouldSendTranscript: Boolean? = null,
|
|
@@ -599,13 +608,13 @@ data class BluetoothStatusUpdate(
|
|
|
599
608
|
putIfNotNull("dashboard_depth", dashboardDepth)
|
|
600
609
|
putIfNotNull("head_up_angle", headUpAngle)
|
|
601
610
|
putIfNotNull("contextual_dashboard", contextualDashboard)
|
|
602
|
-
putIfNotNull("
|
|
611
|
+
putIfNotNull("galleryModeAuto", galleryModeAuto)
|
|
603
612
|
buttonPhotoSize?.let { put("button_photo_size", it.value) }
|
|
604
613
|
putIfNotNull("button_camera_led", buttonCameraLed)
|
|
605
614
|
putIfNotNull("button_max_recording_time", buttonMaxRecordingTime)
|
|
606
615
|
putIfNotNull("button_video_width", buttonVideoWidth)
|
|
607
616
|
putIfNotNull("button_video_height", buttonVideoHeight)
|
|
608
|
-
putIfNotNull("button_video_fps",
|
|
617
|
+
putIfNotNull("button_video_fps", buttonVideoFrameRate)
|
|
609
618
|
putIfNotNull("should_send_pcm", shouldSendPcm)
|
|
610
619
|
putIfNotNull("should_send_lc3", shouldSendLc3)
|
|
611
620
|
putIfNotNull("should_send_transcript", shouldSendTranscript)
|
|
@@ -649,14 +658,14 @@ data class BluetoothStatusUpdate(
|
|
|
649
658
|
dashboardDepth = optionalNumberValue(values, "dashboard_depth"),
|
|
650
659
|
headUpAngle = optionalNumberValue(values, "head_up_angle"),
|
|
651
660
|
contextualDashboard = optionalBoolValue(values, "contextual_dashboard"),
|
|
652
|
-
galleryModeAuto = optionalBoolValue(values, "
|
|
661
|
+
galleryModeAuto = optionalBoolValue(values, "galleryModeAuto"),
|
|
653
662
|
buttonPhotoSize =
|
|
654
663
|
optionalStringValue(values, "button_photo_size")?.let(ButtonPhotoSize::fromValue),
|
|
655
664
|
buttonCameraLed = optionalBoolValue(values, "button_camera_led"),
|
|
656
665
|
buttonMaxRecordingTime = optionalNumberValue(values, "button_max_recording_time"),
|
|
657
666
|
buttonVideoWidth = optionalNumberValue(values, "button_video_width"),
|
|
658
667
|
buttonVideoHeight = optionalNumberValue(values, "button_video_height"),
|
|
659
|
-
|
|
668
|
+
buttonVideoFrameRate = optionalNumberValue(values, "button_video_fps"),
|
|
660
669
|
shouldSendPcm = optionalBoolValue(values, "should_send_pcm"),
|
|
661
670
|
shouldSendLc3 = optionalBoolValue(values, "should_send_lc3"),
|
|
662
671
|
shouldSendTranscript = optionalBoolValue(values, "should_send_transcript"),
|
|
@@ -683,7 +692,7 @@ data class DisplayTextRequest(
|
|
|
683
692
|
)
|
|
684
693
|
}
|
|
685
694
|
|
|
686
|
-
data class DisplayEventRequest(
|
|
695
|
+
internal data class DisplayEventRequest(
|
|
687
696
|
val values: Map<String, Any>,
|
|
688
697
|
) {
|
|
689
698
|
fun toMap(): Map<String, Any> = values
|
|
@@ -694,7 +703,7 @@ data class DashboardPositionRequest(
|
|
|
694
703
|
val depth: Int,
|
|
695
704
|
)
|
|
696
705
|
|
|
697
|
-
data class DashboardMenuItem(
|
|
706
|
+
internal data class DashboardMenuItem(
|
|
698
707
|
val title: String,
|
|
699
708
|
val packageName: String,
|
|
700
709
|
val values: Map<String, Any> = emptyMap(),
|
|
@@ -755,7 +764,7 @@ data class ButtonPhotoSettings(
|
|
|
755
764
|
data class ButtonVideoRecordingSettings(
|
|
756
765
|
val width: Int,
|
|
757
766
|
val height: Int,
|
|
758
|
-
val
|
|
767
|
+
val frameRate: Int,
|
|
759
768
|
)
|
|
760
769
|
|
|
761
770
|
enum class CameraFov(val fov: Int, val roiPosition: Int) {
|
|
@@ -763,19 +772,11 @@ enum class CameraFov(val fov: Int, val roiPosition: Int) {
|
|
|
763
772
|
WIDE(118, 0),
|
|
764
773
|
}
|
|
765
774
|
|
|
766
|
-
data class MicConfig(
|
|
767
|
-
val sendPcmData: Boolean,
|
|
768
|
-
val sendTranscript: Boolean,
|
|
769
|
-
val bypassVad: Boolean,
|
|
770
|
-
val sendLc3Data: Boolean = false,
|
|
771
|
-
)
|
|
772
|
-
|
|
773
775
|
enum class MicPreference(val value: String) {
|
|
774
776
|
AUTO("auto"),
|
|
775
777
|
PHONE("phone"),
|
|
776
778
|
GLASSES("glasses"),
|
|
777
|
-
|
|
778
|
-
BT("bt"),
|
|
779
|
+
BLUETOOTH("bluetooth"),
|
|
779
780
|
}
|
|
780
781
|
|
|
781
782
|
data class PhotoRequest @JvmOverloads constructor(
|
|
@@ -785,7 +786,6 @@ data class PhotoRequest @JvmOverloads constructor(
|
|
|
785
786
|
val webhookUrl: String,
|
|
786
787
|
val authToken: String? = null,
|
|
787
788
|
val compress: PhotoCompression = PhotoCompression.MEDIUM,
|
|
788
|
-
val flash: Boolean = false,
|
|
789
789
|
val sound: Boolean = true,
|
|
790
790
|
)
|
|
791
791
|
|
|
@@ -805,13 +805,13 @@ data class StreamVideoConfig @JvmOverloads constructor(
|
|
|
805
805
|
|
|
806
806
|
companion object {
|
|
807
807
|
@JvmStatic
|
|
808
|
-
fun fromMap(values: Map
|
|
808
|
+
fun fromMap(values: Map<String, Any>?): StreamVideoConfig? {
|
|
809
809
|
values ?: return null
|
|
810
810
|
return StreamVideoConfig(
|
|
811
|
-
width = numberValue(values, "width"
|
|
812
|
-
height = numberValue(values, "height"
|
|
813
|
-
bitrate = numberValue(values, "bitrate"
|
|
814
|
-
frameRate = numberValue(values, "frameRate"
|
|
811
|
+
width = numberValue(values, "width"),
|
|
812
|
+
height = numberValue(values, "height"),
|
|
813
|
+
bitrate = numberValue(values, "bitrate"),
|
|
814
|
+
frameRate = numberValue(values, "frameRate"),
|
|
815
815
|
)
|
|
816
816
|
}
|
|
817
817
|
}
|
|
@@ -833,13 +833,13 @@ data class StreamAudioConfig @JvmOverloads constructor(
|
|
|
833
833
|
|
|
834
834
|
companion object {
|
|
835
835
|
@JvmStatic
|
|
836
|
-
fun fromMap(values: Map
|
|
836
|
+
fun fromMap(values: Map<String, Any>?): StreamAudioConfig? {
|
|
837
837
|
values ?: return null
|
|
838
838
|
return StreamAudioConfig(
|
|
839
|
-
bitrate = numberValue(values, "bitrate"
|
|
840
|
-
sampleRate = numberValue(values, "sampleRate"
|
|
841
|
-
echoCancellation = values["echoCancellation"] as? Boolean
|
|
842
|
-
noiseSuppression = values["noiseSuppression"] as? Boolean
|
|
839
|
+
bitrate = numberValue(values, "bitrate"),
|
|
840
|
+
sampleRate = numberValue(values, "sampleRate"),
|
|
841
|
+
echoCancellation = values["echoCancellation"] as? Boolean,
|
|
842
|
+
noiseSuppression = values["noiseSuppression"] as? Boolean,
|
|
843
843
|
)
|
|
844
844
|
}
|
|
845
845
|
}
|
|
@@ -850,7 +850,6 @@ data class StreamRequest @JvmOverloads constructor(
|
|
|
850
850
|
val streamId: String = "",
|
|
851
851
|
val keepAlive: Boolean = true,
|
|
852
852
|
val keepAliveIntervalSeconds: Int = 15,
|
|
853
|
-
val flash: Boolean = true,
|
|
854
853
|
val sound: Boolean = true,
|
|
855
854
|
val video: StreamVideoConfig? = null,
|
|
856
855
|
val audio: StreamAudioConfig? = null,
|
|
@@ -863,7 +862,8 @@ data class StreamRequest @JvmOverloads constructor(
|
|
|
863
862
|
values["streamId"] = streamId
|
|
864
863
|
values["keepAlive"] = keepAlive
|
|
865
864
|
values["keepAliveIntervalSeconds"] = keepAliveIntervalSeconds
|
|
866
|
-
|
|
865
|
+
// The camera light is a privacy indicator and cannot be disabled by SDK callers.
|
|
866
|
+
values["flash"] = true
|
|
867
867
|
values["sound"] = sound
|
|
868
868
|
video?.toMap()?.takeIf { it.isNotEmpty() }?.let { values["video"] = it }
|
|
869
869
|
audio?.toMap()?.takeIf { it.isNotEmpty() }?.let { values["audio"] = it }
|
|
@@ -880,10 +880,9 @@ data class StreamRequest @JvmOverloads constructor(
|
|
|
880
880
|
streamId = values["streamId"] as? String ?: "",
|
|
881
881
|
keepAlive = values["keepAlive"] as? Boolean ?: true,
|
|
882
882
|
keepAliveIntervalSeconds = (values["keepAliveIntervalSeconds"] as? Number)?.toInt() ?: 15,
|
|
883
|
-
flash = values["flash"] as? Boolean ?: true,
|
|
884
883
|
sound = values["sound"] as? Boolean ?: true,
|
|
885
|
-
video = StreamVideoConfig.fromMap((values["video"]
|
|
886
|
-
audio = StreamAudioConfig.fromMap((values["audio"]
|
|
884
|
+
video = StreamVideoConfig.fromMap(stringMapValue(values["video"])),
|
|
885
|
+
audio = StreamAudioConfig.fromMap(stringMapValue(values["audio"])),
|
|
887
886
|
extraValues = values,
|
|
888
887
|
)
|
|
889
888
|
}
|
|
@@ -943,15 +942,14 @@ data class RgbLedRequest @JvmOverloads constructor(
|
|
|
943
942
|
val packageName: String?,
|
|
944
943
|
val action: RgbLedAction,
|
|
945
944
|
val color: RgbLedColor?,
|
|
946
|
-
val
|
|
947
|
-
val
|
|
945
|
+
val onDurationMs: Int,
|
|
946
|
+
val offDurationMs: Int,
|
|
948
947
|
val count: Int,
|
|
949
948
|
)
|
|
950
949
|
|
|
951
950
|
data class VideoRecordingRequest(
|
|
952
951
|
val requestId: String,
|
|
953
952
|
val save: Boolean,
|
|
954
|
-
val flash: Boolean,
|
|
955
953
|
val sound: Boolean,
|
|
956
954
|
)
|
|
957
955
|
|
|
@@ -964,8 +962,8 @@ data class ButtonPressEvent(
|
|
|
964
962
|
data class TouchEvent(
|
|
965
963
|
val values: Map<String, Any>,
|
|
966
964
|
) {
|
|
967
|
-
val deviceModel: String? get() = stringValue(values, "
|
|
968
|
-
val gestureName: String? get() = stringValue(values, "
|
|
965
|
+
val deviceModel: String? get() = stringValue(values, "deviceModel")
|
|
966
|
+
val gestureName: String? get() = stringValue(values, "gestureName")
|
|
969
967
|
val timestamp: Long? get() = longValue(values, "timestamp")
|
|
970
968
|
val isSwipe: Boolean get() = gestureName?.contains("swipe", ignoreCase = true) == true
|
|
971
969
|
}
|
|
@@ -973,8 +971,8 @@ data class TouchEvent(
|
|
|
973
971
|
data class SwipeEvent(
|
|
974
972
|
val values: Map<String, Any>,
|
|
975
973
|
) {
|
|
976
|
-
val deviceModel: String? get() = stringValue(values, "
|
|
977
|
-
val gestureName: String? get() = stringValue(values, "
|
|
974
|
+
val deviceModel: String? get() = stringValue(values, "deviceModel")
|
|
975
|
+
val gestureName: String? get() = stringValue(values, "gestureName")
|
|
978
976
|
val timestamp: Long? get() = longValue(values, "timestamp")
|
|
979
977
|
}
|
|
980
978
|
|
|
@@ -1107,7 +1105,7 @@ sealed interface HotspotStatus {
|
|
|
1107
1105
|
enabled = enabled,
|
|
1108
1106
|
ssid = stringValue(values, "hotspotSsid"),
|
|
1109
1107
|
password = stringValue(values, "hotspotPassword"),
|
|
1110
|
-
localIp = stringValue(values, "hotspotGatewayIp"
|
|
1108
|
+
localIp = stringValue(values, "hotspotGatewayIp"),
|
|
1111
1109
|
)
|
|
1112
1110
|
}
|
|
1113
1111
|
|
|
@@ -1152,7 +1150,7 @@ data class HotspotStatusEvent(
|
|
|
1152
1150
|
data class HotspotErrorEvent(
|
|
1153
1151
|
val values: Map<String, Any>,
|
|
1154
1152
|
) {
|
|
1155
|
-
val message: String? get() = stringValue(values, "
|
|
1153
|
+
val message: String? get() = stringValue(values, "errorMessage")
|
|
1156
1154
|
val timestamp: Long? get() = longValue(values, "timestamp")
|
|
1157
1155
|
}
|
|
1158
1156
|
|
|
@@ -1170,7 +1168,7 @@ sealed interface PhotoResponse {
|
|
|
1170
1168
|
is Success -> mapOf(
|
|
1171
1169
|
"state" to state,
|
|
1172
1170
|
"requestId" to requestId,
|
|
1173
|
-
"
|
|
1171
|
+
"uploadUrl" to uploadUrl,
|
|
1174
1172
|
"timestamp" to timestamp,
|
|
1175
1173
|
)
|
|
1176
1174
|
|
|
@@ -1190,7 +1188,7 @@ sealed interface PhotoResponse {
|
|
|
1190
1188
|
|
|
1191
1189
|
data class Success(
|
|
1192
1190
|
override val requestId: String,
|
|
1193
|
-
val
|
|
1191
|
+
val uploadUrl: String,
|
|
1194
1192
|
override val timestamp: Long,
|
|
1195
1193
|
) : PhotoResponse {
|
|
1196
1194
|
override val state: String = "success"
|
|
@@ -1207,19 +1205,17 @@ sealed interface PhotoResponse {
|
|
|
1207
1205
|
|
|
1208
1206
|
companion object {
|
|
1209
1207
|
fun fromMap(values: Map<String, Any>): PhotoResponse {
|
|
1210
|
-
val requestId = stringValue(values, "requestId"
|
|
1208
|
+
val requestId = stringValue(values, "requestId").orEmpty()
|
|
1211
1209
|
val timestamp = longValue(values, "timestamp") ?: System.currentTimeMillis()
|
|
1212
|
-
val state = stringValue(values, "state"
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
Success(requestId = requestId, photoUrl = photoUrl, timestamp = timestamp)
|
|
1210
|
+
val state = stringValue(values, "state")?.lowercase()
|
|
1211
|
+
return if (state == "success") {
|
|
1212
|
+
val uploadUrl = stringValue(values, "uploadUrl").orEmpty()
|
|
1213
|
+
Success(requestId = requestId, uploadUrl = uploadUrl, timestamp = timestamp)
|
|
1217
1214
|
} else {
|
|
1218
1215
|
Error(
|
|
1219
1216
|
requestId = requestId,
|
|
1220
|
-
errorCode = stringValue(values, "errorCode"
|
|
1221
|
-
errorMessage = stringValue(values, "errorMessage"
|
|
1222
|
-
?: "Unknown photo error",
|
|
1217
|
+
errorCode = stringValue(values, "errorCode"),
|
|
1218
|
+
errorMessage = stringValue(values, "errorMessage") ?: "Unknown photo error",
|
|
1223
1219
|
timestamp = timestamp,
|
|
1224
1220
|
)
|
|
1225
1221
|
}
|
|
@@ -1369,10 +1365,10 @@ sealed interface StreamStatus {
|
|
|
1369
1365
|
val rawState = stringValue(values, "status")
|
|
1370
1366
|
val streaming = boolValue(values, "streaming")
|
|
1371
1367
|
val reconnecting = boolValue(values, "reconnecting") ?: false
|
|
1372
|
-
val streamId = stringValue(values, "streamId"
|
|
1368
|
+
val streamId = stringValue(values, "streamId")
|
|
1373
1369
|
val timestamp = longValue(values, "timestamp")
|
|
1374
1370
|
val attempt = numberValue(values, "attempt")
|
|
1375
|
-
val maxAttempts = numberValue(values, "maxAttempts"
|
|
1371
|
+
val maxAttempts = numberValue(values, "maxAttempts") ?: 0
|
|
1376
1372
|
|
|
1377
1373
|
if (streaming != null || hasAnyKey(values, "reconnecting")) {
|
|
1378
1374
|
return Snapshot(
|
|
@@ -1416,7 +1412,7 @@ sealed interface StreamStatus {
|
|
|
1416
1412
|
)
|
|
1417
1413
|
StreamState.ERROR -> Error(
|
|
1418
1414
|
streamId = streamId,
|
|
1419
|
-
errorDetails = stringValue(values, "errorDetails"
|
|
1415
|
+
errorDetails = stringValue(values, "errorDetails")
|
|
1420
1416
|
?: if (rawState == "error_not_streaming") "not_streaming" else "Unknown stream error",
|
|
1421
1417
|
timestamp = timestamp,
|
|
1422
1418
|
)
|
|
@@ -1446,8 +1442,8 @@ data class KeepAliveAckEvent(
|
|
|
1446
1442
|
val timestamp: Long?,
|
|
1447
1443
|
) {
|
|
1448
1444
|
constructor(values: Map<String, Any>) : this(
|
|
1449
|
-
streamId = stringValue(values, "streamId"
|
|
1450
|
-
ackId = stringValue(values, "ackId"
|
|
1445
|
+
streamId = stringValue(values, "streamId").orEmpty(),
|
|
1446
|
+
ackId = stringValue(values, "ackId").orEmpty(),
|
|
1451
1447
|
timestamp = longValue(values, "timestamp"),
|
|
1452
1448
|
)
|
|
1453
1449
|
|
|
@@ -1467,14 +1463,14 @@ data class LocalTranscriptionEvent(
|
|
|
1467
1463
|
)
|
|
1468
1464
|
|
|
1469
1465
|
data class GlassesMediaVolumeGetResult(
|
|
1470
|
-
val
|
|
1466
|
+
val level: Int?,
|
|
1471
1467
|
val statusCode: Int?,
|
|
1472
1468
|
val values: Map<String, Any>,
|
|
1473
1469
|
) {
|
|
1474
1470
|
companion object {
|
|
1475
1471
|
fun fromMap(values: Map<String, Any>): GlassesMediaVolumeGetResult =
|
|
1476
1472
|
GlassesMediaVolumeGetResult(
|
|
1477
|
-
|
|
1473
|
+
level = numberValue(values, "level"),
|
|
1478
1474
|
statusCode = (values["statusCode"] as? Number)?.toInt(),
|
|
1479
1475
|
values = values,
|
|
1480
1476
|
)
|
|
@@ -1544,6 +1540,31 @@ enum class ScanStopReason {
|
|
|
1544
1540
|
ERROR,
|
|
1545
1541
|
}
|
|
1546
1542
|
|
|
1543
|
+
interface ScanCallback {
|
|
1544
|
+
fun onResults(devices: List<Device>) {}
|
|
1545
|
+
fun onComplete(devices: List<Device>) {}
|
|
1546
|
+
fun onError(error: BluetoothError) {}
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
abstract class MentraBluetoothScanCallback : ScanCallback
|
|
1550
|
+
|
|
1551
|
+
class ScanSession internal constructor(
|
|
1552
|
+
private val stopAction: () -> Unit,
|
|
1553
|
+
) {
|
|
1554
|
+
@Volatile
|
|
1555
|
+
private var stopped = false
|
|
1556
|
+
|
|
1557
|
+
fun stop() {
|
|
1558
|
+
if (stopped) return
|
|
1559
|
+
stopped = true
|
|
1560
|
+
stopAction()
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
internal fun markStopped() {
|
|
1564
|
+
stopped = true
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1547
1568
|
interface MentraBluetoothSdkListener {
|
|
1548
1569
|
fun onGlassesStatusChanged(status: GlassesStatusUpdate) {}
|
|
1549
1570
|
fun onBluetoothStatusChanged(status: BluetoothStatusUpdate) {}
|
|
@@ -1572,12 +1593,6 @@ interface MentraBluetoothSdkListener {
|
|
|
1572
1593
|
|
|
1573
1594
|
abstract class MentraBluetoothSdkCallback : MentraBluetoothSdkListener
|
|
1574
1595
|
|
|
1575
|
-
private fun numberValue(
|
|
1576
|
-
values: Map<*, *>,
|
|
1577
|
-
fullKey: String,
|
|
1578
|
-
compactKey: String,
|
|
1579
|
-
): Int? = ((values[fullKey] ?: values[compactKey]) as? Number)?.toInt()
|
|
1580
|
-
|
|
1581
1596
|
private fun numberValue(
|
|
1582
1597
|
values: Map<String, Any>,
|
|
1583
1598
|
vararg keys: String,
|