@mentra/bluetooth-sdk 0.1.5 → 0.1.6
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 +29 -13
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +15 -7
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +1 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +34 -46
- package/android/src/main/java/com/mentra/bluetoothsdk/audio/AudioModels.kt +125 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +187 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/connection/ConnectionModels.kt +78 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +60 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/internal/MapParsing.kt +132 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/requests/DisplayRequests.kt +39 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +605 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/status/RuntimeState.kt +199 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/status/WifiHotspotStatus.kt +173 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +348 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +75 -0
- package/build/BluetoothSdk.types.d.ts +4 -0
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +3 -0
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +4 -4
- package/ios/Source/Audio/AudioModels.swift +159 -0
- package/ios/Source/Camera/CameraModels.swift +246 -0
- package/ios/Source/Connection/ScanSession.swift +27 -0
- package/ios/Source/DeviceStore.swift +1 -0
- package/ios/Source/Errors/BluetoothError.swift +19 -0
- package/ios/Source/Events/BluetoothEvents.swift +115 -0
- package/ios/Source/Internal/BluetoothAvailability.swift +58 -0
- package/ios/Source/Internal/ValueParsing.swift +90 -0
- package/ios/Source/MentraBluetoothSDK.swift +25 -2140
- package/ios/Source/Requests/DisplayRequests.swift +58 -0
- package/ios/Source/Status/DeviceStatus.swift +463 -0
- package/ios/Source/Status/RuntimeState.swift +350 -0
- package/ios/Source/Status/WifiHotspotStatus.swift +326 -0
- package/ios/Source/Streaming/StreamModels.swift +436 -0
- package/ios/Source/Types/DeviceModels.swift +134 -0
- package/ios/Source/sgcs/G2.swift +97 -36
- package/package.json +1 -1
- package/src/BluetoothSdk.types.ts +4 -0
- package/src/_private/BluetoothSdkModule.ts +3 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +0 -1810
package/ios/Source/sgcs/G2.swift
CHANGED
|
@@ -1062,6 +1062,8 @@ class G2: NSObject, SGCManager {
|
|
|
1062
1062
|
private var rightAuthenticated: Bool = false
|
|
1063
1063
|
private var isDisconnecting = false
|
|
1064
1064
|
private var pairingTimeoutTimer: DispatchWorkItem?
|
|
1065
|
+
private var useEvenDashboard = true
|
|
1066
|
+
private var dashboardShowing = 0
|
|
1065
1067
|
|
|
1066
1068
|
/// Device search
|
|
1067
1069
|
var DEVICE_SEARCH_ID = "NOT_SET"
|
|
@@ -1598,11 +1600,11 @@ class G2: NSObject, SGCManager {
|
|
|
1598
1600
|
func sendTextWall(_ text: String) {
|
|
1599
1601
|
// Bridge.log("G2: sendTextWall(\(text.prefix(50))...)")
|
|
1600
1602
|
|
|
1601
|
-
// ignore events while the dashboard is open:
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1603
|
+
// ignore events while the ER dashboard is open:
|
|
1604
|
+
let useNativeDashboard = DeviceStore.shared.get("bluetooth", "use_native_dashboard") as? Bool ?? false
|
|
1605
|
+
if useNativeDashboard && dashboardShowing > 0 {
|
|
1606
|
+
return
|
|
1607
|
+
}
|
|
1606
1608
|
|
|
1607
1609
|
if text.isEmpty {
|
|
1608
1610
|
clearDisplay()
|
|
@@ -2191,8 +2193,24 @@ class G2: NSObject, SGCManager {
|
|
|
2191
2193
|
return bmp
|
|
2192
2194
|
}
|
|
2193
2195
|
|
|
2196
|
+
/// Bring the Even Realities dashboard (the OS-level home/idle screen) to
|
|
2197
|
+
/// the foreground by tearing down whatever EvenHub page we currently own.
|
|
2198
|
+
/// The glasses fall back to the dashboard automatically when no page is up.
|
|
2194
2199
|
func showDashboard() {
|
|
2195
|
-
|
|
2200
|
+
Bridge.log("G2: showDashboard")
|
|
2201
|
+
dashboardShowing += 2
|
|
2202
|
+
let msg = EvenHubProto.shutdownMessage()
|
|
2203
|
+
sendEvenHubCommand(msg)
|
|
2204
|
+
pageCreated = false
|
|
2205
|
+
pageHasTextContainer = false
|
|
2206
|
+
currentTextContent = ""
|
|
2207
|
+
currentBitmapBase64 = ""
|
|
2208
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
|
|
2209
|
+
guard let self = self else { return }
|
|
2210
|
+
// activate the dashboard by setting dept to the current setting:
|
|
2211
|
+
let currentDepth = DeviceStore.shared.get("bluetooth", "dashboard_depth") as? Int ?? 0
|
|
2212
|
+
self.setDashboardDepthOnly(currentDepth)
|
|
2213
|
+
}
|
|
2196
2214
|
}
|
|
2197
2215
|
|
|
2198
2216
|
func setDashboardPosition(_ height: Int, _ depth: Int) {
|
|
@@ -2302,21 +2320,33 @@ class G2: NSObject, SGCManager {
|
|
|
2302
2320
|
sendEvenHubCommand(toSend)
|
|
2303
2321
|
}
|
|
2304
2322
|
|
|
2323
|
+
func restartMic() {
|
|
2324
|
+
// if already enabled, set to disabled, then send enabled after 500ms:
|
|
2325
|
+
DeviceStore.shared.apply("glasses", "micEnabled", true)
|
|
2326
|
+
let msg = EvenHubProto.audioControlMessage(enable: false)
|
|
2327
|
+
sendEvenHubCommand(msg)
|
|
2328
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
|
|
2329
|
+
guard let self = self else { return }
|
|
2330
|
+
let useNativeDashboard = DeviceStore.shared.get("bluetooth", "use_native_dashboard") as? Bool ?? false
|
|
2331
|
+
Bridge.log("G2: setMicEnabled - useNativeDashboard=\(useNativeDashboard), dashboardShowing=\(dashboardShowing)")
|
|
2332
|
+
if useNativeDashboard && dashboardShowing > 0 {
|
|
2333
|
+
return
|
|
2334
|
+
}
|
|
2335
|
+
if (!pageCreated || !pageHasTextContainer) {
|
|
2336
|
+
DeviceManager.shared.sendCurrentState()// should re-create the page if needed
|
|
2337
|
+
}
|
|
2338
|
+
let msg = EvenHubProto.audioControlMessage(enable: true)
|
|
2339
|
+
self.sendEvenHubCommand(msg)
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2305
2343
|
// MARK: - SGCManager: Audio Control
|
|
2306
2344
|
|
|
2307
2345
|
func setMicEnabled(_ enabled: Bool) {
|
|
2308
2346
|
Bridge.log("G2: setMicEnabled(\(enabled))")
|
|
2309
2347
|
let currentEnabled = DeviceStore.shared.get("glasses", "micEnabled") as? Bool ?? false
|
|
2310
2348
|
if currentEnabled && enabled {
|
|
2311
|
-
|
|
2312
|
-
DeviceStore.shared.apply("glasses", "micEnabled", true)
|
|
2313
|
-
let msg = EvenHubProto.audioControlMessage(enable: false)
|
|
2314
|
-
sendEvenHubCommand(msg)
|
|
2315
|
-
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
|
|
2316
|
-
guard let self = self else { return }
|
|
2317
|
-
let msg = EvenHubProto.audioControlMessage(enable: true)
|
|
2318
|
-
self.sendEvenHubCommand(msg)
|
|
2319
|
-
}
|
|
2349
|
+
restartMic()
|
|
2320
2350
|
return
|
|
2321
2351
|
}
|
|
2322
2352
|
|
|
@@ -2505,7 +2535,8 @@ class G2: NSObject, SGCManager {
|
|
|
2505
2535
|
// }
|
|
2506
2536
|
|
|
2507
2537
|
// connectController("1B:08:26:8E:0E:E6")
|
|
2508
|
-
connectController()
|
|
2538
|
+
// connectController()
|
|
2539
|
+
showDashboard()
|
|
2509
2540
|
}
|
|
2510
2541
|
|
|
2511
2542
|
func dbg2() {
|
|
@@ -2532,6 +2563,8 @@ class G2: NSObject, SGCManager {
|
|
|
2532
2563
|
// // update the text
|
|
2533
2564
|
// Bridge.log("G2: sendTextWall() - updating text container")
|
|
2534
2565
|
// updateText("test2")
|
|
2566
|
+
let currentDepth = DeviceStore.shared.get("bluetooth", "dashboard_depth") as? Int ?? 0
|
|
2567
|
+
setDashboardDepthOnly(currentDepth)
|
|
2535
2568
|
}
|
|
2536
2569
|
|
|
2537
2570
|
// MARK: - SGCManager: Device Control
|
|
@@ -3021,15 +3054,22 @@ class G2: NSObject, SGCManager {
|
|
|
3021
3054
|
if eventType == .doubleClick {
|
|
3022
3055
|
// trigger dashboard:
|
|
3023
3056
|
let isHeadUp = DeviceStore.shared.get("glasses", "headUp") as? Bool ?? false
|
|
3024
|
-
|
|
3025
|
-
DeviceStore.shared.
|
|
3026
|
-
if
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
}
|
|
3057
|
+
|
|
3058
|
+
let useNativeDashboard = DeviceStore.shared.get("bluetooth", "use_native_dashboard") as? Bool ?? false
|
|
3059
|
+
if useNativeDashboard {
|
|
3060
|
+
showDashboard()
|
|
3061
|
+
} else {
|
|
3062
|
+
// toggle head up:
|
|
3063
|
+
DeviceStore.shared.apply("glasses", "headUp", !isHeadUp)
|
|
3032
3064
|
}
|
|
3065
|
+
|
|
3066
|
+
// if isHeadUp {
|
|
3067
|
+
// // Bridge.log("G2: going back to home, clearing display")
|
|
3068
|
+
// // clear the display after a delay:
|
|
3069
|
+
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
|
3070
|
+
// self.clearDisplay()
|
|
3071
|
+
// }
|
|
3072
|
+
// }
|
|
3033
3073
|
// sendDashboardCommand(DashboardCommand.trigger)
|
|
3034
3074
|
|
|
3035
3075
|
// toggle head up:
|
|
@@ -3373,18 +3413,39 @@ class G2: NSObject, SGCManager {
|
|
|
3373
3413
|
// if we got 08011A00 that means we closed the dashboard, which means the mic is probably dead,
|
|
3374
3414
|
// so we need to revive it:
|
|
3375
3415
|
if data == Data([0x08, 0x01, 0x1A, 0x00]) {
|
|
3376
|
-
Bridge.log("G2:
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3416
|
+
Bridge.log("G2: dashboard closed / shutdown - dashboardShowing=\(dashboardShowing)")
|
|
3417
|
+
let useNativeDashboard = DeviceStore.shared.get("bluetooth", "use_native_dashboard") as? Bool ?? false
|
|
3418
|
+
if !useNativeDashboard {
|
|
3419
|
+
// make sure the container exists:
|
|
3420
|
+
DeviceManager.shared.sendCurrentState()
|
|
3421
|
+
// re-send mic on / if it's enabled:
|
|
3422
|
+
let micEnabled = DeviceStore.shared.get("glasses", "micEnabled") as? Bool ?? false
|
|
3423
|
+
if micEnabled {
|
|
3424
|
+
restartMic()
|
|
3425
|
+
}
|
|
3426
|
+
// reset the text container (different from clearDisplay())
|
|
3427
|
+
// sendTextWall(" ")
|
|
3428
|
+
// createPageWithText(" ")
|
|
3429
|
+
} else {
|
|
3430
|
+
// if we aren't trying to show the dashboard
|
|
3431
|
+
// then we need to turn the mic back on and display the mentra main page:
|
|
3432
|
+
if dashboardShowing <= 1 {
|
|
3433
|
+
dashboardShowing = 0
|
|
3434
|
+
// make sure the container exists:
|
|
3435
|
+
DeviceManager.shared.sendCurrentState()
|
|
3436
|
+
// set the mic back on if it should be on
|
|
3437
|
+
let micEnabled = DeviceStore.shared.get("glasses", "micEnabled") as? Bool ?? false
|
|
3438
|
+
if micEnabled {
|
|
3439
|
+
restartMic()
|
|
3440
|
+
}
|
|
3441
|
+
return
|
|
3442
|
+
}
|
|
3443
|
+
// do nothing this time since we just closed the dashboard
|
|
3444
|
+
dashboardShowing -= 1
|
|
3445
|
+
if (dashboardShowing < 0) {
|
|
3446
|
+
dashboardShowing = 0
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3388
3449
|
}
|
|
3389
3450
|
|
|
3390
3451
|
// if we got 08011097012200 that means we selected a menu item:
|
package/package.json
CHANGED
|
@@ -728,6 +728,10 @@ export interface Device {
|
|
|
728
728
|
name: string
|
|
729
729
|
/** Platform address/identifier when available: Android Bluetooth address, iOS CoreBluetooth identifier. */
|
|
730
730
|
address?: string
|
|
731
|
+
/**
|
|
732
|
+
* Optional scan signal strength. It may be undefined at first discovery and
|
|
733
|
+
* appear in a later scan update when the platform reports RSSI metadata.
|
|
734
|
+
*/
|
|
731
735
|
rssi?: number
|
|
732
736
|
}
|
|
733
737
|
|
|
@@ -466,6 +466,9 @@ NativeBluetoothSdkModule.scan = async function (
|
|
|
466
466
|
}
|
|
467
467
|
|
|
468
468
|
const handleBluetoothStatus = (status: Partial<BluetoothStatus>) => {
|
|
469
|
+
if (!Array.isArray(status.searchResults)) {
|
|
470
|
+
return
|
|
471
|
+
}
|
|
469
472
|
emitResults(searchResultsForModel(status, scanOptions.model))
|
|
470
473
|
}
|
|
471
474
|
|