@mentra/bluetooth-sdk 0.1.14 → 0.1.16
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 +4 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +22 -9
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +5 -20
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +358 -261
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +3 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +133 -52
- package/android/src/main/java/com/mentra/bluetoothsdk/OtaManifest.kt +12 -12
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +22 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +1 -22
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.kt +50 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +1184 -795
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +422 -78
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +3 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Nimo.kt +2532 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +15 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +5 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +2 -1
- package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +60 -1
- package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoProtocolTest.kt +333 -0
- package/build/BluetoothSdk.types.d.ts +39 -14
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js +1 -0
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_internal.d.ts +4 -4
- package/build/_internal.js +4 -4
- package/build/_internal.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +11 -3
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +5 -0
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/_private/cameraRequestPayload.d.ts +4 -0
- package/build/_private/cameraRequestPayload.d.ts.map +1 -0
- package/build/_private/cameraRequestPayload.js +25 -0
- package/build/_private/cameraRequestPayload.js.map +1 -0
- package/build/_private/photoRequestPayload.d.ts.map +1 -1
- package/build/_private/photoRequestPayload.js +8 -2
- package/build/_private/photoRequestPayload.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +72 -54
- package/build/index.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +40 -12
- package/ios/Source/Bridge.swift +4 -16
- package/ios/Source/DeviceManager.swift +72 -12
- package/ios/Source/MentraBluetoothSDK.swift +120 -50
- package/ios/Source/OtaManifest.swift +13 -13
- package/ios/Source/camera/CameraModels.swift +75 -9
- package/ios/Source/errors/{BluetoothError.swift → BluetoothSdkError.swift} +1 -1
- package/ios/Source/events/BluetoothEvents.swift +5 -27
- package/ios/Source/internal/BluetoothAvailability.swift +5 -5
- package/ios/Source/sgcs/G1.swift +51 -1
- package/ios/Source/sgcs/G2.swift +643 -203
- package/ios/Source/sgcs/MentraLive.swift +53 -39
- package/ios/Source/sgcs/Nimo.swift +1928 -0
- package/ios/Source/sgcs/SGCManager.swift +12 -5
- package/ios/Source/stt/STTTools.swift +1 -1
- package/ios/Source/types/DeviceModels.swift +5 -0
- package/ios/Source/utils/Constants.swift +2 -0
- package/package.json +6 -1
- package/src/BluetoothSdk.types.ts +42 -17
- package/src/_internal.ts +4 -4
- package/src/_private/BluetoothSdkModule.ts +18 -2
- package/src/_private/cameraRequestPayload.ts +29 -0
- package/src/_private/photoRequestPayload.ts +9 -2
- package/src/index.ts +76 -58
|
@@ -56,6 +56,12 @@ protocol SGCManager {
|
|
|
56
56
|
/// Display a bitmap. Optional `x`/`y`/`width`/`height` position and size the target
|
|
57
57
|
/// container (used by G2; other SGCs ignore positioning and render the bitmap as before).
|
|
58
58
|
func displayBitmap(base64ImageData: String, x: Int32?, y: Int32?, width: Int32?, height: Int32?) async -> Bool
|
|
59
|
+
/// Show text in a positioned container with an optional rounded border.
|
|
60
|
+
/// G2-only capability; default no-op (see protocol extension) so other glasses ignore it.
|
|
61
|
+
func sendPositionedText(
|
|
62
|
+
_ text: String, x: Int32, y: Int32, width: Int32, height: Int32,
|
|
63
|
+
borderWidth: Int32, borderRadius: Int32
|
|
64
|
+
) async
|
|
59
65
|
func showDashboard()
|
|
60
66
|
func setDashboardPosition(_ height: Int, _ depth: Int)
|
|
61
67
|
/// Default implementation sends both via [setDashboardPosition]; Nex overrides to one protobuf.
|
|
@@ -118,7 +124,6 @@ protocol SGCManager {
|
|
|
118
124
|
func sendOtaStart(otaVersionUrl: String?)
|
|
119
125
|
func sendOtaQueryStatus()
|
|
120
126
|
func sendSetSystemTime(_ timestampMs: Int64)
|
|
121
|
-
func sendOtaRetryVersionCheck()
|
|
122
127
|
|
|
123
128
|
// MARK: - User Context (for crash reporting)
|
|
124
129
|
|
|
@@ -145,6 +150,12 @@ protocol SGCManager {
|
|
|
145
150
|
/// doesn't seem to work for concurrency reasons :(
|
|
146
151
|
/// we can make read-only getters for convienence though:
|
|
147
152
|
extension SGCManager {
|
|
153
|
+
/// Default: no-op. Only G2 renders positioned text containers; other glasses ignore it.
|
|
154
|
+
func sendPositionedText(
|
|
155
|
+
_: String, x _: Int32, y _: Int32, width _: Int32, height _: Int32,
|
|
156
|
+
borderWidth _: Int32, borderRadius _: Int32
|
|
157
|
+
) async {}
|
|
158
|
+
|
|
148
159
|
// MARK: - Video recording (default: ignore custom settings, use saved defaults)
|
|
149
160
|
|
|
150
161
|
func startVideoRecording(
|
|
@@ -201,10 +212,6 @@ extension SGCManager {
|
|
|
201
212
|
Bridge.log("SGC: sendSetSystemTime not supported")
|
|
202
213
|
}
|
|
203
214
|
|
|
204
|
-
func sendOtaRetryVersionCheck() {
|
|
205
|
-
Bridge.log("SGC: sendOtaRetryVersionCheck not supported")
|
|
206
|
-
}
|
|
207
|
-
|
|
208
215
|
// MARK: - Default DeviceStore-backed property implementations
|
|
209
216
|
|
|
210
217
|
var fullyBooted: Bool {
|
|
@@ -7,7 +7,7 @@ class STTTools {
|
|
|
7
7
|
// Send partial result to server witgetConnectedBluetoothNameh proper formatting
|
|
8
8
|
let transcriptionLanguage =
|
|
9
9
|
UserDefaults.standard.string(forKey: "STTModelLanguageCode") ?? "en-US"
|
|
10
|
-
Bridge.log("Mentra: Sending partial transcription: \(text), \(transcriptionLanguage)")
|
|
10
|
+
// Bridge.log("Mentra: Sending partial transcription: \(text), \(transcriptionLanguage)")
|
|
11
11
|
let transcription: [String: Any] = [
|
|
12
12
|
"type": "local_transcription",
|
|
13
13
|
"text": transcriptionLanguage == "en-US" ? text.lowercased() : text,
|
|
@@ -18,6 +18,7 @@ public enum DeviceModel: String {
|
|
|
18
18
|
case mach1
|
|
19
19
|
case z100
|
|
20
20
|
case frame
|
|
21
|
+
case nimo
|
|
21
22
|
case simulated
|
|
22
23
|
case r1
|
|
23
24
|
|
|
@@ -37,6 +38,8 @@ public enum DeviceModel: String {
|
|
|
37
38
|
DeviceTypes.Z100
|
|
38
39
|
case .frame:
|
|
39
40
|
DeviceTypes.FRAME
|
|
41
|
+
case .nimo:
|
|
42
|
+
DeviceTypes.NIMO
|
|
40
43
|
case .simulated:
|
|
41
44
|
DeviceTypes.SIMULATED
|
|
42
45
|
case .r1:
|
|
@@ -60,6 +63,8 @@ public enum DeviceModel: String {
|
|
|
60
63
|
.z100
|
|
61
64
|
case DeviceTypes.FRAME:
|
|
62
65
|
.frame
|
|
66
|
+
case DeviceTypes.NIMO:
|
|
67
|
+
.nimo
|
|
63
68
|
case DeviceTypes.SIMULATED:
|
|
64
69
|
.simulated
|
|
65
70
|
case ControllerTypes.R1:
|
|
@@ -7,6 +7,7 @@ struct DeviceTypes {
|
|
|
7
7
|
static let Z100 = "Vuzix Z100"
|
|
8
8
|
static let NEX = "Mentra Display"
|
|
9
9
|
static let FRAME = "Brilliant Frame"
|
|
10
|
+
static let NIMO = "NIMO"
|
|
10
11
|
|
|
11
12
|
static let ALL = [
|
|
12
13
|
SIMULATED,
|
|
@@ -17,6 +18,7 @@ struct DeviceTypes {
|
|
|
17
18
|
Z100,
|
|
18
19
|
NEX,
|
|
19
20
|
FRAME,
|
|
21
|
+
NIMO,
|
|
20
22
|
]
|
|
21
23
|
|
|
22
24
|
/// Private init to prevent instantiation
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mentra/bluetooth-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "SDK for communicating with smart glasses",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"react-native": "./src/index.ts",
|
|
13
13
|
"default": "./build/index.js"
|
|
14
14
|
},
|
|
15
|
+
"./internal": {
|
|
16
|
+
"types": "./build/_internal.d.ts",
|
|
17
|
+
"react-native": "./src/_internal.ts",
|
|
18
|
+
"default": "./build/_internal.js"
|
|
19
|
+
},
|
|
15
20
|
"./react": {
|
|
16
21
|
"types": "./build/react/index.d.ts",
|
|
17
22
|
"react-native": "./src/react/index.ts",
|
|
@@ -270,6 +270,15 @@ export type PhotoStatusEvent = {
|
|
|
270
270
|
errorMessage?: string
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
export type CameraStatusEvent = {
|
|
274
|
+
type: "camera_status"
|
|
275
|
+
requestId: string
|
|
276
|
+
state: "warming" | "ready" | "stopped" | "error" | string
|
|
277
|
+
timestamp: number
|
|
278
|
+
errorCode?: string
|
|
279
|
+
errorMessage?: string
|
|
280
|
+
}
|
|
281
|
+
|
|
273
282
|
export type VideoRecordingStatusEvent = {
|
|
274
283
|
type: "video_recording_status"
|
|
275
284
|
requestId?: string
|
|
@@ -310,9 +319,7 @@ export type VideoRecordingStoppedStatusEvent = Omit<VideoRecordingStatusEvent, "
|
|
|
310
319
|
status: "recording_stopped"
|
|
311
320
|
}
|
|
312
321
|
|
|
313
|
-
export type VideoRecordingSuccessStatusEvent =
|
|
314
|
-
| VideoRecordingStartedStatusEvent
|
|
315
|
-
| VideoRecordingStoppedStatusEvent
|
|
322
|
+
export type VideoRecordingSuccessStatusEvent = VideoRecordingStartedStatusEvent | VideoRecordingStoppedStatusEvent
|
|
316
323
|
|
|
317
324
|
export type MediaUploadSuccessEvent = {
|
|
318
325
|
type: "media_success"
|
|
@@ -398,6 +405,7 @@ export type SettingsAckSetting =
|
|
|
398
405
|
| "button_video_recording"
|
|
399
406
|
| "button_max_recording_time"
|
|
400
407
|
| "camera_fov"
|
|
408
|
+
| "camera_tuning"
|
|
401
409
|
|
|
402
410
|
export type SettingsAckEvent = {
|
|
403
411
|
type: "settings_ack"
|
|
@@ -415,6 +423,10 @@ export type SettingsAckEvent = {
|
|
|
415
423
|
fps?: number
|
|
416
424
|
enabled?: boolean
|
|
417
425
|
minutes?: number
|
|
426
|
+
/** ANR enabled flag; present when setting === "camera_tuning" */
|
|
427
|
+
anr?: boolean
|
|
428
|
+
/** Stock-gain flag; present when setting === "camera_tuning" */
|
|
429
|
+
gain?: boolean
|
|
418
430
|
errorCode?: string
|
|
419
431
|
errorMessage?: string
|
|
420
432
|
}
|
|
@@ -478,6 +490,7 @@ export const DeviceModels = {
|
|
|
478
490
|
Mach1: "Mentra Mach1",
|
|
479
491
|
Z100: "Vuzix Z100",
|
|
480
492
|
Frame: "Brilliant Frame",
|
|
493
|
+
Nimo: "NIMO",
|
|
481
494
|
R1: "Even Realities R1",
|
|
482
495
|
} as const
|
|
483
496
|
|
|
@@ -528,8 +541,7 @@ export type MicPreference = "auto" | "phone" | "glasses" | "bluetooth"
|
|
|
528
541
|
export type MicMode = "phone" | "glasses" | "bluetoothClassic" | "bluetooth"
|
|
529
542
|
|
|
530
543
|
export type PhotoRequestParams = {
|
|
531
|
-
requestId
|
|
532
|
-
appId: string
|
|
544
|
+
requestId?: string
|
|
533
545
|
size: PhotoSize
|
|
534
546
|
webhookUrl: string | null
|
|
535
547
|
authToken: string | null
|
|
@@ -552,6 +564,13 @@ export type PhotoRequestParams = {
|
|
|
552
564
|
ispAnalogGain?: string
|
|
553
565
|
}
|
|
554
566
|
|
|
567
|
+
export type WarmUpCameraParams = {
|
|
568
|
+
requestId?: string
|
|
569
|
+
size: PhotoSize
|
|
570
|
+
exposureTimeNs?: number | null
|
|
571
|
+
durationMs?: number
|
|
572
|
+
}
|
|
573
|
+
|
|
555
574
|
export type StreamVideoConfig = {
|
|
556
575
|
width?: number
|
|
557
576
|
height?: number
|
|
@@ -725,15 +744,6 @@ export type MtkUpdateCompleteEvent = {
|
|
|
725
744
|
timestamp: number
|
|
726
745
|
}
|
|
727
746
|
|
|
728
|
-
export type OtaUpdateAvailableEvent = {
|
|
729
|
-
type: "ota_update_available"
|
|
730
|
-
version_code?: number
|
|
731
|
-
version_name?: string
|
|
732
|
-
updates?: string[]
|
|
733
|
-
total_size?: number
|
|
734
|
-
cache_ready?: boolean
|
|
735
|
-
}
|
|
736
|
-
|
|
737
747
|
/** @deprecated Glasses no longer emit ota_progress; use {@link OtaStatusEvent} and status-store mapping. */
|
|
738
748
|
export type OtaProgressEvent = {
|
|
739
749
|
type: "ota_progress"
|
|
@@ -764,7 +774,7 @@ export type OtaStatusEvent = {
|
|
|
764
774
|
error_message?: string
|
|
765
775
|
}
|
|
766
776
|
|
|
767
|
-
export type OtaQueryResult =
|
|
777
|
+
export type OtaQueryResult = OtaStatusEvent
|
|
768
778
|
|
|
769
779
|
/** Nex BLE protobuf trace (NexEventUtils); payload matches native Map keys. */
|
|
770
780
|
export type BleCommandTraceEvent = {
|
|
@@ -803,6 +813,7 @@ export type BluetoothSdkModuleEvents = {
|
|
|
803
813
|
hotspot_error: (event: HotspotErrorEvent) => void
|
|
804
814
|
photo_response: (event: PhotoResponseEvent) => void
|
|
805
815
|
photo_status: (event: PhotoStatusEvent) => void
|
|
816
|
+
camera_status: (event: CameraStatusEvent) => void
|
|
806
817
|
video_recording_status: (event: VideoRecordingStatusEvent) => void
|
|
807
818
|
media_success: (event: MediaUploadSuccessEvent) => void
|
|
808
819
|
media_error: (event: MediaUploadErrorEvent) => void
|
|
@@ -826,7 +837,6 @@ export type BluetoothSdkModuleEvents = {
|
|
|
826
837
|
stream_status: (event: StreamStatusEvent) => void
|
|
827
838
|
keep_alive_ack: (event: KeepAliveAckEvent) => void
|
|
828
839
|
mtk_update_complete: (event: MtkUpdateCompleteEvent) => void
|
|
829
|
-
ota_update_available: (event: OtaUpdateAvailableEvent) => void
|
|
830
840
|
ota_start_ack: (event: OtaStartAckEvent) => void
|
|
831
841
|
ota_status: (event: OtaStatusEvent) => void
|
|
832
842
|
version_info: (event: VersionInfoEvent) => void
|
|
@@ -880,6 +890,7 @@ export type BluetoothSdkEventMap = {
|
|
|
880
890
|
hotspot_error: HotspotErrorEvent
|
|
881
891
|
photo_response: PhotoResponseEvent
|
|
882
892
|
photo_status: PhotoStatusEvent
|
|
893
|
+
camera_status: CameraStatusEvent
|
|
883
894
|
video_recording_status: VideoRecordingStatusEvent
|
|
884
895
|
media_success: MediaUploadSuccessEvent
|
|
885
896
|
media_error: MediaUploadErrorEvent
|
|
@@ -953,8 +964,23 @@ export interface BluetoothSdkPublicModule {
|
|
|
953
964
|
setVideoRecordingDefaults(settings: VideoRecordingDefaults): Promise<SettingsAckSuccessEvent>
|
|
954
965
|
setMaxVideoRecordingDuration(minutes: number): Promise<SettingsAckSuccessEvent>
|
|
955
966
|
setCameraFov(request: CameraFovRequest): Promise<CameraFovResult>
|
|
967
|
+
/**
|
|
968
|
+
* Configure camera HAL tuning (ANR / gain) on Mentra Live glasses.
|
|
969
|
+
*
|
|
970
|
+
* The phone sends a {@code camera_tuning_config} BLE command; the glasses relay it as a
|
|
971
|
+
* {@code camconfig} broadcast to the camera HAL so parameters take effect without a reboot.
|
|
972
|
+
*
|
|
973
|
+
* **Scan-mode convention**: call with `(false, false)` when activating scan mode to disable ANR
|
|
974
|
+
* and pixsmart gain for sharper text/barcode captures. Call with `(true, true)` to restore
|
|
975
|
+
* defaults when exiting scan mode.
|
|
976
|
+
*
|
|
977
|
+
* @param anrOn `true` = ANR enabled (default), `false` = ANR disabled
|
|
978
|
+
* @param gainOn `true` = stock gain params (default), `false` = pixsmart gain-off params
|
|
979
|
+
*/
|
|
980
|
+
setCameraTuningConfig(anrOn: boolean, gainOn: boolean): Promise<SettingsAckSuccessEvent>
|
|
956
981
|
queryGalleryStatus(): Promise<GalleryStatusEvent>
|
|
957
982
|
requestPhoto(params: PhotoRequestParams): Promise<PhotoSuccessResponseEvent>
|
|
983
|
+
warmUpCamera(params: WarmUpCameraParams): Promise<CameraStatusEvent>
|
|
958
984
|
startVideoRecording(
|
|
959
985
|
requestId: string,
|
|
960
986
|
save: boolean,
|
|
@@ -1059,7 +1085,6 @@ export interface OtaUpdateInfo {
|
|
|
1059
1085
|
versionName: string
|
|
1060
1086
|
updates: string[] // ["apk", "mtk", "bes"]
|
|
1061
1087
|
totalSize: number
|
|
1062
|
-
cacheReady?: boolean
|
|
1063
1088
|
}
|
|
1064
1089
|
|
|
1065
1090
|
export interface OtaProgress {
|
package/src/_internal.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MentraOS-only compatibility entrypoint.
|
|
3
3
|
*
|
|
4
|
-
* Apps should import from `@mentra/bluetooth-sdk`. This
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Apps should import from `@mentra/bluetooth-sdk`. This is exported as
|
|
5
|
+
* `@mentra/bluetooth-sdk/internal` only for MentraOS packages that still need
|
|
6
|
+
* the compatibility surface while the app is migrated onto the public SDK
|
|
7
|
+
* surface.
|
|
8
8
|
*/
|
|
9
9
|
export {default} from "./_private/BluetoothSdkModule"
|
|
10
10
|
export type {BluetoothSdkInternalModule} from "./_private/BluetoothSdkModule"
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
CameraFovResult,
|
|
15
15
|
CameraFovSetting,
|
|
16
16
|
CameraRoiPosition,
|
|
17
|
+
CameraStatusEvent,
|
|
17
18
|
ConnectOptions,
|
|
18
19
|
DashboardMenuItem,
|
|
19
20
|
Device,
|
|
@@ -43,9 +44,11 @@ import {
|
|
|
43
44
|
VideoRecordingSettings,
|
|
44
45
|
VideoRecordingStoppedStatusEvent,
|
|
45
46
|
VersionInfoResult,
|
|
47
|
+
WarmUpCameraParams,
|
|
46
48
|
WifiSearchResult,
|
|
47
49
|
WifiStatusChangeEvent,
|
|
48
50
|
} from "../BluetoothSdk.types"
|
|
51
|
+
import {warmUpCameraParamsForNative} from "./cameraRequestPayload"
|
|
49
52
|
import {photoRequestParamsForNative} from "./photoRequestPayload"
|
|
50
53
|
|
|
51
54
|
/**
|
|
@@ -125,8 +128,18 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
|
|
|
125
128
|
setVideoRecordingDefaults(width: number, height: number, fps: number): Promise<SettingsAckSuccessEvent>
|
|
126
129
|
setMaxVideoRecordingDuration(minutes: number): Promise<SettingsAckSuccessEvent>
|
|
127
130
|
setCameraFov(request: CameraFovRequest): Promise<CameraFovResult>
|
|
131
|
+
/**
|
|
132
|
+
* Configure camera HAL tuning (ANR / gain) on Mentra Live glasses.
|
|
133
|
+
* Sends a {@code camera_tuning_config} BLE message; the ASG client relays it as a
|
|
134
|
+
* {@code camconfig} broadcast so the HAL picks up new parameters without a reboot.
|
|
135
|
+
*
|
|
136
|
+
* Scan-mode convention: pass `{anr: false, gain: false}` when activating scan mode
|
|
137
|
+
* (disables ANR and pixsmart gain) and `{anr: true, gain: true}` to restore defaults.
|
|
138
|
+
*/
|
|
139
|
+
setCameraTuningConfig(anrOn: boolean, gainOn: boolean): Promise<SettingsAckSuccessEvent>
|
|
128
140
|
queryGalleryStatus(): Promise<GalleryStatusEvent>
|
|
129
141
|
requestPhoto(params: PhotoRequestParams): Promise<PhotoSuccessResponseEvent>
|
|
142
|
+
warmUpCamera(params: WarmUpCameraParams): Promise<CameraStatusEvent>
|
|
130
143
|
|
|
131
144
|
// OTA Commands
|
|
132
145
|
setOtaVersionUrl(otaVersionUrl: string): void
|
|
@@ -134,8 +147,6 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
|
|
|
134
147
|
checkForOtaUpdate(): Promise<boolean>
|
|
135
148
|
startOtaUpdate(otaVersionUrl?: string | null): Promise<OtaStartAckEvent>
|
|
136
149
|
sendOtaQueryStatus(): Promise<OtaQueryResult>
|
|
137
|
-
/** Re-run glasses-side OTA version check (called after a clock fix invalidates a TLS failure). */
|
|
138
|
-
retryOtaVersionCheck(): Promise<OtaQueryResult>
|
|
139
150
|
|
|
140
151
|
// Version Info Commands
|
|
141
152
|
requestVersionInfo(): Promise<VersionInfoResult>
|
|
@@ -566,5 +577,10 @@ NativeBluetoothSdkModule.requestPhoto = function (params: PhotoRequestParams) {
|
|
|
566
577
|
return nativeRequestPhoto(photoRequestParamsForNative(params) as unknown as PhotoRequestParams)
|
|
567
578
|
}
|
|
568
579
|
|
|
580
|
+
const nativeWarmUpCamera = NativeBluetoothSdkModule.warmUpCamera.bind(NativeBluetoothSdkModule)
|
|
581
|
+
NativeBluetoothSdkModule.warmUpCamera = function (params: WarmUpCameraParams) {
|
|
582
|
+
return nativeWarmUpCamera(warmUpCameraParamsForNative(params) as unknown as WarmUpCameraParams)
|
|
583
|
+
}
|
|
584
|
+
|
|
569
585
|
export default NativeBluetoothSdkModule
|
|
570
586
|
export const BluetoothSdk = NativeBluetoothSdkModule as BluetoothSdkInternalModule
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type {WarmUpCameraParams} from "../BluetoothSdk.types"
|
|
2
|
+
import {normalizePhotoSizeTier} from "./photoRequestPayload"
|
|
3
|
+
|
|
4
|
+
function nonBlankString(value?: string | null): string | undefined {
|
|
5
|
+
const trimmed = value?.trim()
|
|
6
|
+
return trimmed && trimmed.length > 0 ? trimmed : undefined
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */
|
|
10
|
+
export function warmUpCameraParamsForNative(
|
|
11
|
+
params: WarmUpCameraParams,
|
|
12
|
+
): Record<string, string | number> {
|
|
13
|
+
const payload: Record<string, string | number> = {
|
|
14
|
+
size: normalizePhotoSizeTier(params.size),
|
|
15
|
+
}
|
|
16
|
+
const requestId = nonBlankString(params.requestId)
|
|
17
|
+
if (requestId != null) {
|
|
18
|
+
payload.requestId = requestId
|
|
19
|
+
}
|
|
20
|
+
const exposureTimeNs = params.exposureTimeNs
|
|
21
|
+
if (exposureTimeNs != null && Number.isFinite(exposureTimeNs) && exposureTimeNs > 0) {
|
|
22
|
+
payload.exposureTimeNs = exposureTimeNs
|
|
23
|
+
}
|
|
24
|
+
const durationMs = params.durationMs
|
|
25
|
+
if (durationMs != null && Number.isFinite(durationMs) && durationMs > 0) {
|
|
26
|
+
payload.durationMs = Math.round(durationMs)
|
|
27
|
+
}
|
|
28
|
+
return payload
|
|
29
|
+
}
|
|
@@ -19,18 +19,25 @@ export function normalizePhotoSizeTier(size: string | undefined): PhotoSize {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
function nonBlankString(value?: string | null): string | undefined {
|
|
23
|
+
const trimmed = value?.trim()
|
|
24
|
+
return trimmed && trimmed.length > 0 ? trimmed : undefined
|
|
25
|
+
}
|
|
26
|
+
|
|
22
27
|
/** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */
|
|
23
28
|
export function photoRequestParamsForNative(
|
|
24
29
|
params: PhotoRequestParams,
|
|
25
30
|
): Record<string, string | number | boolean> {
|
|
26
31
|
const payload: Record<string, string | number | boolean> = {
|
|
27
|
-
requestId: params.requestId,
|
|
28
|
-
appId: params.appId,
|
|
29
32
|
size: normalizePhotoSizeTier(params.size),
|
|
30
33
|
webhookUrl: params.webhookUrl ?? "",
|
|
31
34
|
compress: params.compress,
|
|
32
35
|
sound: params.sound,
|
|
33
36
|
}
|
|
37
|
+
const requestId = nonBlankString(params.requestId)
|
|
38
|
+
if (requestId != null) {
|
|
39
|
+
payload.requestId = requestId
|
|
40
|
+
}
|
|
34
41
|
if (params.save != null) {
|
|
35
42
|
payload.save = params.save
|
|
36
43
|
}
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,7 @@ const PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([
|
|
|
25
25
|
"hotspot_error",
|
|
26
26
|
"photo_response",
|
|
27
27
|
"photo_status",
|
|
28
|
+
"camera_status",
|
|
28
29
|
"video_recording_status",
|
|
29
30
|
"media_success",
|
|
30
31
|
"media_error",
|
|
@@ -58,65 +59,84 @@ const startOtaUpdate: BluetoothSdkPublicModule["startOtaUpdate"] = () => {
|
|
|
58
59
|
return PrivateBluetoothSdkModule.startOtaUpdate()
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
const bindPublicMethod = <K extends keyof BluetoothSdkPublicModule>(name: K): BluetoothSdkPublicModule[K] => {
|
|
63
|
+
const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>)[name]
|
|
64
|
+
if (typeof method === "function") {
|
|
65
|
+
return method.bind(PrivateBluetoothSdkModule) as BluetoothSdkPublicModule[K]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return (async () => {
|
|
69
|
+
throw new Error(`BluetoothSdk.${String(name)} is not available in this native build. Rebuild the app.`)
|
|
70
|
+
}) as unknown as BluetoothSdkPublicModule[K]
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
export const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({
|
|
62
74
|
addListener,
|
|
63
|
-
getDefaultDevice:
|
|
64
|
-
setDefaultDevice:
|
|
65
|
-
clearDefaultDevice:
|
|
66
|
-
startScan:
|
|
67
|
-
stopScan:
|
|
68
|
-
scan:
|
|
69
|
-
connect:
|
|
70
|
-
connectDefault:
|
|
71
|
-
cancelConnectionAttempt:
|
|
72
|
-
disconnect:
|
|
73
|
-
forget:
|
|
74
|
-
displayText:
|
|
75
|
-
clearDisplay:
|
|
76
|
-
showDashboard:
|
|
77
|
-
setDashboardPosition:
|
|
78
|
-
setHeadUpAngle:
|
|
79
|
-
setImuEnabled:
|
|
80
|
-
setScreenDisabled:
|
|
81
|
-
requestWifiScan:
|
|
82
|
-
sendWifiCredentials:
|
|
83
|
-
forgetWifiNetwork:
|
|
84
|
-
setHotspotState:
|
|
85
|
-
setGalleryModeEnabled:
|
|
86
|
-
setVoiceActivityDetectionEnabled:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
75
|
+
getDefaultDevice: bindPublicMethod("getDefaultDevice"),
|
|
76
|
+
setDefaultDevice: bindPublicMethod("setDefaultDevice"),
|
|
77
|
+
clearDefaultDevice: bindPublicMethod("clearDefaultDevice"),
|
|
78
|
+
startScan: bindPublicMethod("startScan"),
|
|
79
|
+
stopScan: bindPublicMethod("stopScan"),
|
|
80
|
+
scan: bindPublicMethod("scan") as BluetoothSdkPublicModule["scan"],
|
|
81
|
+
connect: bindPublicMethod("connect"),
|
|
82
|
+
connectDefault: bindPublicMethod("connectDefault"),
|
|
83
|
+
cancelConnectionAttempt: bindPublicMethod("cancelConnectionAttempt"),
|
|
84
|
+
disconnect: bindPublicMethod("disconnect"),
|
|
85
|
+
forget: bindPublicMethod("forget"),
|
|
86
|
+
displayText: bindPublicMethod("displayText"),
|
|
87
|
+
clearDisplay: bindPublicMethod("clearDisplay"),
|
|
88
|
+
showDashboard: bindPublicMethod("showDashboard"),
|
|
89
|
+
setDashboardPosition: bindPublicMethod("setDashboardPosition"),
|
|
90
|
+
setHeadUpAngle: bindPublicMethod("setHeadUpAngle"),
|
|
91
|
+
setImuEnabled: bindPublicMethod("setImuEnabled"),
|
|
92
|
+
setScreenDisabled: bindPublicMethod("setScreenDisabled"),
|
|
93
|
+
requestWifiScan: bindPublicMethod("requestWifiScan"),
|
|
94
|
+
sendWifiCredentials: bindPublicMethod("sendWifiCredentials"),
|
|
95
|
+
forgetWifiNetwork: bindPublicMethod("forgetWifiNetwork"),
|
|
96
|
+
setHotspotState: bindPublicMethod("setHotspotState"),
|
|
97
|
+
setGalleryModeEnabled: bindPublicMethod("setGalleryModeEnabled"),
|
|
98
|
+
setVoiceActivityDetectionEnabled: bindPublicMethod("setVoiceActivityDetectionEnabled"),
|
|
99
|
+
setPhotoCaptureDefaults: bindPublicMethod("setPhotoCaptureDefaults"),
|
|
100
|
+
setVideoRecordingDefaults: ({width, height, fps}: VideoRecordingDefaults) => {
|
|
101
|
+
const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>).setVideoRecordingDefaults
|
|
102
|
+
if (typeof method !== "function") {
|
|
103
|
+
return Promise.reject(
|
|
104
|
+
new Error("BluetoothSdk.setVideoRecordingDefaults is not available in this native build. Rebuild the app."),
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
return PrivateBluetoothSdkModule.setVideoRecordingDefaults(width, height, fps)
|
|
108
|
+
},
|
|
109
|
+
setMaxVideoRecordingDuration: bindPublicMethod("setMaxVideoRecordingDuration"),
|
|
110
|
+
setCameraFov: bindPublicMethod("setCameraFov"),
|
|
111
|
+
setCameraTuningConfig: bindPublicMethod("setCameraTuningConfig"),
|
|
112
|
+
queryGalleryStatus: bindPublicMethod("queryGalleryStatus"),
|
|
113
|
+
requestPhoto: bindPublicMethod("requestPhoto"),
|
|
114
|
+
warmUpCamera: bindPublicMethod("warmUpCamera"),
|
|
115
|
+
startVideoRecording: bindPublicMethod("startVideoRecording"),
|
|
116
|
+
stopVideoRecording: bindPublicMethod("stopVideoRecording"),
|
|
117
|
+
startStream: bindPublicMethod("startStream"),
|
|
118
|
+
stopStream: bindPublicMethod("stopStream"),
|
|
119
|
+
setMicState: bindPublicMethod("setMicState"),
|
|
120
|
+
setPreferredMic: bindPublicMethod("setPreferredMic"),
|
|
121
|
+
setOwnAppAudioPlaying: bindPublicMethod("setOwnAppAudioPlaying"),
|
|
122
|
+
getGlassesMediaVolume: bindPublicMethod("getGlassesMediaVolume"),
|
|
123
|
+
setGlassesMediaVolume: bindPublicMethod("setGlassesMediaVolume"),
|
|
124
|
+
rgbLedControl: bindPublicMethod("rgbLedControl"),
|
|
125
|
+
requestVersionInfo: bindPublicMethod("requestVersionInfo"),
|
|
126
|
+
checkForOtaUpdate: bindPublicMethod("checkForOtaUpdate"),
|
|
107
127
|
startOtaUpdate,
|
|
108
|
-
setSttModelDetails:
|
|
109
|
-
getSttModelPath:
|
|
110
|
-
checkSttModelAvailable:
|
|
111
|
-
validateSttModel:
|
|
112
|
-
extractTarBz2:
|
|
113
|
-
restartTranscriber:
|
|
114
|
-
setTtsModelDetails:
|
|
115
|
-
getTtsModelPath:
|
|
116
|
-
getTtsModelLanguage:
|
|
117
|
-
checkTtsModelAvailable:
|
|
118
|
-
validateTtsModel:
|
|
119
|
-
generateTtsAudio:
|
|
128
|
+
setSttModelDetails: bindPublicMethod("setSttModelDetails"),
|
|
129
|
+
getSttModelPath: bindPublicMethod("getSttModelPath"),
|
|
130
|
+
checkSttModelAvailable: bindPublicMethod("checkSttModelAvailable"),
|
|
131
|
+
validateSttModel: bindPublicMethod("validateSttModel"),
|
|
132
|
+
extractTarBz2: bindPublicMethod("extractTarBz2"),
|
|
133
|
+
restartTranscriber: bindPublicMethod("restartTranscriber"),
|
|
134
|
+
setTtsModelDetails: bindPublicMethod("setTtsModelDetails"),
|
|
135
|
+
getTtsModelPath: bindPublicMethod("getTtsModelPath"),
|
|
136
|
+
getTtsModelLanguage: bindPublicMethod("getTtsModelLanguage"),
|
|
137
|
+
checkTtsModelAvailable: bindPublicMethod("checkTtsModelAvailable"),
|
|
138
|
+
validateTtsModel: bindPublicMethod("validateTtsModel"),
|
|
139
|
+
generateTtsAudio: bindPublicMethod("generateTtsAudio"),
|
|
120
140
|
})
|
|
121
141
|
|
|
122
142
|
export default BluetoothSdk
|
|
@@ -178,8 +198,6 @@ export type {
|
|
|
178
198
|
OtaStatus,
|
|
179
199
|
OtaStatusEvent,
|
|
180
200
|
OtaQueryResult,
|
|
181
|
-
OtaUpdateAvailableEvent,
|
|
182
|
-
OtaUpdateInfo,
|
|
183
201
|
PairFailureEvent,
|
|
184
202
|
PhotoCaptureMetadata,
|
|
185
203
|
PhotoResolvedConfig,
|