@mentra/bluetooth-sdk 0.1.2 → 0.1.3

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 (59) hide show
  1. package/README.md +33 -19
  2. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +13 -13
  3. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +42 -18
  4. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +19 -21
  5. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +4 -4
  6. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +118 -103
  7. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +110 -38
  8. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +4 -4
  9. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +2 -2
  10. package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +6 -6
  11. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +1 -1
  12. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3 -3
  13. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1 -1
  14. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +18 -18
  15. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1 -1
  16. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +4 -4
  17. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +2 -2
  18. package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +6 -6
  19. package/build/BluetoothSdk.types.d.ts +126 -27
  20. package/build/BluetoothSdk.types.d.ts.map +1 -1
  21. package/build/BluetoothSdk.types.js.map +1 -1
  22. package/build/_internal.d.ts +12 -0
  23. package/build/_internal.d.ts.map +1 -0
  24. package/build/_internal.js +11 -0
  25. package/build/_internal.js.map +1 -0
  26. package/build/{BluetoothSdkModule.d.ts → _private/BluetoothSdkModule.d.ts} +19 -8
  27. package/build/_private/BluetoothSdkModule.d.ts.map +1 -0
  28. package/build/{BluetoothSdkModule.js → _private/BluetoothSdkModule.js} +41 -26
  29. package/build/_private/BluetoothSdkModule.js.map +1 -0
  30. package/build/index.d.ts +4 -2
  31. package/build/index.d.ts.map +1 -1
  32. package/build/index.js +3 -4
  33. package/build/index.js.map +1 -1
  34. package/ios/BluetoothSdkModule.swift +14 -9
  35. package/ios/Source/Bridge.swift +44 -12
  36. package/ios/Source/DeviceManager.swift +27 -26
  37. package/ios/Source/DeviceStore.swift +4 -4
  38. package/ios/Source/MentraBluetoothSDK.swift +250 -132
  39. package/ios/Source/controllers/ControllerManager.swift +5 -5
  40. package/ios/Source/controllers/R1.swift +3 -3
  41. package/ios/Source/services/PhoneMic.swift +5 -5
  42. package/ios/Source/sgcs/Frame.swift +1 -1
  43. package/ios/Source/sgcs/G1.swift +1 -1
  44. package/ios/Source/sgcs/G2.swift +3 -3
  45. package/ios/Source/sgcs/Mach1.swift +1 -1
  46. package/ios/Source/sgcs/MentraLive.swift +31 -33
  47. package/ios/Source/sgcs/MentraNex.swift +2 -2
  48. package/ios/Source/sgcs/SGCManager.swift +5 -5
  49. package/ios/Source/sgcs/Simulated.swift +3 -3
  50. package/ios/Source/utils/Constants.swift +6 -6
  51. package/ios/Source/utils/JSCExperiment.swift +8 -8
  52. package/ios/Source/utils/TarBz2Extractor.swift +2 -2
  53. package/package.json +13 -1
  54. package/src/BluetoothSdk.types.ts +186 -28
  55. package/src/_internal.ts +11 -0
  56. package/src/{BluetoothSdkModule.ts → _private/BluetoothSdkModule.ts} +71 -38
  57. package/src/index.ts +80 -4
  58. package/build/BluetoothSdkModule.d.ts.map +0 -1
  59. package/build/BluetoothSdkModule.js.map +0 -1
@@ -6,13 +6,22 @@ const DEFAULT_CONNECT_OPTIONS = {
6
6
  saveAsDefault: true,
7
7
  cancelExistingConnectionAttempt: true,
8
8
  };
9
- const DEFAULT_CONNECT_FIRST_TIMEOUT_MS = 15_000;
9
+ const DEFAULT_SCAN_TIMEOUT_MS = 15_000;
10
10
  const CAMERA_FOV_SETTINGS = {
11
- standard: { fov: 118, roi_position: 0 },
12
- wide: { fov: 118, roi_position: 0 },
11
+ standard: { fov: 118, roiPosition: 0 },
12
+ wide: { fov: 118, roiPosition: 0 },
13
13
  };
14
- function findSearchResult(status, model) {
15
- return status.searchResults?.find((device) => device.model === model) ?? null;
14
+ function searchResultsForModel(status, model) {
15
+ return status.searchResults?.filter((device) => device.model === model) ?? [];
16
+ }
17
+ function normalizeScanArgs(modelOrOptions, options) {
18
+ if (typeof modelOrOptions === "string") {
19
+ return { model: modelOrOptions, ...options };
20
+ }
21
+ return modelOrOptions;
22
+ }
23
+ function normalizeTimeoutMs(timeoutMs, defaultTimeoutMs) {
24
+ return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : defaultTimeoutMs;
16
25
  }
17
26
  function dashboardMenuItemToNative(item) {
18
27
  return {
@@ -131,11 +140,11 @@ NativeBluetoothSdkModule.setScreenDisabled = function (disabled) {
131
140
  NativeBluetoothSdkModule.setButtonPhotoSettings = function (size) {
132
141
  return this.updateBluetoothSettings({ button_photo_size: size });
133
142
  };
134
- NativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width, height, fps) {
143
+ NativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width, height, frameRate) {
135
144
  return this.updateBluetoothSettings({
136
145
  button_video_width: width,
137
146
  button_video_height: height,
138
- button_video_fps: fps,
147
+ button_video_fps: frameRate,
139
148
  });
140
149
  };
141
150
  NativeBluetoothSdkModule.setButtonCameraLed = function (enabled) {
@@ -171,19 +180,29 @@ NativeBluetoothSdkModule.connectDefault = function (options) {
171
180
  NativeBluetoothSdkModule.connect = function (device, options) {
172
181
  return this.connectWithOptions(device, { ...DEFAULT_CONNECT_OPTIONS, ...options });
173
182
  };
174
- NativeBluetoothSdkModule.connectFirst = async function (model, options) {
175
- const { timeoutMs = DEFAULT_CONNECT_FIRST_TIMEOUT_MS, ...connectOptions } = options ?? {};
176
- const device = await new Promise((resolve, reject) => {
183
+ NativeBluetoothSdkModule.scan = async function (modelOrOptions, options) {
184
+ const scanOptions = normalizeScanArgs(modelOrOptions, options);
185
+ const timeoutMs = normalizeTimeoutMs(scanOptions.timeoutMs ?? scanOptions.timeout, DEFAULT_SCAN_TIMEOUT_MS);
186
+ let latestResults = [];
187
+ return new Promise((resolve, reject) => {
177
188
  let timeout = null;
178
189
  let removeBluetoothListener = () => { };
179
190
  let settled = false;
191
+ let scanStarted = false;
192
+ const emitResults = (devices) => {
193
+ latestResults = devices;
194
+ scanOptions.onResults?.([...devices]);
195
+ };
180
196
  const cleanup = () => {
181
197
  if (timeout) {
182
198
  clearTimeout(timeout);
183
199
  }
184
200
  removeBluetoothListener();
201
+ if (scanStarted) {
202
+ void Promise.resolve(this.stopScan()).catch(() => undefined);
203
+ }
185
204
  };
186
- const settle = (error, result) => {
205
+ const settle = (error) => {
187
206
  if (settled) {
188
207
  return;
189
208
  }
@@ -192,29 +211,25 @@ NativeBluetoothSdkModule.connectFirst = async function (model, options) {
192
211
  if (error) {
193
212
  reject(error);
194
213
  }
195
- else if (result) {
196
- resolve(result);
214
+ else {
215
+ resolve([...latestResults]);
197
216
  }
198
217
  };
199
218
  const handleBluetoothStatus = (status) => {
200
- const result = findSearchResult(status, model);
201
- if (result) {
202
- settle(null, result);
203
- }
219
+ emitResults(searchResultsForModel(status, scanOptions.model));
204
220
  };
205
221
  removeBluetoothListener = this.onBluetoothStatus(handleBluetoothStatus);
206
- if (Number.isFinite(timeoutMs) && timeoutMs > 0) {
207
- timeout = setTimeout(() => {
208
- settle(new Error(`Timed out after ${timeoutMs}ms while scanning for ${model}.`));
209
- }, timeoutMs);
210
- }
211
- Promise.resolve(this.startScan(model))
212
- .then(() => this.getBluetoothStatus())
222
+ emitResults([]);
223
+ timeout = setTimeout(() => settle(), timeoutMs);
224
+ Promise.resolve(this.startScan(scanOptions.model))
225
+ .then(() => {
226
+ scanStarted = true;
227
+ return this.getBluetoothStatus();
228
+ })
213
229
  .then(handleBluetoothStatus)
214
230
  .catch((error) => settle(error instanceof Error ? error : new Error(String(error))));
215
231
  });
216
- await this.connect(device, connectOptions);
217
- return device;
218
232
  };
219
233
  export default NativeBluetoothSdkModule;
234
+ export const BluetoothSdk = NativeBluetoothSdkModule;
220
235
  //# sourceMappingURL=BluetoothSdkModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BluetoothSdkModule.js","sourceRoot":"","sources":["../../src/_private/BluetoothSdkModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {NativeModule, requireNativeModule} from \"expo\"\n\nimport {\n BluetoothSettingsUpdate,\n BluetoothSdkPublicModule,\n BluetoothSdkModuleEvents,\n BluetoothStatus,\n ButtonPhotoSize,\n CameraFov,\n CameraFovSetting,\n ConnectOptions,\n DashboardMenuItem,\n Device,\n DeviceModel,\n GalleryMode,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesStatus,\n MicPreference,\n ObservableStoreCategory,\n PhotoCompression,\n PhotoSize,\n RgbLedAction,\n RgbLedColor,\n ScanModelOptions,\n ScanOptions,\n StreamKeepAliveRequest,\n StreamStartRequest,\n} from \"../BluetoothSdk.types\"\n\n/**\n * Private React Native native-module facade.\n *\n * This file intentionally lives under `_private` so the package root can expose\n * a small SDK surface while MentraOS uses its monorepo-only internal alias\n * during migration.\n */\n\ntype GlassesListener = (changed: Partial<GlassesStatus>) => void\ntype BluetoothStatusListener = (changed: Partial<BluetoothStatus>) => void\ntype MaybePromise<T> = T | Promise<T>\n\ndeclare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEvents> {\n // Observable Store Functions (native)\n getGlassesStatus(): Promise<GlassesStatus>\n getBluetoothStatus(): Promise<BluetoothStatus>\n getDefaultDevice(): Promise<Device | null>\n update(category: ObservableStoreCategory, values: object): Promise<void>\n\n // Display Commands\n displayEvent(params: Record<string, unknown>): Promise<void>\n displayText(text: string, x?: number, y?: number, size?: number): Promise<void>\n clearDisplay(): Promise<void>\n\n // Connection Commands\n requestStatus(): Promise<void>\n connectDefault(options?: ConnectOptions): Promise<void>\n connectDefaultWithOptions(options: Required<ConnectOptions>): Promise<void>\n setDefaultDevice(device: Device | null): Promise<void>\n clearDefaultDevice(): Promise<void>\n startScan(model: DeviceModel): Promise<void>\n stopScan(): Promise<void>\n scan(options: ScanOptions): Promise<Device[]>\n scan(model: DeviceModel, options?: ScanModelOptions): Promise<Device[]>\n connect(device: Device, options?: ConnectOptions): Promise<void>\n connectWithOptions(device: Device, options: Required<ConnectOptions>): Promise<void>\n cancelConnectionAttempt(): Promise<void>\n connectDefaultController(): Promise<void>\n disconnectController(): Promise<void>\n connectSimulated(): Promise<void>\n disconnect(): Promise<void>\n forget(): Promise<void>\n forgetController(): Promise<void>\n showDashboard(): Promise<void>\n setBrightness(level: number, autoMode?: boolean | null): Promise<void>\n setAutoBrightness(enabled: boolean): Promise<void>\n setDashboardPosition(height: number, depth: number): Promise<void>\n setDashboardMenu(items: DashboardMenuItem[]): Promise<void>\n setHeadUpAngle(angleDegrees: number): Promise<void>\n setScreenDisabled(disabled: boolean): Promise<void>\n ping(): Promise<void>\n dbg1(): Promise<void>\n dbg2(): Promise<void>\n\n // Incident Reporting\n sendIncidentId(incidentId: string, apiBaseUrl?: string | null): Promise<void>\n\n // WiFi Commands\n requestWifiScan(): Promise<void>\n sendWifiCredentials(ssid: string, password: string): Promise<void>\n forgetWifiNetwork(ssid: string): Promise<void>\n setHotspotState(enabled: boolean): Promise<void>\n /** Logs current WiFi frequency (MHz) and 5 GHz band to Android logcat. */\n logCurrentWifiFrequency(): Promise<void>\n\n // Gallery Commands\n setGalleryMode(mode: GalleryMode): Promise<void>\n setButtonPhotoSettings(size: ButtonPhotoSize): Promise<void>\n setButtonVideoRecordingSettings(width: number, height: number, frameRate: number): Promise<void>\n setButtonCameraLed(enabled: boolean): Promise<void>\n setButtonMaxRecordingTime(minutes: number): Promise<void>\n setCameraFov(fov: CameraFov): Promise<void>\n queryGalleryStatus(): Promise<void>\n requestPhoto(\n requestId: string,\n appId: string,\n size: PhotoSize,\n webhookUrl: string | null,\n authToken: string | null,\n compress: PhotoCompression,\n sound: boolean,\n ): Promise<void>\n\n // OTA Commands\n sendOtaStart(): Promise<void>\n sendOtaQueryStatus(): Promise<void>\n\n // Version Info Commands\n requestVersionInfo(): Promise<void>\n\n // Video Recording Commands\n startVideoRecording(requestId: string, save: boolean, sound: boolean): Promise<void>\n stopVideoRecording(requestId: string): Promise<void>\n\n // Stream Commands\n startStream(params: StreamStartRequest): Promise<void>\n stopStream(): Promise<void>\n keepStreamAlive(params: StreamKeepAliveRequest): Promise<void>\n\n // Microphone Commands\n setMicState(\n enabled: boolean,\n useGlassesMic?: boolean,\n bypassVad?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n ): Promise<void>\n setPreferredMic(preferredMic: MicPreference): Promise<void>\n restartTranscriber(): Promise<void>\n\n // Audio Playback Monitoring\n // Notify native side when our app starts/stops playing audio\n // Used to suspend LC3 mic during audio playback to avoid MCU overload\n setOwnAppAudioPlaying(playing: boolean): Promise<void>\n\n /** Mentra Live only: K900 `cs_getvol` / `sr_getvol`. */\n getGlassesMediaVolume(): Promise<GlassesMediaVolumeGetResult>\n /** Mentra Live only: K900 `cs_vol` / `sr_vol`; level clamped 0–15 on native. */\n setGlassesMediaVolume(level: number): Promise<GlassesMediaVolumeSetResult>\n\n // RGB LED Control\n rgbLedControl(\n requestId: string,\n packageName: string | null,\n action: RgbLedAction,\n color: RgbLedColor | null,\n onDurationMs: number,\n offDurationMs: number,\n count: number,\n ): Promise<void>\n\n // STT Commands\n setSttModelDetails(path: string, languageCode: string): Promise<void>\n getSttModelPath(): Promise<string>\n checkSttModelAvailable(): Promise<boolean>\n validateSttModel(path: string): Promise<boolean>\n extractTarBz2(sourcePath: string, destinationPath: string): Promise<boolean>\n\n // Helper methods for type-safe observable store access\n updateGlasses(values: Partial<GlassesStatus>): Promise<void>\n updateBluetoothSettings(values: BluetoothSettingsUpdate): Promise<void>\n onGlassesStatus(callback: GlassesListener): () => void\n onBluetoothStatus(callback: BluetoothStatusListener): () => void\n\n // Process resident-set-size in MB. iOS-only; Android stub returns 0.\n getMemoryMB(): number\n}\n\nexport type BluetoothSdkInternalModule = BluetoothSdkNativeModule\n\n// This call loads the native module object from the JSI.\n// NativeModule<BluetoothSdkModuleEvents> already extends EventEmitter<BluetoothSdkModuleEvents>\nconst NativeBluetoothSdkModule = requireNativeModule<BluetoothSdkNativeModule>(\"BluetoothSdk\")\n\nconst DEFAULT_CONNECT_OPTIONS: Required<ConnectOptions> = {\n saveAsDefault: true,\n cancelExistingConnectionAttempt: true,\n}\n\nconst DEFAULT_SCAN_TIMEOUT_MS = 15_000\n\nconst CAMERA_FOV_SETTINGS: Record<CameraFov, CameraFovSetting> = {\n standard: {fov: 118, roiPosition: 0},\n wide: {fov: 118, roiPosition: 0},\n}\n\nfunction searchResultsForModel(status: Partial<BluetoothStatus>, model: DeviceModel): Device[] {\n return status.searchResults?.filter((device) => device.model === model) ?? []\n}\n\nfunction normalizeScanArgs(modelOrOptions: DeviceModel | ScanOptions, options?: ScanModelOptions): ScanOptions {\n if (typeof modelOrOptions === \"string\") {\n return {model: modelOrOptions, ...options}\n }\n return modelOrOptions\n}\n\nfunction normalizeTimeoutMs(timeoutMs: number | undefined, defaultTimeoutMs: number): number {\n return typeof timeoutMs === \"number\" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : defaultTimeoutMs\n}\n\nfunction dashboardMenuItemToNative(item: DashboardMenuItem): Record<string, unknown> {\n return {\n ...(item.values ?? {}),\n title: item.title,\n packageName: item.packageName,\n }\n}\n\nfunction adaptConnectionStatusToNative(connection: GlassesStatus[\"connection\"]): Record<string, unknown> {\n switch (connection.state) {\n case \"connected\":\n return {connectionState: \"CONNECTED\", connected: true, fullyBooted: connection.fullyBooted}\n case \"scanning\":\n return {connectionState: \"SCANNING\", connected: false, fullyBooted: false}\n case \"connecting\":\n return {connectionState: \"CONNECTING\", connected: false, fullyBooted: false}\n case \"bonding\":\n return {connectionState: \"BONDING\", connected: false, fullyBooted: false}\n case \"disconnected\":\n return {connectionState: \"DISCONNECTED\", connected: false, fullyBooted: false}\n }\n}\n\nfunction adaptGlassesUpdateToNative(values: Partial<GlassesStatus>): Record<string, unknown> {\n const {wifi, hotspot, connection, ...rest} = values\n let update: Record<string, unknown> = {...rest}\n if (connection) {\n update = {\n ...update,\n ...adaptConnectionStatusToNative(connection),\n }\n }\n if (wifi?.state === \"connected\") {\n update = {\n ...update,\n wifiConnected: true,\n wifiSsid: wifi.ssid,\n wifiLocalIp: wifi.localIp ?? \"\",\n }\n } else if (wifi?.state === \"disconnected\") {\n update = {\n ...update,\n wifiConnected: false,\n wifiSsid: \"\",\n wifiLocalIp: \"\",\n }\n }\n if (hotspot?.state === \"enabled\") {\n update = {\n ...update,\n hotspotEnabled: true,\n hotspotSsid: hotspot.ssid,\n hotspotPassword: hotspot.password,\n hotspotGatewayIp: hotspot.localIp,\n }\n } else if (hotspot?.state === \"disabled\") {\n update = {\n ...update,\n hotspotEnabled: false,\n hotspotSsid: \"\",\n hotspotPassword: \"\",\n hotspotGatewayIp: \"\",\n }\n }\n return update\n}\n\n// Add helper methods to the module\nconst nativeGetGlassesStatus = NativeBluetoothSdkModule.getGlassesStatus.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<GlassesStatus>\nNativeBluetoothSdkModule.getGlassesStatus = function () {\n return Promise.resolve(nativeGetGlassesStatus())\n}\n\nconst nativeGetBluetoothStatus = NativeBluetoothSdkModule.getBluetoothStatus.bind(NativeBluetoothSdkModule) as () => MaybePromise<BluetoothStatus>\nNativeBluetoothSdkModule.getBluetoothStatus = function () {\n return Promise.resolve(nativeGetBluetoothStatus())\n}\n\nconst nativeGetDefaultDevice = NativeBluetoothSdkModule.getDefaultDevice.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<Device | null>\nNativeBluetoothSdkModule.getDefaultDevice = function () {\n return Promise.resolve(nativeGetDefaultDevice())\n}\n\nconst nativeSetMicState = NativeBluetoothSdkModule.setMicState.bind(NativeBluetoothSdkModule) as (\n enabled: boolean,\n useGlassesMic: boolean,\n bypassVad: boolean,\n sendTranscript: boolean,\n sendLc3Data: boolean,\n) => MaybePromise<void>\n\nconst nativeDisplayText = NativeBluetoothSdkModule.displayText.bind(NativeBluetoothSdkModule) as (\n text: string,\n x: number,\n y: number,\n size: number,\n) => MaybePromise<void>\n\nNativeBluetoothSdkModule.updateGlasses = function (values: Partial<GlassesStatus>) {\n return this.update(\"glasses\", adaptGlassesUpdateToNative(values))\n}\n\nNativeBluetoothSdkModule.updateBluetoothSettings = function (values: BluetoothSettingsUpdate) {\n return this.update(\"bluetooth\", values)\n}\n\nNativeBluetoothSdkModule.displayText = function (text: string, x?: number, y?: number, size?: number) {\n return Promise.resolve(nativeDisplayText(text, x ?? 0, y ?? 0, size ?? 24))\n}\n\nNativeBluetoothSdkModule.setBrightness = function (level: number, autoMode?: boolean | null) {\n return this.updateBluetoothSettings({\n ...(autoMode == null ? {} : {auto_brightness: autoMode}),\n brightness: level,\n })\n}\n\nNativeBluetoothSdkModule.setAutoBrightness = function (enabled: boolean) {\n return this.updateBluetoothSettings({auto_brightness: enabled})\n}\n\nNativeBluetoothSdkModule.setDashboardPosition = function (height: number, depth: number) {\n return this.updateBluetoothSettings({\n dashboard_height: height,\n dashboard_depth: depth,\n })\n}\n\nNativeBluetoothSdkModule.setDashboardMenu = function (items: DashboardMenuItem[]) {\n return this.updateBluetoothSettings({menu_apps: items.map(dashboardMenuItemToNative)})\n}\n\nNativeBluetoothSdkModule.setHeadUpAngle = function (angleDegrees: number) {\n return this.updateBluetoothSettings({head_up_angle: angleDegrees})\n}\n\nNativeBluetoothSdkModule.setScreenDisabled = function (disabled: boolean) {\n return this.updateBluetoothSettings({screen_disabled: disabled})\n}\n\nNativeBluetoothSdkModule.setButtonPhotoSettings = function (size: ButtonPhotoSize) {\n return this.updateBluetoothSettings({button_photo_size: size})\n}\n\nNativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width: number, height: number, frameRate: number) {\n return this.updateBluetoothSettings({\n button_video_width: width,\n button_video_height: height,\n button_video_fps: frameRate,\n })\n}\n\nNativeBluetoothSdkModule.setButtonCameraLed = function (enabled: boolean) {\n return this.updateBluetoothSettings({button_camera_led: enabled})\n}\n\nNativeBluetoothSdkModule.setButtonMaxRecordingTime = function (minutes: number) {\n return this.updateBluetoothSettings({button_max_recording_time: minutes})\n}\n\nNativeBluetoothSdkModule.setCameraFov = function (fov: CameraFov) {\n return this.updateBluetoothSettings({camera_fov: CAMERA_FOV_SETTINGS[fov]})\n}\n\nNativeBluetoothSdkModule.setMicState = function (\n enabled: boolean,\n useGlassesMic?: boolean,\n bypassVad?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n) {\n return Promise.resolve(\n nativeSetMicState(\n enabled,\n useGlassesMic ?? true,\n bypassVad ?? false,\n sendTranscript ?? false,\n sendLc3Data ?? false,\n ),\n )\n}\n\nNativeBluetoothSdkModule.setPreferredMic = function (preferredMic: MicPreference) {\n return this.updateBluetoothSettings({preferred_mic: preferredMic})\n}\n\nNativeBluetoothSdkModule.onGlassesStatus = function (callback: GlassesListener) {\n const subscription = this.addListener(\"glasses_status\", callback)\n return () => subscription.remove()\n}\n\nNativeBluetoothSdkModule.onBluetoothStatus = function (callback: BluetoothStatusListener) {\n const subscription = this.addListener(\"bluetooth_status\", callback)\n return () => subscription.remove()\n}\n\nconst nativeConnectDefault = NativeBluetoothSdkModule.connectDefault.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.connectDefault = function (options?: ConnectOptions) {\n if (!options) {\n return nativeConnectDefault()\n }\n return this.connectDefaultWithOptions({...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nNativeBluetoothSdkModule.connect = function (device: Device, options?: ConnectOptions) {\n return this.connectWithOptions(device, {...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nNativeBluetoothSdkModule.scan = async function (\n modelOrOptions: DeviceModel | ScanOptions,\n options?: ScanModelOptions,\n) {\n const scanOptions = normalizeScanArgs(modelOrOptions, options)\n const timeoutMs = normalizeTimeoutMs(scanOptions.timeoutMs ?? scanOptions.timeout, DEFAULT_SCAN_TIMEOUT_MS)\n let latestResults: Device[] = []\n\n return new Promise<Device[]>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout> | null = null\n let removeBluetoothListener = () => {}\n let settled = false\n let scanStarted = false\n\n const emitResults = (devices: Device[]) => {\n latestResults = devices\n scanOptions.onResults?.([...devices])\n }\n\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout)\n }\n removeBluetoothListener()\n if (scanStarted) {\n void Promise.resolve(this.stopScan()).catch(() => undefined)\n }\n }\n\n const settle = (error?: Error) => {\n if (settled) {\n return\n }\n settled = true\n cleanup()\n if (error) {\n reject(error)\n } else {\n resolve([...latestResults])\n }\n }\n\n const handleBluetoothStatus = (status: Partial<BluetoothStatus>) => {\n emitResults(searchResultsForModel(status, scanOptions.model))\n }\n\n removeBluetoothListener = this.onBluetoothStatus(handleBluetoothStatus)\n emitResults([])\n\n timeout = setTimeout(() => settle(), timeoutMs)\n\n Promise.resolve(this.startScan(scanOptions.model))\n .then(() => {\n scanStarted = true\n return this.getBluetoothStatus()\n })\n .then(handleBluetoothStatus)\n .catch((error) => settle(error instanceof Error ? error : new Error(String(error))))\n })\n}\n\nexport default NativeBluetoothSdkModule\nexport const BluetoothSdk = NativeBluetoothSdkModule as BluetoothSdkPublicModule\n"]}
package/build/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
- export { default } from "./BluetoothSdkModule";
2
- export * from "./BluetoothSdk.types";
1
+ import { BluetoothSdk } from "./_private/BluetoothSdkModule";
2
+ export default BluetoothSdk;
3
+ export { DeviceModels, createDisconnectedGlassesStatus, isBusyGlassesConnectionStatus, isConnectedGlassesConnectionStatus, isConnectedWifiStatus, isEnabledHotspotStatus, isReadyGlassesConnectionStatus, } from "./BluetoothSdk.types";
4
+ export type { AudioConnectedEvent, AudioDisconnectedEvent, AudioPairingNeededEvent, BatteryStatusEvent, BluetoothSdkEvent, BluetoothSdkEventListener, BluetoothSdkEventMap, BluetoothSdkEventName, BluetoothSdkPublicModule as BluetoothSdkModule, BluetoothSdkSubscription, ButtonPhotoSize, ButtonPressEvent, CameraFov, CompatibleGlassesSearchStopEvent, ConnectOptions, ConnectedGlassesConnectionStatus, ConnectedWifiStatus, Device, DeviceModel, EnabledHotspotStatus, GalleryMode, GalleryStatusEvent, GlassesConnectionStatus, GlassesMediaVolumeGetResult, GlassesMediaVolumeSetResult, GlassesNotReadyEvent, HeadUpEvent, HotspotErrorEvent, HotspotStatus, HotspotStatusChangeEvent, KeepAliveAckEvent, LocalTranscriptionEvent, LogEvent, MicLc3Event, MicMode, MicPcmEvent, MicPreference, PairFailureEvent, PhotoCompression, PhotoResponseEvent, PhotoSize, PublicBluetoothStatus as BluetoothStatus, PublicGlassesStatus as GlassesStatus, RgbLedAction, RgbLedColor, RgbLedControlResponseEvent, ScanModelOptions, ScanOptions, ScanResultsCallback, StreamAudioConfig, StreamKeepAliveRequest, StreamStartRequest, StreamStatusEvent, StreamStatusLifecycleState, StreamStatusReconnectState, StreamStatusState, StreamVideoConfig, SwipeVolumeStatusEvent, SwitchStatusEvent, TouchEvent, VadStatusEvent, WifiSearchResult, WifiStatus, WifiStatusChangeEvent, } from "./BluetoothSdk.types";
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,OAAO,EAAC,MAAM,sBAAsB,CAAA;AAC5C,cAAc,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,+BAA+B,CAAA;AAE1D,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,YAAY,EACZ,+BAA+B,EAC/B,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,IAAI,kBAAkB,EAC9C,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,gCAAgC,EAChC,cAAc,EACd,gCAAgC,EAChC,mBAAmB,EACnB,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,iBAAiB,EACjB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,OAAO,EACP,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,EACT,qBAAqB,IAAI,eAAe,EACxC,mBAAmB,IAAI,aAAa,EACpC,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,gBAAgB,EAChB,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,sBAAsB,CAAA"}
package/build/index.js CHANGED
@@ -1,5 +1,4 @@
1
- // Reexport the native module. On web, it will be resolved to BluetoothSdkModule.web.ts
2
- // and on native platforms to BluetoothSdkModule.ts
3
- export { default } from "./BluetoothSdkModule";
4
- export * from "./BluetoothSdk.types";
1
+ import { BluetoothSdk } from "./_private/BluetoothSdkModule";
2
+ export default BluetoothSdk;
3
+ export { DeviceModels, createDisconnectedGlassesStatus, isBusyGlassesConnectionStatus, isConnectedGlassesConnectionStatus, isConnectedWifiStatus, isEnabledHotspotStatus, isReadyGlassesConnectionStatus, } from "./BluetoothSdk.types";
5
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,mDAAmD;AACnD,OAAO,EAAC,OAAO,EAAC,MAAM,sBAAsB,CAAA;AAC5C,cAAc,sBAAsB,CAAA","sourcesContent":["// Reexport the native module. On web, it will be resolved to BluetoothSdkModule.web.ts\n// and on native platforms to BluetoothSdkModule.ts\nexport {default} from \"./BluetoothSdkModule\"\nexport * from \"./BluetoothSdk.types\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,+BAA+B,CAAA;AAE1D,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,YAAY,EACZ,+BAA+B,EAC/B,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA","sourcesContent":["import {BluetoothSdk} from \"./_private/BluetoothSdkModule\"\n\nexport default BluetoothSdk\n\nexport {\n DeviceModels,\n createDisconnectedGlassesStatus,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\n AudioConnectedEvent,\n AudioDisconnectedEvent,\n AudioPairingNeededEvent,\n BatteryStatusEvent,\n BluetoothSdkEvent,\n BluetoothSdkEventListener,\n BluetoothSdkEventMap,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule as BluetoothSdkModule,\n BluetoothSdkSubscription,\n ButtonPhotoSize,\n ButtonPressEvent,\n CameraFov,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryMode,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n KeepAliveAckEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicMode,\n MicPcmEvent,\n MicPreference,\n PairFailureEvent,\n PhotoCompression,\n PhotoResponseEvent,\n PhotoSize,\n PublicBluetoothStatus as BluetoothStatus,\n PublicGlassesStatus as GlassesStatus,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n ScanModelOptions,\n ScanOptions,\n ScanResultsCallback,\n StreamAudioConfig,\n StreamKeepAliveRequest,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VadStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n"]}
@@ -193,6 +193,12 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
193
193
  }
194
194
  }
195
195
 
196
+ AsyncFunction("stopScan") {
197
+ await MainActor.run {
198
+ self.bluetoothSdk().stopScan()
199
+ }
200
+ }
201
+
196
202
  AsyncFunction("cancelConnectionAttempt") {
197
203
  await MainActor.run {
198
204
  self.bluetoothSdk().cancelConnectionAttempt()
@@ -308,10 +314,10 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
308
314
  }
309
315
  }
310
316
 
311
- AsyncFunction("photoRequest") {
317
+ AsyncFunction("requestPhoto") {
312
318
  (
313
319
  requestId: String, appId: String, size: String, webhookUrl: String?,
314
- authToken: String?, compress: String?, flash: Bool, sound: Bool
320
+ authToken: String?, compress: String?, sound: Bool
315
321
  ) in
316
322
  await MainActor.run {
317
323
  self.bluetoothSdk().requestPhoto(
@@ -322,7 +328,6 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
322
328
  webhookUrl: webhookUrl,
323
329
  authToken: authToken,
324
330
  compress: compress.flatMap(PhotoCompression.init(rawValue:)),
325
- flash: flash,
326
331
  sound: sound
327
332
  )
328
333
  )
@@ -367,10 +372,10 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
367
372
 
368
373
  // MARK: - Video Recording Commands
369
374
 
370
- AsyncFunction("startVideoRecording") { (requestId: String, save: Bool, flash: Bool, sound: Bool) in
375
+ AsyncFunction("startVideoRecording") { (requestId: String, save: Bool, sound: Bool) in
371
376
  await MainActor.run {
372
377
  self.bluetoothSdk().startVideoRecording(
373
- VideoRecordingRequest(requestId: requestId, save: save, flash: flash, sound: sound)
378
+ VideoRecordingRequest(requestId: requestId, save: save, sound: sound)
374
379
  )
375
380
  }
376
381
  }
@@ -422,7 +427,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
422
427
  AsyncFunction("rgbLedControl") {
423
428
  (
424
429
  requestId: String, packageName: String?, action: String, color: String?,
425
- ontime: Int, offtime: Int, count: Int
430
+ onDurationMs: Int, offDurationMs: Int, count: Int
426
431
  ) in
427
432
  await MainActor.run {
428
433
  self.bluetoothSdk().rgbLedControl(
@@ -431,8 +436,8 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
431
436
  packageName: packageName,
432
437
  action: RgbLedAction(rawValue: action) ?? .off,
433
438
  color: color.flatMap(RgbLedColor.init(rawValue:)),
434
- ontime: ontime,
435
- offtime: offtime,
439
+ onDurationMs: onDurationMs,
440
+ offDurationMs: offDurationMs,
436
441
  count: count
437
442
  )
438
443
  )
@@ -545,7 +550,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
545
550
  "compatible_glasses_search_stop",
546
551
  [
547
552
  "type": "compatible_glasses_search_stop",
548
- "device_model": deviceModel,
553
+ "deviceModel": deviceModel,
549
554
  ]
550
555
  )
551
556
  }
@@ -126,18 +126,48 @@ class Bridge {
126
126
  if let rssi {
127
127
  newResult["rssi"] = rssi
128
128
  }
129
- let allResults = searchResults + [newResult]
130
- var seen = Set<String>()
131
- let uniqueResults = allResults.reversed().filter {
132
- let model = $0["model"] as? String ?? $0["deviceModel"] as? String ?? deviceModel
133
- guard let name = $0["name"] as? String ?? $0["deviceName"] as? String else { return false }
134
- return seen.insert("\(model):\(name)").inserted
135
- }.reversed()
136
- DeviceStore.shared.set("bluetooth", "searchResults", Array(uniqueResults))
129
+ // Keep the public searchResults array stable as glasses are added or removed.
130
+ // Duplicate discoveries refresh their existing row; only new glasses append.
131
+ let uniqueResults = mergeStableSearchResults(
132
+ searchResults,
133
+ newResult: newResult,
134
+ fallbackModel: deviceModel
135
+ )
136
+ DeviceStore.shared.set("bluetooth", "searchResults", uniqueResults)
137
137
  }
138
138
  }
139
139
  }
140
140
 
141
+ private static func mergeStableSearchResults(
142
+ _ currentResults: [[String: Any]],
143
+ newResult: [String: Any],
144
+ fallbackModel: String
145
+ ) -> [[String: Any]] {
146
+ guard let newKey = searchResultKey(newResult, fallbackModel: fallbackModel) else {
147
+ return currentResults
148
+ }
149
+ var nextResults = currentResults
150
+ if let existingIndex = nextResults.firstIndex(where: {
151
+ searchResultKey($0, fallbackModel: fallbackModel) == newKey
152
+ }) {
153
+ nextResults[existingIndex] = newResult
154
+ } else {
155
+ nextResults.append(newResult)
156
+ }
157
+ return nextResults
158
+ }
159
+
160
+ private static func searchResultKey(_ result: [String: Any], fallbackModel: String) -> String? {
161
+ if let id = result["id"] as? String, !id.isEmpty {
162
+ return id
163
+ }
164
+ let model = result["model"] as? String ?? fallbackModel
165
+ guard let name = result["name"] as? String else {
166
+ return nil
167
+ }
168
+ return "\(model):\(name)"
169
+ }
170
+
141
171
  // MARK: - Hardware Events
142
172
 
143
173
  static func sendButtonPress(buttonId: String, pressType: String) {
@@ -153,8 +183,9 @@ class Bridge {
153
183
 
154
184
  static func sendTouchEvent(deviceModel: String, gestureName: String, timestamp: Int64, source: Int32? = nil) {
155
185
  var body: [String: Any] = [
156
- "device_model": deviceModel,
157
- "gesture_name": gestureName,
186
+ "type": "touch_event",
187
+ "deviceModel": deviceModel,
188
+ "gestureName": gestureName,
158
189
  "timestamp": timestamp,
159
190
  ]
160
191
  if let source {
@@ -173,8 +204,8 @@ class Bridge {
173
204
 
174
205
  static func sendSwitchStatus(switchType: Int, value: Int, timestamp: Int64) {
175
206
  let body: [String: Any] = [
176
- "switch_type": switchType,
177
- "switch_value": value,
207
+ "switchType": switchType,
208
+ "switchValue": value,
178
209
  "timestamp": timestamp,
179
210
  ]
180
211
  Bridge.sendTypedMessage("switch_status", body: body)
@@ -183,6 +214,7 @@ class Bridge {
183
214
  static func sendRgbLedControlResponse(requestId: String, success: Bool, error: String?) {
184
215
  guard !requestId.isEmpty else { return }
185
216
  var body: [String: Any] = [
217
+ "type": "rgb_led_control_response",
186
218
  "requestId": requestId,
187
219
  "state": success ? "success" : "error",
188
220
  ]
@@ -66,9 +66,9 @@ struct ViewState {
66
66
  if isPaired {
67
67
  // Device is paired! Don't activate it - let PhoneMic.swift activate when recording starts
68
68
  Bridge.log("Audio: ✅ Mentra Live is paired (preserving A2DP for music)")
69
- glassesBtcConnected = true
69
+ glassesBluetoothClassicConnected = true
70
70
  } else {
71
- glassesBtcConnected = false
71
+ glassesBluetoothClassicConnected = false
72
72
  // Not found in availableInputs - not paired yet
73
73
 
74
74
  // Start monitoring for when user pairs manually
@@ -79,10 +79,10 @@ struct ViewState {
79
79
  if connected {
80
80
  Bridge.log("Audio: ✅ Device paired and connected")
81
81
  // Don't activate - let PhoneMic.swift handle that when recording starts
82
- self.glassesBtcConnected = true
82
+ self.glassesBluetoothClassicConnected = true
83
83
  } else {
84
84
  Bridge.log("Audio: Device disconnected")
85
- self.glassesBtcConnected = false
85
+ self.glassesBluetoothClassicConnected = false
86
86
  }
87
87
  }
88
88
  }
@@ -214,9 +214,9 @@ struct ViewState {
214
214
  set { DeviceStore.shared.apply("bluetooth", "searchingController", newValue) }
215
215
  }
216
216
 
217
- private var glassesBtcConnected: Bool {
218
- get { DeviceStore.shared.get("glasses", "btcConnected") as? Bool ?? false }
219
- set { DeviceStore.shared.apply("glasses", "btcConnected", newValue) }
217
+ private var glassesBluetoothClassicConnected: Bool {
218
+ get { DeviceStore.shared.get("glasses", "bluetoothClassicConnected") as? Bool ?? false }
219
+ set { DeviceStore.shared.apply("glasses", "bluetoothClassicConnected", newValue) }
220
220
  }
221
221
 
222
222
  private var micRanking: [String] {
@@ -506,8 +506,8 @@ struct ViewState {
506
506
 
507
507
  if micEnabled {
508
508
  for micMode in micRanking {
509
- if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.BT_CLASSIC
510
- || micMode == MicTypes.BT
509
+ if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.BLUETOOTH_CLASSIC
510
+ || micMode == MicTypes.BLUETOOTH
511
511
  {
512
512
  if PhoneMic.shared.isRecordingWithMode(micMode) {
513
513
  micUsed = micMode
@@ -572,8 +572,8 @@ struct ViewState {
572
572
  continue
573
573
  }
574
574
 
575
- if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.BT_CLASSIC
576
- || micMode == MicTypes.BT
575
+ if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.BLUETOOTH_CLASSIC
576
+ || micMode == MicTypes.BLUETOOTH
577
577
  {
578
578
  PhoneMic.shared.stopMode(micMode)
579
579
  }
@@ -849,7 +849,7 @@ struct ViewState {
849
849
  Bridge.log("MAN: checkCurrentAudioDevice: audioDevicePattern: \(audioDevicePattern)")
850
850
 
851
851
  if audioDevicePattern.isEmpty || audioDevicePattern == DeviceTypes.SIMULATED {
852
- glassesBtcConnected = false
852
+ glassesBluetoothClassicConnected = false
853
853
  Bridge.log("MAN: Audio device pattern is empty or simulated, returning")
854
854
  return
855
855
  }
@@ -861,7 +861,7 @@ struct ViewState {
861
861
 
862
862
  if !isConnected {
863
863
  Bridge.log("MAN: Device '\(deviceName)' disconnected")
864
- glassesBtcConnected = false
864
+ glassesBluetoothClassicConnected = false
865
865
 
866
866
  let isOtherDeviceConnected = AudioSessionMonitor.isOtherAudioDeviceConnected(
867
867
  devicePattern: audioDevicePattern
@@ -880,9 +880,9 @@ struct ViewState {
880
880
  $0.portName.localizedCaseInsensitiveContains(audioDevicePattern)
881
881
  })?.portName
882
882
  Bridge.log("MAN: ✅ Successfully detected newly paired device '\(deviceName)'")
883
- glassesBtcConnected = true
883
+ glassesBluetoothClassicConnected = true
884
884
  } else {
885
- glassesBtcConnected = false
885
+ glassesBluetoothClassicConnected = false
886
886
  }
887
887
  }
888
888
 
@@ -1120,6 +1120,8 @@ struct ViewState {
1120
1120
  func dbg2() {}
1121
1121
 
1122
1122
  func startStream(_ message: [String: Any]) {
1123
+ var message = message
1124
+ message["flash"] = true
1123
1125
  Bridge.log("MAN: startStream: \(message)")
1124
1126
  sgc?.startStream(message)
1125
1127
  }
@@ -1199,11 +1201,11 @@ struct ViewState {
1199
1201
  sgc?.sendReboot()
1200
1202
  }
1201
1203
 
1202
- func startVideoRecording(_ requestId: String, _ save: Bool, _ flash: Bool, _ sound: Bool) {
1204
+ func startVideoRecording(_ requestId: String, _ save: Bool, _ sound: Bool) {
1203
1205
  Bridge.log(
1204
- "MAN: onStartVideoRecording: requestId=\(requestId), save=\(save), flash=\(flash), sound=\(sound)"
1206
+ "MAN: onStartVideoRecording: requestId=\(requestId), save=\(save), flash=true, sound=\(sound)"
1205
1207
  )
1206
- sgc?.startVideoRecording(requestId: requestId, save: save, flash: flash, sound: sound)
1208
+ sgc?.startVideoRecording(requestId: requestId, save: save, flash: true, sound: sound)
1207
1209
  }
1208
1210
 
1209
1211
  func stopVideoRecording(_ requestId: String) {
@@ -1223,8 +1225,8 @@ struct ViewState {
1223
1225
  packageName: String?,
1224
1226
  action: String,
1225
1227
  color: String?,
1226
- ontime: Int,
1227
- offtime: Int,
1228
+ onDurationMs: Int,
1229
+ offDurationMs: Int,
1228
1230
  count: Int
1229
1231
  ) {
1230
1232
  sgc?.sendRgbLedControl(
@@ -1232,8 +1234,8 @@ struct ViewState {
1232
1234
  packageName: packageName,
1233
1235
  action: action,
1234
1236
  color: color,
1235
- ontime: ontime,
1236
- offtime: offtime,
1237
+ onDurationMs: onDurationMs,
1238
+ offDurationMs: offDurationMs,
1237
1239
  count: count
1238
1240
  )
1239
1241
  }
@@ -1272,22 +1274,21 @@ struct ViewState {
1272
1274
  }
1273
1275
  }
1274
1276
 
1275
- func photoRequest(
1277
+ func requestPhoto(
1276
1278
  _ requestId: String,
1277
1279
  _ appId: String,
1278
1280
  _ size: String,
1279
1281
  _ webhookUrl: String?,
1280
1282
  _ authToken: String?,
1281
1283
  _ compress: String?,
1282
- _ flash: Bool,
1283
1284
  _ sound: Bool
1284
1285
  ) {
1285
1286
  Bridge.log(
1286
- "MAN: onPhotoRequest: \(requestId), \(appId), \(webhookUrl), size=\(size), compress=\(compress ?? "none"), flash=\(flash), sound=\(sound)"
1287
+ "MAN: requestPhoto: \(requestId), \(appId), \(webhookUrl), size=\(size), compress=\(compress ?? "none"), flash=true, sound=\(sound)"
1287
1288
  )
1288
1289
  sgc?.requestPhoto(
1289
1290
  requestId, appId: appId, size: size, webhookUrl: webhookUrl, authToken: authToken,
1290
- compress: compress, flash: flash, sound: sound
1291
+ compress: compress, flash: true, sound: sound
1291
1292
  )
1292
1293
  }
1293
1294
 
@@ -28,7 +28,7 @@ class DeviceStore {
28
28
  store.set("glasses", "deviceModel", "")
29
29
  store.set("glasses", "firmwareVersion", "")
30
30
  store.set("glasses", "micEnabled", false)
31
- store.set("glasses", "btcConnected", false)
31
+ store.set("glasses", "bluetoothClassicConnected", false)
32
32
  store.set("glasses", "caseRemoved", true)
33
33
  store.set("glasses", "caseOpen", true)
34
34
  store.set("glasses", "caseCharging", false)
@@ -80,12 +80,12 @@ class DeviceStore {
80
80
  store.set("bluetooth", "dashboard_depth", 2)
81
81
  store.set("bluetooth", "head_up_angle", 30)
82
82
  store.set("bluetooth", "contextual_dashboard", true)
83
- store.set("bluetooth", "gallery_mode", true)
83
+ store.set("bluetooth", "galleryModeAuto", true)
84
84
  store.set("bluetooth", "screen_disabled", false)
85
85
  store.set("bluetooth", "button_photo_size", "medium")
86
86
  store.set("bluetooth", "button_camera_led", true)
87
87
  store.set("bluetooth", "button_max_recording_time", 10)
88
- store.set("bluetooth", "camera_fov", ["fov": 118, "roi_position": 0])
88
+ store.set("bluetooth", "camera_fov", ["fov": 118, "roiPosition": 0])
89
89
  store.set("bluetooth", "button_video_width", 1280)
90
90
  store.set("bluetooth", "button_video_height", 720)
91
91
  store.set("bluetooth", "button_video_fps", 30)
@@ -214,7 +214,7 @@ class DeviceStore {
214
214
  DeviceManager.shared.sgc?.setDashboardMenu(items)
215
215
  }
216
216
 
217
- case ("bluetooth", "gallery_mode"):
217
+ case ("bluetooth", "galleryModeAuto"):
218
218
  DeviceManager.shared.sgc?.sendGalleryMode()
219
219
 
220
220
  case ("bluetooth", "screen_disabled"):