@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.
Files changed (147) hide show
  1. package/README.md +116 -18
  2. package/android/build.gradle +289 -16
  3. package/android/gradle.properties.example +9 -0
  4. package/android/lc3Lib/build.gradle +95 -6
  5. package/android/settings.gradle +3 -0
  6. package/android/silero/LICENSE.md +17 -0
  7. package/android/silero/build.gradle +42 -0
  8. package/android/silero/proguard-rules.pro +24 -0
  9. package/android/silero/src/androidTest/assets/hello.wav +0 -0
  10. package/android/silero/src/androidTest/java/com/konovalov/vad/silero/VadSileroTest.kt +79 -0
  11. package/android/silero/src/main/assets/LICENSE +21 -0
  12. package/android/silero/src/main/assets/silero_vad.onnx +0 -0
  13. package/android/silero/src/main/java/com/konovalov/vad/silero/Vad.kt +160 -0
  14. package/android/silero/src/main/java/com/konovalov/vad/silero/VadSilero.kt +449 -0
  15. package/android/silero/src/main/java/com/konovalov/vad/silero/config/FrameSize.kt +15 -0
  16. package/android/silero/src/main/java/com/konovalov/vad/silero/config/Mode.kt +14 -0
  17. package/android/silero/src/main/java/com/konovalov/vad/silero/config/SampleRate.kt +12 -0
  18. package/android/silero/src/main/java/com/konovalov/vad/silero/utils/AudioUtils.kt +47 -0
  19. package/android/silero/src/main/java/com/konovalov/vad/silero/utils/TensorMap.kt +41 -0
  20. package/android/silero/src/test/java/com/konovalov/vad/silero/utils/AudioUtilsTest.kt +44 -0
  21. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkDefaults.kt +6 -0
  22. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +195 -34
  23. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +103 -21
  24. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +210 -18
  25. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +30 -2
  26. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +787 -85
  27. package/android/src/main/java/com/mentra/bluetoothsdk/audio/AudioModels.kt +6 -2
  28. package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +125 -11
  29. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +12 -2
  30. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +8 -2
  31. package/android/src/main/java/com/mentra/bluetoothsdk/debug/BleTraceLogger.kt +33 -17
  32. package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +101 -0
  33. package/android/src/main/java/com/mentra/bluetoothsdk/internal/MapParsing.kt +8 -0
  34. package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistry.java +108 -0
  35. package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoUploadServer.kt +399 -74
  36. package/android/src/main/java/com/mentra/bluetoothsdk/photoreceiver/MentraPhotoReceiverModule.kt +100 -17
  37. package/android/src/main/java/com/mentra/bluetoothsdk/requests/DisplayRequests.kt +17 -0
  38. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +2 -2
  39. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +1293 -758
  40. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +2 -2
  41. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +271 -66
  42. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +197 -149
  43. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +12753 -27036
  44. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +64 -2
  45. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +16 -4
  46. package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +60 -3
  47. package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +12 -3
  48. package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +87 -36
  49. package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +13 -4
  50. package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +229 -0
  51. package/android/src/main/java/com/mentra/bluetoothsdk/tts/TTSTools.kt +180 -0
  52. package/android/src/main/java/com/mentra/bluetoothsdk/utils/AvifExifStripper.java +573 -0
  53. package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +488 -50
  54. package/android/src/main/java/com/mentra/bluetoothsdk/utils/HeifExifTagReader.java +199 -0
  55. package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunkReassembler.java +18 -1
  56. package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +64 -18
  57. package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +48 -39
  58. package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +23 -0
  59. package/android/src/test/java/com/mentra/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistryTest.java +75 -0
  60. package/android/src/test/java/com/mentra/bluetoothsdk/utils/AvifExifStripperTest.java +30 -0
  61. package/android/src/test/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadServiceTest.java +98 -0
  62. package/android/src/test/resources/avif_with_exif.avif +0 -0
  63. package/build/BluetoothSdk.types.d.ts +253 -44
  64. package/build/BluetoothSdk.types.d.ts.map +1 -1
  65. package/build/BluetoothSdk.types.js +11 -10
  66. package/build/BluetoothSdk.types.js.map +1 -1
  67. package/build/_private/BluetoothSdkModule.d.ts +37 -23
  68. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  69. package/build/_private/BluetoothSdkModule.js +43 -52
  70. package/build/_private/BluetoothSdkModule.js.map +1 -1
  71. package/build/_private/photoRequestPayload.d.ts +4 -0
  72. package/build/_private/photoRequestPayload.d.ts.map +1 -0
  73. package/build/_private/photoRequestPayload.js +25 -0
  74. package/build/_private/photoRequestPayload.js.map +1 -0
  75. package/build/index.d.ts +1 -1
  76. package/build/index.d.ts.map +1 -1
  77. package/build/index.js +25 -0
  78. package/build/index.js.map +1 -1
  79. package/build/react/useMentraBluetooth.d.ts +2 -2
  80. package/build/react/useMentraBluetooth.d.ts.map +1 -1
  81. package/build/react/useMentraBluetooth.js +3 -3
  82. package/build/react/useMentraBluetooth.js.map +1 -1
  83. package/ios/BluetoothSdkModule.swift +177 -70
  84. package/ios/LocalPhotoUploadServer.swift +370 -105
  85. package/ios/MentraBluetoothSDK.podspec +3 -1
  86. package/ios/MentraPhotoReceiverModule.swift +62 -10
  87. package/ios/Packages/CoreObjC/include/PcmConverter.h +22 -0
  88. package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +668 -26
  89. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +13 -9
  90. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/c-api.h +4551 -0
  91. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/cxx-api.h +1745 -0
  92. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
  93. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/c-api.h +4551 -0
  94. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/cxx-api.h +1745 -0
  95. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
  96. package/ios/Source/BluetoothSdkDefaults.swift +6 -0
  97. package/ios/Source/Bridge.swift +68 -19
  98. package/ios/Source/DeviceManager.swift +167 -32
  99. package/ios/Source/DeviceStore.swift +24 -8
  100. package/ios/Source/MentraBluetoothSDK.swift +803 -47
  101. package/ios/Source/ObservableStore.swift +6 -0
  102. package/ios/Source/{Audio → audio}/AudioModels.swift +9 -7
  103. package/ios/Source/{Camera → camera}/CameraModels.swift +226 -16
  104. package/ios/Source/controllers/ControllerManager.swift +4 -3
  105. package/ios/Source/controllers/R1.swift +3 -3
  106. package/ios/Source/{Events → events}/BluetoothEvents.swift +183 -1
  107. package/ios/Source/{Internal → internal}/ValueParsing.swift +10 -1
  108. package/ios/Source/{Requests → requests}/DisplayRequests.swift +28 -4
  109. package/ios/Source/services/PhoneMic.swift +1 -0
  110. package/ios/Source/sgcs/G1.swift +5 -5
  111. package/ios/Source/sgcs/G2.swift +1494 -870
  112. package/ios/Source/sgcs/Mach1.swift +4 -4
  113. package/ios/Source/sgcs/MentraLive.swift +814 -321
  114. package/ios/Source/sgcs/MentraNex.swift +604 -244
  115. package/ios/Source/sgcs/SGCManager.swift +68 -5
  116. package/ios/Source/sgcs/Simulated.swift +9 -5
  117. package/ios/Source/sgcs/mentraos_ble.pb.swift +3073 -3134
  118. package/ios/Source/status/DeviceStatus.swift +974 -0
  119. package/ios/Source/{Status → status}/WifiHotspotStatus.swift +4 -4
  120. package/ios/Source/{Streaming → streaming}/StreamModels.swift +24 -9
  121. package/ios/Source/stt/STTTools.swift +27 -12
  122. package/ios/Source/stt/SherpaOnnxTranscriber.swift +31 -8
  123. package/ios/Source/tts/TTSTools.swift +164 -0
  124. package/ios/Source/utils/JSCExperiment.swift +7 -7
  125. package/ios/Source/utils/MessageChunkReassembler.swift +20 -1
  126. package/ios/Source/utils/MessageChunker.swift +78 -21
  127. package/ios/Source/utils/TarBz2Extractor.swift +53 -2
  128. package/package.json +1 -1
  129. package/plugin/build/withAndroid.js +68 -4
  130. package/src/BluetoothSdk.types.ts +344 -60
  131. package/src/_private/BluetoothSdkModule.ts +132 -102
  132. package/src/_private/photoRequestPayload.ts +28 -0
  133. package/src/index.ts +61 -15
  134. package/src/react/useMentraBluetooth.ts +6 -4
  135. package/android/.project +0 -28
  136. package/android/lc3Lib/.project +0 -28
  137. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +0 -162
  138. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +0 -1852
  139. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +0 -674
  140. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
  141. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
  142. package/ios/Source/Status/DeviceStatus.swift +0 -471
  143. /package/ios/Source/{Connection → connection}/ScanSession.swift +0 -0
  144. /package/ios/Source/{Errors → errors}/BluetoothError.swift +0 -0
  145. /package/ios/Source/{Internal → internal}/BluetoothAvailability.swift +0 -0
  146. /package/ios/Source/{Status → status}/RuntimeState.swift +0 -0
  147. /package/ios/Source/{Types → types}/DeviceModels.swift +0 -0
@@ -6,10 +6,15 @@ import {
6
6
  BluetoothSdkModuleEvents,
7
7
  BluetoothStatus,
8
8
  ButtonPhotoSize,
9
+ CalendarEvent,
9
10
  CAMERA_FOV_DEFAULT,
10
11
  CAMERA_FOV_MAX,
11
12
  CAMERA_FOV_MIN,
12
- CameraFov,
13
+ CameraFovPreset,
14
+ CameraFovRequest,
15
+ CameraFovResult,
16
+ CameraFovSetting,
17
+ CameraRoiPosition,
13
18
  ConnectOptions,
14
19
  DashboardMenuItem,
15
20
  Device,
@@ -17,17 +22,32 @@ import {
17
22
  GlassesMediaVolumeGetResult,
18
23
  GlassesMediaVolumeSetResult,
19
24
  GlassesStatus,
25
+ GalleryStatusEvent,
26
+ HotspotStatusChangeEvent,
20
27
  MicPreference,
21
28
  ObservableStoreCategory,
29
+ OtaQueryResult,
30
+ OtaStartAckEvent,
22
31
  PhotoRequestParams,
32
+ PhotoSuccessResponseEvent,
23
33
  PublicBluetoothStatus,
24
34
  RgbLedAction,
25
35
  RgbLedColor,
36
+ RgbLedControlSuccessResponseEvent,
26
37
  ScanModelOptions,
27
38
  ScanOptions,
39
+ SettingsAckSuccessEvent,
28
40
  StreamKeepAliveRequest,
29
41
  StreamStartRequest,
42
+ StreamStatusEvent,
43
+ VideoRecordingStartedStatusEvent,
44
+ VideoRecordingSettings,
45
+ VideoRecordingStoppedStatusEvent,
46
+ VersionInfoResult,
47
+ WifiSearchResult,
48
+ WifiStatusChangeEvent,
30
49
  } from "../BluetoothSdk.types"
50
+ import {photoRequestParamsForNative} from "./photoRequestPayload"
31
51
 
32
52
  /**
33
53
  * Private React Native native-module facade.
@@ -78,7 +98,9 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
78
98
  setAutoBrightness(enabled: boolean): Promise<void>
79
99
  setDashboardPosition(height: number, depth: number): Promise<void>
80
100
  setDashboardMenu(items: DashboardMenuItem[]): Promise<void>
101
+ setCalendarEvents(events: CalendarEvent[]): Promise<void>
81
102
  setHeadUpAngle(angleDegrees: number): Promise<void>
103
+ setImuEnabled(enabled: boolean): Promise<void>
82
104
  setScreenDisabled(disabled: boolean): Promise<void>
83
105
  ping(): Promise<void>
84
106
  dbg1(): Promise<void>
@@ -88,48 +110,54 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
88
110
  sendIncidentId(incidentId: string, apiBaseUrl?: string | null): Promise<void>
89
111
 
90
112
  // WiFi Commands
91
- requestWifiScan(): Promise<void>
92
- sendWifiCredentials(ssid: string, password: string): Promise<void>
93
- forgetWifiNetwork(ssid: string): Promise<void>
94
- setHotspotState(enabled: boolean): Promise<void>
113
+ requestWifiScan(): Promise<WifiSearchResult[]>
114
+ sendWifiCredentials(ssid: string, password: string): Promise<WifiStatusChangeEvent>
115
+ forgetWifiNetwork(ssid: string): Promise<WifiStatusChangeEvent>
116
+ setHotspotState(enabled: boolean): Promise<HotspotStatusChangeEvent>
117
+ /** Set glasses system clock (Mentra Live only) when phone detects clock skew. */
118
+ setSystemTime(timestampMs: number): Promise<void>
95
119
  /** Logs current WiFi frequency (MHz) and 5 GHz band to Android logcat. */
96
120
  logCurrentWifiFrequency(): Promise<void>
97
121
 
98
122
  // Gallery Commands
99
- setGalleryModeEnabled(enabled: boolean): Promise<void>
123
+ setGalleryModeEnabled(enabled: boolean): Promise<SettingsAckSuccessEvent>
100
124
  setVoiceActivityDetectionEnabled(enabled: boolean): Promise<void>
101
- setButtonPhotoSettings(size: ButtonPhotoSize): Promise<void>
102
- setButtonVideoRecordingSettings(width: number, height: number, fps: number): Promise<void>
103
- setButtonCameraLed(enabled: boolean): Promise<void>
104
- setButtonMaxRecordingTime(minutes: number): Promise<void>
105
- setCameraFov(fov: CameraFov): Promise<void>
106
- queryGalleryStatus(): Promise<void>
107
- requestPhoto(params: PhotoRequestParams): Promise<void>
125
+ setButtonPhotoSettings(size: ButtonPhotoSize): Promise<SettingsAckSuccessEvent>
126
+ setButtonVideoRecordingSettings(width: number, height: number, fps: number): Promise<SettingsAckSuccessEvent>
127
+ setButtonCameraLed(enabled: boolean): Promise<SettingsAckSuccessEvent>
128
+ setButtonMaxRecordingTime(minutes: number): Promise<SettingsAckSuccessEvent>
129
+ setCameraFov(request: CameraFovRequest): Promise<CameraFovResult>
130
+ queryGalleryStatus(): Promise<GalleryStatusEvent>
131
+ requestPhoto(params: PhotoRequestParams): Promise<PhotoSuccessResponseEvent>
108
132
 
109
133
  // OTA Commands
110
- sendOtaStart(): Promise<void>
111
- sendOtaQueryStatus(): Promise<void>
134
+ sendOtaStart(): Promise<OtaStartAckEvent>
135
+ sendOtaQueryStatus(): Promise<OtaQueryResult>
136
+ /** Re-run glasses-side OTA version check (called after a clock fix invalidates a TLS failure). */
137
+ retryOtaVersionCheck(): Promise<OtaQueryResult>
138
+ checkForOtaUpdate(): Promise<OtaQueryResult>
139
+ startOtaUpdate(): Promise<OtaStartAckEvent>
112
140
 
113
141
  // Version Info Commands
114
- requestVersionInfo(): Promise<void>
142
+ requestVersionInfo(): Promise<VersionInfoResult>
115
143
 
116
144
  // Video Recording Commands
117
- startVideoRecording(requestId: string, save: boolean, sound: boolean): Promise<void>
118
- stopVideoRecording(requestId: string): Promise<void>
145
+ startVideoRecording(
146
+ requestId: string,
147
+ save: boolean,
148
+ sound: boolean,
149
+ settings?: VideoRecordingSettings,
150
+ ): Promise<VideoRecordingStartedStatusEvent>
151
+ stopVideoRecording(requestId: string): Promise<VideoRecordingStoppedStatusEvent>
119
152
 
120
153
  // Stream Commands
121
- startStream(params: StreamStartRequest): Promise<void>
122
- startCloudManagedStream(params: StreamStartRequest): Promise<void>
123
- stopStream(): Promise<void>
124
- sendCloudStreamKeepAlive(params: StreamKeepAliveRequest): Promise<void>
154
+ startStream(params: StreamStartRequest): Promise<StreamStatusEvent>
155
+ startExternallyManagedStream(params: StreamStartRequest): Promise<StreamStatusEvent>
156
+ stopStream(): Promise<StreamStatusEvent>
157
+ sendExternallyManagedStreamKeepAlive(params: StreamKeepAliveRequest): Promise<void>
125
158
 
126
159
  // Microphone Commands
127
- setMicState(
128
- enabled: boolean,
129
- useGlassesMic?: boolean,
130
- sendTranscript?: boolean,
131
- sendLc3Data?: boolean,
132
- ): Promise<void>
160
+ setMicState(enabled: boolean, useGlassesMic?: boolean, sendTranscript?: boolean, sendLc3Data?: boolean): Promise<void>
133
161
  setPreferredMic(preferredMic: MicPreference): Promise<void>
134
162
  restartTranscriber(): Promise<void>
135
163
 
@@ -152,7 +180,7 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
152
180
  onDurationMs: number,
153
181
  offDurationMs: number,
154
182
  count: number,
155
- ): Promise<void>
183
+ ): Promise<RgbLedControlSuccessResponseEvent>
156
184
 
157
185
  // STT Commands
158
186
  setSttModelDetails(path: string, languageCode: string): Promise<void>
@@ -161,6 +189,20 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
161
189
  validateSttModel(path: string): Promise<boolean>
162
190
  extractTarBz2(sourcePath: string, destinationPath: string): Promise<boolean>
163
191
 
192
+ // TTS Commands
193
+ setTtsModelDetails(path: string, languageCode: string): Promise<void>
194
+ getTtsModelPath(): Promise<string>
195
+ getTtsModelLanguage(): Promise<string>
196
+ checkTtsModelAvailable(): Promise<boolean>
197
+ validateTtsModel(path: string): Promise<boolean>
198
+ generateTtsAudio(
199
+ text: string,
200
+ modelPath: string,
201
+ outputPath: string,
202
+ speakerId: number,
203
+ speed: number,
204
+ ): Promise<boolean>
205
+
164
206
  // Helper methods for type-safe observable store access
165
207
  updateGlasses(values: Partial<GlassesStatus>): Promise<void>
166
208
  updateBluetoothSettings(values: BluetoothSettingsUpdate): Promise<void>
@@ -184,25 +226,57 @@ const DEFAULT_CONNECT_OPTIONS: Required<ConnectOptions> = {
184
226
 
185
227
  const DEFAULT_SCAN_TIMEOUT_MS = 15_000
186
228
 
229
+ function bindNativeMethod<T extends (...args: never[]) => unknown>(
230
+ module: Record<string, unknown>,
231
+ name: string,
232
+ ): T {
233
+ const method = module[name]
234
+ if (typeof method !== "function") {
235
+ console.warn(`[BluetoothSdk] Native method "${name}" is unavailable — rebuild the app (bun android / bun ios)`)
236
+ return (async () => {
237
+ throw new Error(`BluetoothSdk.${name} is not available in this native build. Rebuild the app.`)
238
+ }) as T
239
+ }
240
+ return method.bind(module) as T
241
+ }
242
+
187
243
  const CAMERA_ROI_MIN = 0
188
244
  const CAMERA_ROI_MAX = 2
245
+ const CAMERA_ROI_POSITION_VALUES: Record<CameraRoiPosition, CameraFovSetting["roiPosition"]> = {
246
+ center: 0,
247
+ bottom: 1,
248
+ top: 2,
249
+ }
250
+
251
+ // Named presets are a convenience layer over the numeric {fov, roiPosition} API.
252
+ // "narrow" uses 82, a device-tested FOV; "standard" matches CAMERA_FOV_DEFAULT.
253
+ const CAMERA_FOV_PRESETS: Record<CameraFovPreset, CameraFovSetting> = {
254
+ narrow: {fov: 82, roiPosition: 0},
255
+ standard: {fov: CAMERA_FOV_DEFAULT, roiPosition: 0},
256
+ wide: {fov: CAMERA_FOV_MAX, roiPosition: 0},
257
+ }
189
258
 
190
259
  function clampInteger(value: number, min: number, max: number): number {
191
260
  return Math.max(min, Math.min(max, Math.round(value)))
192
261
  }
193
262
 
194
- function normalizeCameraFov(setting: CameraFov): Required<CameraFov> {
263
+ function normalizeCameraFov(request: CameraFovRequest): CameraFovSetting {
264
+ if ("preset" in request) {
265
+ return CAMERA_FOV_PRESETS[request.preset] ?? CAMERA_FOV_PRESETS.standard
266
+ }
267
+
268
+ const roiPosition = request.roiPosition ?? "center"
269
+
195
270
  return {
196
271
  fov: clampInteger(
197
- Number.isFinite(setting.fov) ? setting.fov : CAMERA_FOV_DEFAULT,
272
+ Number.isFinite(request.fov) ? request.fov : CAMERA_FOV_DEFAULT,
198
273
  CAMERA_FOV_MIN,
199
274
  CAMERA_FOV_MAX,
200
275
  ),
201
- roiPosition: clampInteger(
202
- Number.isFinite(setting.roiPosition ?? 0) ? (setting.roiPosition ?? 0) : 0,
203
- CAMERA_ROI_MIN,
204
- CAMERA_ROI_MAX,
205
- ) as Required<CameraFov>["roiPosition"],
276
+ roiPosition: clampInteger(CAMERA_ROI_POSITION_VALUES[roiPosition] ?? 0, CAMERA_ROI_MIN, CAMERA_ROI_MAX) as
277
+ | 0
278
+ | 1
279
+ | 2,
206
280
  }
207
281
  }
208
282
 
@@ -296,7 +370,9 @@ NativeBluetoothSdkModule.getGlassesStatus = function () {
296
370
  return Promise.resolve(nativeGetGlassesStatus())
297
371
  }
298
372
 
299
- const nativeGetBluetoothStatus = NativeBluetoothSdkModule.getBluetoothStatus.bind(NativeBluetoothSdkModule) as () => MaybePromise<BluetoothStatus>
373
+ const nativeGetBluetoothStatus = NativeBluetoothSdkModule.getBluetoothStatus.bind(
374
+ NativeBluetoothSdkModule,
375
+ ) as () => MaybePromise<BluetoothStatus>
300
376
  NativeBluetoothSdkModule.getBluetoothStatus = function () {
301
377
  return Promise.resolve(nativeGetBluetoothStatus())
302
378
  }
@@ -356,47 +432,32 @@ NativeBluetoothSdkModule.setDashboardMenu = function (items: DashboardMenuItem[]
356
432
  return this.updateBluetoothSettings({menu_apps: items.map(dashboardMenuItemToNative)})
357
433
  }
358
434
 
435
+ NativeBluetoothSdkModule.setCalendarEvents = function (events: CalendarEvent[]) {
436
+ return this.updateBluetoothSettings({calendar_events: events})
437
+ }
438
+
359
439
  NativeBluetoothSdkModule.setHeadUpAngle = function (angleDegrees: number) {
360
440
  return this.updateBluetoothSettings({head_up_angle: angleDegrees})
361
441
  }
362
442
 
363
- NativeBluetoothSdkModule.setScreenDisabled = function (disabled: boolean) {
364
- return this.updateBluetoothSettings({screen_disabled: disabled})
443
+ NativeBluetoothSdkModule.setImuEnabled = function (enabled: boolean) {
444
+ return this.updateBluetoothSettings({imu_enabled: enabled})
365
445
  }
366
446
 
367
- NativeBluetoothSdkModule.setGalleryModeEnabled = function (enabled: boolean) {
368
- return this.updateBluetoothSettings({gallery_mode: enabled})
447
+ NativeBluetoothSdkModule.setScreenDisabled = function (disabled: boolean) {
448
+ return this.updateBluetoothSettings({screen_disabled: disabled})
369
449
  }
370
450
 
371
451
  NativeBluetoothSdkModule.setVoiceActivityDetectionEnabled = function (enabled: boolean) {
372
452
  return this.updateBluetoothSettings({voice_activity_detection_enabled: enabled})
373
453
  }
374
454
 
375
- NativeBluetoothSdkModule.setButtonPhotoSettings = function (size: ButtonPhotoSize) {
376
- return this.updateBluetoothSettings({button_photo_size: size})
377
- }
378
-
379
- NativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width: number, height: number, fps: number) {
380
- return this.updateBluetoothSettings({
381
- button_video_width: width,
382
- button_video_height: height,
383
- button_video_fps: fps,
384
- })
385
- }
386
-
387
- NativeBluetoothSdkModule.setButtonCameraLed = function (enabled: boolean) {
388
- return this.updateBluetoothSettings({button_camera_led: enabled})
389
- }
390
-
391
- NativeBluetoothSdkModule.setButtonMaxRecordingTime = function (minutes: number) {
392
- return this.updateBluetoothSettings({button_max_recording_time: minutes})
393
- }
394
-
395
- NativeBluetoothSdkModule.setCameraFov = function (fov: CameraFov) {
396
- const setting = normalizeCameraFov(fov)
397
- return this.updateBluetoothSettings({
398
- camera_fov: {fov: setting.fov, roi_position: setting.roiPosition},
399
- })
455
+ const nativeSetCameraFov = bindNativeMethod<
456
+ (fov: CameraFovSetting) => MaybePromise<CameraFovResult>
457
+ >(NativeBluetoothSdkModule as unknown as Record<string, unknown>, "setCameraFov")
458
+ NativeBluetoothSdkModule.setCameraFov = function (request: CameraFovRequest) {
459
+ const setting = normalizeCameraFov(request)
460
+ return Promise.resolve(nativeSetCameraFov(setting))
400
461
  }
401
462
 
402
463
  NativeBluetoothSdkModule.setMicState = function (
@@ -406,12 +467,7 @@ NativeBluetoothSdkModule.setMicState = function (
406
467
  sendLc3Data?: boolean,
407
468
  ) {
408
469
  return Promise.resolve(
409
- nativeSetMicState(
410
- enabled,
411
- useGlassesMic ?? true,
412
- sendTranscript ?? false,
413
- sendLc3Data ?? false,
414
- ),
470
+ nativeSetMicState(enabled, useGlassesMic ?? true, sendTranscript ?? false, sendLc3Data ?? false),
415
471
  )
416
472
  }
417
473
 
@@ -441,10 +497,7 @@ NativeBluetoothSdkModule.connect = function (device: Device, options?: ConnectOp
441
497
  return this.connectWithOptions(device, {...DEFAULT_CONNECT_OPTIONS, ...options})
442
498
  }
443
499
 
444
- NativeBluetoothSdkModule.scan = async function (
445
- modelOrOptions: DeviceModel | ScanOptions,
446
- options?: ScanModelOptions,
447
- ) {
500
+ NativeBluetoothSdkModule.scan = async function (modelOrOptions: DeviceModel | ScanOptions, options?: ScanModelOptions) {
448
501
  const scanOptions = normalizeScanArgs(modelOrOptions, options)
449
502
  const timeoutMs = normalizeTimeoutMs(scanOptions.timeoutMs ?? scanOptions.timeout, DEFAULT_SCAN_TIMEOUT_MS)
450
503
  let latestResults: Device[] = []
@@ -505,40 +558,17 @@ NativeBluetoothSdkModule.scan = async function (
505
558
  })
506
559
  }
507
560
 
508
- /** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */
509
- function photoRequestParamsForNative(params: PhotoRequestParams): Record<string, string | number | boolean> {
510
- const payload: Record<string, string | number | boolean> = {
511
- requestId: params.requestId,
512
- appId: params.appId,
513
- size: params.size,
514
- webhookUrl: params.webhookUrl ?? "",
515
- compress: params.compress,
516
- flash: true,
517
- sound: params.sound,
518
- }
519
- if (params.authToken != null && params.authToken.length > 0) {
520
- payload.authToken = params.authToken
521
- }
522
- const exposureTimeNs = params.exposureTimeNs
523
- const hasManualExposure = exposureTimeNs != null && Number.isFinite(exposureTimeNs) && exposureTimeNs > 0
524
- if (hasManualExposure) {
525
- payload.exposureTimeNs = exposureTimeNs
526
- }
527
- if (hasManualExposure && params.iso != null && Number.isFinite(params.iso) && params.iso > 0) {
528
- payload.iso = Math.round(params.iso)
529
- }
530
- return payload
531
- }
532
-
533
561
  const nativeRequestPhoto = NativeBluetoothSdkModule.requestPhoto.bind(NativeBluetoothSdkModule)
534
562
  NativeBluetoothSdkModule.requestPhoto = function (params: PhotoRequestParams) {
535
563
  return nativeRequestPhoto(photoRequestParamsForNative(params) as unknown as PhotoRequestParams)
536
564
  }
537
565
 
538
566
  const nativeStartStream = NativeBluetoothSdkModule.startStream.bind(NativeBluetoothSdkModule)
539
- NativeBluetoothSdkModule.startCloudManagedStream = function (params: StreamStartRequest) {
567
+ NativeBluetoothSdkModule.startExternallyManagedStream = function (params: StreamStartRequest) {
540
568
  return nativeStartStream({...params, keepAliveMode: "external"} as StreamStartRequest)
541
569
  }
570
+ NativeBluetoothSdkModule.checkForOtaUpdate = NativeBluetoothSdkModule.sendOtaQueryStatus.bind(NativeBluetoothSdkModule)
571
+ NativeBluetoothSdkModule.startOtaUpdate = NativeBluetoothSdkModule.sendOtaStart.bind(NativeBluetoothSdkModule)
542
572
 
543
573
  export default NativeBluetoothSdkModule
544
574
  export const BluetoothSdk = NativeBluetoothSdkModule as BluetoothSdkPublicModule
@@ -0,0 +1,28 @@
1
+ import type {PhotoRequestParams} from "../BluetoothSdk.types"
2
+
3
+ /** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */
4
+ export function photoRequestParamsForNative(
5
+ params: PhotoRequestParams,
6
+ ): Record<string, string | number | boolean> {
7
+ const payload: Record<string, string | number | boolean> = {
8
+ requestId: params.requestId,
9
+ appId: params.appId,
10
+ size: params.size,
11
+ webhookUrl: params.webhookUrl ?? "",
12
+ compress: params.compress,
13
+ flash: true,
14
+ sound: params.sound,
15
+ }
16
+ if (params.authToken != null && params.authToken.length > 0) {
17
+ payload.authToken = params.authToken
18
+ }
19
+ const exposureTimeNs = params.exposureTimeNs
20
+ const hasManualExposure = exposureTimeNs != null && Number.isFinite(exposureTimeNs) && exposureTimeNs > 0
21
+ if (hasManualExposure) {
22
+ payload.exposureTimeNs = exposureTimeNs
23
+ }
24
+ if (hasManualExposure && params.iso != null && Number.isFinite(params.iso) && params.iso > 0) {
25
+ payload.iso = Math.round(params.iso)
26
+ }
27
+ return payload
28
+ }
package/src/index.ts CHANGED
@@ -1,9 +1,5 @@
1
1
  import PrivateBluetoothSdkModule from "./_private/BluetoothSdkModule"
2
- import type {
3
- BluetoothSdkEventListener,
4
- BluetoothSdkEventName,
5
- BluetoothSdkPublicModule,
6
- } from "./BluetoothSdk.types"
2
+ import type {BluetoothSdkEventListener, BluetoothSdkEventName, BluetoothSdkPublicModule} from "./BluetoothSdk.types"
7
3
 
8
4
  const PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([
9
5
  "log",
@@ -12,21 +8,25 @@ const PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([
12
8
  "glasses_not_ready",
13
9
  "button_press",
14
10
  "touch_event",
11
+ "accel_event",
15
12
  "head_up",
16
13
  "voice_activity_detection_status",
17
14
  "speaking_status",
18
15
  "battery_status",
19
16
  "local_transcription",
20
17
  "wifi_status_change",
18
+ "wifi_scan_result",
21
19
  "hotspot_status_change",
22
20
  "hotspot_error",
23
21
  "photo_response",
24
22
  "photo_status",
23
+ "video_recording_status",
25
24
  "gallery_status",
26
25
  "compatible_glasses_search_stop",
27
26
  "swipe_volume_status",
28
27
  "switch_status",
29
28
  "rgb_led_control_response",
29
+ "settings_ack",
30
30
  "pair_failure",
31
31
  "audio_pairing_needed",
32
32
  "audio_connected",
@@ -34,18 +34,18 @@ const PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([
34
34
  "mic_pcm",
35
35
  "mic_lc3",
36
36
  "stream_status",
37
+ "ota_update_available",
38
+ "ota_start_ack",
39
+ "ota_status",
40
+ "version_info",
41
+ "extraction_progress",
37
42
  ])
38
43
 
39
44
  const addListener: BluetoothSdkPublicModule["addListener"] = (eventName, listener) => {
40
45
  if (!PUBLIC_EVENT_NAMES.has(eventName)) {
41
- throw new Error(
42
- `Unsupported BluetoothSdk event "${eventName}". Use @mentra/bluetooth-sdk/react for status state.`,
43
- )
46
+ throw new Error(`Unsupported BluetoothSdk event "${eventName}". Use @mentra/bluetooth-sdk/react for status state.`)
44
47
  }
45
- return PrivateBluetoothSdkModule.addListener(
46
- eventName,
47
- listener as BluetoothSdkEventListener<BluetoothSdkEventName>,
48
- )
48
+ return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)
49
49
  }
50
50
 
51
51
  export const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({
@@ -66,15 +66,18 @@ export const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({
66
66
  showDashboard: PrivateBluetoothSdkModule.showDashboard.bind(PrivateBluetoothSdkModule),
67
67
  setDashboardPosition: PrivateBluetoothSdkModule.setDashboardPosition.bind(PrivateBluetoothSdkModule),
68
68
  setHeadUpAngle: PrivateBluetoothSdkModule.setHeadUpAngle.bind(PrivateBluetoothSdkModule),
69
+ setImuEnabled: PrivateBluetoothSdkModule.setImuEnabled.bind(PrivateBluetoothSdkModule),
69
70
  setScreenDisabled: PrivateBluetoothSdkModule.setScreenDisabled.bind(PrivateBluetoothSdkModule),
70
71
  requestWifiScan: PrivateBluetoothSdkModule.requestWifiScan.bind(PrivateBluetoothSdkModule),
71
72
  sendWifiCredentials: PrivateBluetoothSdkModule.sendWifiCredentials.bind(PrivateBluetoothSdkModule),
72
73
  forgetWifiNetwork: PrivateBluetoothSdkModule.forgetWifiNetwork.bind(PrivateBluetoothSdkModule),
73
74
  setHotspotState: PrivateBluetoothSdkModule.setHotspotState.bind(PrivateBluetoothSdkModule),
74
75
  setGalleryModeEnabled: PrivateBluetoothSdkModule.setGalleryModeEnabled.bind(PrivateBluetoothSdkModule),
75
- setVoiceActivityDetectionEnabled: PrivateBluetoothSdkModule.setVoiceActivityDetectionEnabled.bind(PrivateBluetoothSdkModule),
76
+ setVoiceActivityDetectionEnabled:
77
+ PrivateBluetoothSdkModule.setVoiceActivityDetectionEnabled.bind(PrivateBluetoothSdkModule),
76
78
  setButtonPhotoSettings: PrivateBluetoothSdkModule.setButtonPhotoSettings.bind(PrivateBluetoothSdkModule),
77
- setButtonVideoRecordingSettings: PrivateBluetoothSdkModule.setButtonVideoRecordingSettings.bind(PrivateBluetoothSdkModule),
79
+ setButtonVideoRecordingSettings:
80
+ PrivateBluetoothSdkModule.setButtonVideoRecordingSettings.bind(PrivateBluetoothSdkModule),
78
81
  setButtonCameraLed: PrivateBluetoothSdkModule.setButtonCameraLed.bind(PrivateBluetoothSdkModule),
79
82
  setButtonMaxRecordingTime: PrivateBluetoothSdkModule.setButtonMaxRecordingTime.bind(PrivateBluetoothSdkModule),
80
83
  setCameraFov: PrivateBluetoothSdkModule.setCameraFov.bind(PrivateBluetoothSdkModule),
@@ -91,6 +94,21 @@ export const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({
91
94
  setGlassesMediaVolume: PrivateBluetoothSdkModule.setGlassesMediaVolume.bind(PrivateBluetoothSdkModule),
92
95
  rgbLedControl: PrivateBluetoothSdkModule.rgbLedControl.bind(PrivateBluetoothSdkModule),
93
96
  requestVersionInfo: PrivateBluetoothSdkModule.requestVersionInfo.bind(PrivateBluetoothSdkModule),
97
+ checkForOtaUpdate: PrivateBluetoothSdkModule.sendOtaQueryStatus.bind(PrivateBluetoothSdkModule),
98
+ startOtaUpdate: PrivateBluetoothSdkModule.sendOtaStart.bind(PrivateBluetoothSdkModule),
99
+ retryOtaVersionCheck: PrivateBluetoothSdkModule.retryOtaVersionCheck.bind(PrivateBluetoothSdkModule),
100
+ setSttModelDetails: PrivateBluetoothSdkModule.setSttModelDetails.bind(PrivateBluetoothSdkModule),
101
+ getSttModelPath: PrivateBluetoothSdkModule.getSttModelPath.bind(PrivateBluetoothSdkModule),
102
+ checkSttModelAvailable: PrivateBluetoothSdkModule.checkSttModelAvailable.bind(PrivateBluetoothSdkModule),
103
+ validateSttModel: PrivateBluetoothSdkModule.validateSttModel.bind(PrivateBluetoothSdkModule),
104
+ extractTarBz2: PrivateBluetoothSdkModule.extractTarBz2.bind(PrivateBluetoothSdkModule),
105
+ restartTranscriber: PrivateBluetoothSdkModule.restartTranscriber.bind(PrivateBluetoothSdkModule),
106
+ setTtsModelDetails: PrivateBluetoothSdkModule.setTtsModelDetails.bind(PrivateBluetoothSdkModule),
107
+ getTtsModelPath: PrivateBluetoothSdkModule.getTtsModelPath.bind(PrivateBluetoothSdkModule),
108
+ getTtsModelLanguage: PrivateBluetoothSdkModule.getTtsModelLanguage.bind(PrivateBluetoothSdkModule),
109
+ checkTtsModelAvailable: PrivateBluetoothSdkModule.checkTtsModelAvailable.bind(PrivateBluetoothSdkModule),
110
+ validateTtsModel: PrivateBluetoothSdkModule.validateTtsModel.bind(PrivateBluetoothSdkModule),
111
+ generateTtsAudio: PrivateBluetoothSdkModule.generateTtsAudio.bind(PrivateBluetoothSdkModule),
94
112
  })
95
113
 
96
114
  export default BluetoothSdk
@@ -108,6 +126,7 @@ export {
108
126
  } from "./BluetoothSdk.types"
109
127
 
110
128
  export type {
129
+ AccelEvent,
111
130
  AudioConnectedEvent,
112
131
  AudioDisconnectedEvent,
113
132
  AudioPairingNeededEvent,
@@ -120,7 +139,9 @@ export type {
120
139
  BluetoothSdkSubscription,
121
140
  ButtonPhotoSize,
122
141
  ButtonPressEvent,
123
- CameraFov,
142
+ CameraFovPreset,
143
+ CameraFovRequest,
144
+ CameraFovResult,
124
145
  CameraRoiPosition,
125
146
  CompatibleGlassesSearchStopEvent,
126
147
  ConnectOptions,
@@ -144,20 +165,37 @@ export type {
144
165
  MicMode,
145
166
  MicPcmEvent,
146
167
  MicPreference,
168
+ OtaStartAckEvent,
169
+ OtaStatus,
170
+ OtaStatusEvent,
171
+ OtaQueryResult,
172
+ OtaUpdateAvailableEvent,
173
+ OtaUpdateInfo,
147
174
  PairFailureEvent,
175
+ PhotoCaptureMetadata,
148
176
  PhotoResolvedConfig,
149
177
  PhotoCompression,
178
+ PhotoFpsRange,
179
+ PhotoMeteredPreview,
150
180
  PhotoResponseEvent,
181
+ PhotoRequestedCaptureConfig,
151
182
  PhotoSize,
152
183
  PhotoStatusEvent,
153
184
  PhotoStatusState,
185
+ PhotoSuccessResponseEvent,
154
186
  RgbLedAction,
155
187
  RgbLedColor,
156
188
  RgbLedControlResponseEvent,
189
+ RgbLedControlSuccessResponseEvent,
157
190
  ScanModelOptions,
158
191
  ScanOptions,
159
192
  ScanResultsCallback,
160
193
  SpeakingStatusEvent,
194
+ SettingsAckEvent,
195
+ SettingsAckSetting,
196
+ SettingsAckSuccessEvent,
197
+ SettingsAckSuccessStatus,
198
+ SettingsAckStatus,
161
199
  StreamAudioConfig,
162
200
  StreamResolvedConfig,
163
201
  StreamStartRequest,
@@ -169,6 +207,14 @@ export type {
169
207
  SwipeVolumeStatusEvent,
170
208
  SwitchStatusEvent,
171
209
  TouchEvent,
210
+ VideoRecordingStartedStatusEvent,
211
+ VideoRecordingStatusEvent,
212
+ VideoRecordingStatusState,
213
+ VideoRecordingStoppedStatusEvent,
214
+ VideoRecordingSuccessStatusEvent,
215
+ VersionInfoEvent,
216
+ VersionInfoResult,
217
+ WifiScanResultEvent,
172
218
  VoiceActivityDetectionStatusEvent,
173
219
  WifiSearchResult,
174
220
  WifiStatus,
@@ -2,6 +2,7 @@ import {useState} from "react"
2
2
 
3
3
  import BluetoothSdk from "../index"
4
4
  import {
5
+ DEFAULT_VOICE_ACTIVITY_DETECTION_ENABLED,
5
6
  DeviceModels,
6
7
  createDisconnectedGlassesStatus,
7
8
  isConnectedGlassesConnectionStatus,
@@ -16,6 +17,7 @@ import type {
16
17
  PublicBluetoothStatus,
17
18
  PublicGlassesStatus,
18
19
  MicMode,
20
+ SettingsAckSuccessEvent,
19
21
  WifiSearchResult,
20
22
  WifiStatus,
21
23
  } from "../BluetoothSdk.types"
@@ -134,7 +136,7 @@ export type MentraBluetoothSession = {
134
136
  scan: ScanController
135
137
  sdk: PhoneSdkRuntimeState
136
138
  setDefaultDevice: (device: Device | null) => Promise<void>
137
- setGalleryModeEnabled: (enabled: boolean) => Promise<void>
139
+ setGalleryModeEnabled: (enabled: boolean) => Promise<SettingsAckSuccessEvent>
138
140
  setVoiceActivityDetectionEnabled: (enabled: boolean) => Promise<void>
139
141
  }
140
142
 
@@ -221,7 +223,7 @@ function runtimeGlassesState(status: Partial<PublicGlassesStatus>): GlassesRunti
221
223
  strengthDbm: numberValue((status as Record<string, unknown>).signalStrength),
222
224
  updatedAt: numberValue((status as Record<string, unknown>).signalStrengthUpdatedAt),
223
225
  },
224
- voiceActivityDetectionEnabled: status.voiceActivityDetectionEnabled ?? true,
226
+ voiceActivityDetectionEnabled: status.voiceActivityDetectionEnabled ?? DEFAULT_VOICE_ACTIVITY_DETECTION_ENABLED,
225
227
  wifi: status.wifi ?? {state: "disconnected"},
226
228
  }
227
229
  }
@@ -271,11 +273,11 @@ export function useMentraBluetooth(options: UseMentraBluetoothOptions = {}): Men
271
273
  const [galleryModeApplying, setGalleryModeApplying] = useState(false)
272
274
  const [galleryModeError, setGalleryModeError] = useState<unknown | null>(null)
273
275
 
274
- async function setGalleryModeEnabled(enabled: boolean) {
276
+ async function setGalleryModeEnabled(enabled: boolean): Promise<SettingsAckSuccessEvent> {
275
277
  setGalleryModeApplying(true)
276
278
  setGalleryModeError(null)
277
279
  try {
278
- await BluetoothSdk.setGalleryModeEnabled(enabled)
280
+ return await BluetoothSdk.setGalleryModeEnabled(enabled)
279
281
  } catch (error) {
280
282
  setGalleryModeError(error)
281
283
  options.onError?.(error)
package/android/.project DELETED
@@ -1,28 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <projectDescription>
3
- <name>mentra-bluetooth-sdk</name>
4
- <comment>Project mentra-bluetooth-sdk created by Buildship.</comment>
5
- <projects>
6
- </projects>
7
- <buildSpec>
8
- <buildCommand>
9
- <name>org.eclipse.buildship.core.gradleprojectbuilder</name>
10
- <arguments>
11
- </arguments>
12
- </buildCommand>
13
- </buildSpec>
14
- <natures>
15
- <nature>org.eclipse.buildship.core.gradleprojectnature</nature>
16
- </natures>
17
- <filteredResources>
18
- <filter>
19
- <id>1779400133450</id>
20
- <name></name>
21
- <type>30</type>
22
- <matcher>
23
- <id>org.eclipse.core.resources.regexFilterMatcher</id>
24
- <arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
25
- </matcher>
26
- </filter>
27
- </filteredResources>
28
- </projectDescription>