@mentra/bluetooth-sdk 3.2.0-dev.203 → 3.2.0-dev.206
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/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +0 -8
- package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedReleaseMetadata.kt +5 -5
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +13 -152
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +14 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamControllerProbe.kt +14 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +16 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamSessionState.kt +32 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/streaming/StreamControllerProbeTest.kt +24 -0
- package/android/src/test/java/com/mentra/bluetoothsdk/streaming/StreamSessionStateTest.kt +43 -0
- package/build/BluetoothSdk.types.d.ts +6 -1
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +1 -3
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/generated/releaseMetadata.js +5 -5
- package/build/generated/releaseMetadata.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +0 -11
- package/ios/Source/BluetoothSdkDefaults.swift +1 -1
- package/ios/Source/GeneratedReleaseMetadata.swift +5 -5
- package/ios/Source/MentraBluetoothSDK.swift +10 -130
- package/ios/Source/sgcs/MentraLive.swift +46 -35
- package/ios/Source/streaming/StreamControllerProbe.swift +18 -0
- package/ios/Source/streaming/StreamModels.swift +12 -0
- package/ios/Source/streaming/StreamSessionState.swift +29 -0
- package/ios/Tests/StreamControllerProbeTests.swift +27 -0
- package/ios/Tests/StreamSessionStateTests.swift +38 -0
- package/package.json +1 -1
- package/src/BluetoothSdk.types.ts +6 -1
- package/src/_private/BluetoothSdkModule.ts +0 -3
- package/src/generated/releaseMetadata.ts +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BluetoothSdkModule.js","sourceRoot":"","sources":["../../src/_private/BluetoothSdkModule.ts"],"names":[],"mappings":"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","sourcesContent":["import {createScanSession} from \"./scanSession\"\nimport {NativeModule, requireNativeModule} from \"expo\"\nimport {Platform} from \"react-native\"\n\nimport {installNativeLogConsole} from \"./nativeLogConsole\"\n\nimport {\n BluetoothSettingsUpdate,\n BluetoothSdkModuleEvents,\n BluetoothStatus,\n PhotoCaptureDefaults,\n CalendarEvent,\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovOverrideRequest,\n CameraFovResult,\n CameraFovSetting,\n CameraRoiPosition,\n CameraStatusEvent,\n ConnectOptions,\n DashboardMenuItem,\n Device,\n DeviceModel,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesStatus,\n GalleryStatusEvent,\n HotspotStatusChangeEvent,\n MicPreference,\n NativePhoneNotification,\n NativeNotificationConfig,\n NativeNotificationStatus,\n ObservableStoreCategory,\n OtaQueryResult,\n OtaStartAckEvent,\n PhotoRequestParams,\n PhotoSuccessResponseEvent,\n PublicBluetoothStatus,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlSuccessResponseEvent,\n ScanDiagnostic,\n ScanModelOptions,\n ScanOptions,\n SettingsAckSuccessEvent,\n StreamKeepAliveRequest,\n StreamStartRequest,\n StreamStatusEvent,\n VideoRecordingStartedStatusEvent,\n VideoRecordingSettings,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingStatusEvent,\n VersionInfoResult,\n WarmUpCameraParams,\n SavedWifiNetworksResult,\n WifiForgetResult,\n WifiSearchResult,\n WifiStatusChangeEvent,\n} from \"../BluetoothSdk.types\"\nimport {warmUpCameraParamsForNative} from \"./cameraRequestPayload\"\nimport {photoRequestParamsForNative} from \"./photoRequestPayload\"\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. Raw status getters/listeners stay here so React hooks can\n * shape native store snapshots before app code sees them.\n */\n\ntype GlassesListener = (changed: Partial<GlassesStatus>) => void\ntype BluetoothStatusListener = (changed: Partial<PublicBluetoothStatus>) => 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<PublicBluetoothStatus>\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 setDashboardContent(content: string): 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 getScanDiagnostic?: (model: DeviceModel) => Promise<ScanDiagnostic | null>\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 setCalendarEvents(events: CalendarEvent[]): Promise<void>\n setHeadUpAngle(angleDegrees: number): Promise<void>\n setImuEnabled(enabled: boolean): 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<WifiSearchResult[]>\n getSavedWifiNetworks(): Promise<SavedWifiNetworksResult>\n sendWifiCredentials(ssid: string, password: string): Promise<WifiStatusChangeEvent>\n forgetWifiNetwork(ssid: string): Promise<WifiForgetResult>\n setHotspotState(enabled: boolean): Promise<HotspotStatusChangeEvent>\n /** Enable or disable Wi-Fi ADB on Mentra Live (no-op on other devices). */\n setWifiAdbState(enabled: boolean): Promise<void>\n /** Set the glasses system clock when phone detects clock skew (Mentra Live and G2). */\n setSystemTime(timestampMs: number): Promise<void>\n /** Logs current WiFi frequency (MHz) and 5 GHz band to Android logcat. */\n logCurrentWifiFrequency(): Promise<void>\n\n // Gallery Commands\n setGalleryModeEnabled(enabled: boolean): Promise<SettingsAckSuccessEvent>\n setVoiceActivityDetectionEnabled(enabled: boolean): Promise<void>\n /** Mentra Live center-mic loudness / Barrier gate (cs_swit type 10). */\n setLoudnessGateEnabled(enabled: boolean): Promise<void>\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for text sensor size/crop).\n */\n setPhotoCaptureDefaults(settings: PhotoCaptureDefaults): Promise<SettingsAckSuccessEvent>\n setVideoRecordingDefaults(width: number, height: number, fps: number): Promise<SettingsAckSuccessEvent>\n setMaxVideoRecordingDuration(minutes: number): Promise<SettingsAckSuccessEvent>\n setCameraFov(request: CameraFovRequest): Promise<CameraFovResult>\n setLegacyCameraFov(request: CameraFovRequest): Promise<CameraFovResult>\n restoreLegacyCameraFov(): Promise<void>\n setCameraFovOverride(request: CameraFovOverrideRequest): Promise<CameraFovResult>\n releaseCameraFovOverride(leaseId: string): Promise<SettingsAckSuccessEvent>\n /**\n * Configure camera HAL tuning (ANR / gain) on Mentra Live glasses.\n * Sends a {@code camera_tuning_config} BLE message; the ASG client relays it as a\n * {@code camconfig} broadcast so the HAL picks up new parameters without a reboot.\n *\n * Scan-mode convention: pass `{anr: false, gain: false}` when activating scan mode\n * (disables ANR and pixsmart gain) and `{anr: true, gain: true}` to restore defaults.\n */\n setCameraTuningConfig(anrOn: boolean, gainOn: boolean): Promise<SettingsAckSuccessEvent>\n queryGalleryStatus(): Promise<GalleryStatusEvent>\n requestPhoto(params: PhotoRequestParams): Promise<PhotoSuccessResponseEvent>\n warmUpCamera(params: WarmUpCameraParams): Promise<CameraStatusEvent>\n stopCameraWarmUp(requestId: string): Promise<void>\n\n // OTA Commands\n setOtaVersionUrl(otaVersionUrl: string): void\n getOtaVersionUrl(): string\n checkForOtaUpdate(): Promise<boolean>\n startOtaUpdate(otaVersionUrl?: string | null): Promise<OtaStartAckEvent>\n sendOtaQueryStatus(): Promise<OtaQueryResult>\n startAr99OtaFromFile(path: string): Promise<boolean>\n cancelAr99Ota(): Promise<void>\n sendAr99FactoryReset(): Promise<void>\n buildAr99OtaSignature(\n secret: string,\n appName: string,\n currentVersion: string,\n serialNumber: string,\n nonce: string,\n ): string\n\n // Version Info Commands\n requestVersionInfo(): Promise<VersionInfoResult>\n\n // Video Recording Commands\n startVideoRecording(\n requestId: string,\n save: boolean,\n sound: boolean,\n settings?: VideoRecordingSettings,\n ): Promise<VideoRecordingStartedStatusEvent>\n stopVideoRecording(\n requestId: string,\n webhookUrl?: string,\n authToken?: string,\n ): Promise<VideoRecordingStoppedStatusEvent>\n queryVideoRecordingStatus(requestId: string): Promise<VideoRecordingStatusEvent>\n\n // Stream Commands\n startStream(params: StreamStartRequest): Promise<StreamStatusEvent>\n startExternallyManagedStream(params: StreamStartRequest): Promise<StreamStatusEvent>\n stopStream(): Promise<StreamStatusEvent>\n sendExternallyManagedStreamKeepAlive(params: StreamKeepAliveRequest): Promise<void>\n\n // Microphone Commands\n setMicState(enabled: boolean, useGlassesMic?: boolean, sendTranscript?: boolean, sendLc3Data?: boolean): 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 // Live PCM output stream (miniapp speaker.createStream). MentraOS-internal\n // ? 16-bit LE PCM chunks into a streaming AudioTrack (USAGE_MEDIA, so it\n // follows the phone's media route, e.g. A2DP to glasses). Implemented with\n // AudioTrack on Android and AVAudioEngine on iOS.\n /** Open a PCM stream session. One AudioTrack per id; caller manages ids. */\n pcmStreamOpen(streamId: string, sampleRate: number, channels: number, volume: number): Promise<void>\n /**\n * Append base64 PCM. Resolves with the queued-but-unplayed backlog in ms;\n * blocks (on a background dispatcher) while the backlog is above the\n * backpressure ceiling, so awaited writes self-throttle to realtime.\n */\n pcmStreamWrite(streamId: string, base64: string): Promise<{bufferedMs: number}>\n /** Drain the backlog, then stop. Resolves with the total played duration. */\n pcmStreamClose(streamId: string): Promise<{durationMs: number}>\n /** Stop immediately, dropping any backlog. Idempotent. */\n pcmStreamAbort(streamId: string): 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??5 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<RgbLedControlSuccessResponseEvent>\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 // TTS Commands\n setTtsModelDetails(path: string, languageCode: string): Promise<void>\n getTtsModelPath(): Promise<string>\n getTtsModelLanguage(): Promise<string>\n checkTtsModelAvailable(): Promise<boolean>\n validateTtsModel(path: string): Promise<boolean>\n generateTtsAudio(\n text: string,\n modelPath: string,\n outputPath: string,\n speakerId: number,\n speed: number,\n ): Promise<boolean>\n\n /** Android G2 content upload. iOS receives ANCS directly and rejects uploads. */\n sendPhoneNotification(notification: NativePhoneNotification): Promise<void>\n configureNativeNotifications(config: NativeNotificationConfig): Promise<void>\n getNativeNotificationStatus(): Promise<NativeNotificationStatus>\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\")\ninstallNativeLogConsole(NativeBluetoothSdkModule, Platform.OS)\n\nconst DEFAULT_CONNECT_OPTIONS: Required<ConnectOptions> = {\n saveAsDefault: true,\n cancelExistingConnectionAttempt: true,\n requiresAncs: true,\n}\n\nconst DEFAULT_SCAN_TIMEOUT_MS = 15_000\n\nfunction bindNativeMethod<T extends (...args: never[]) => unknown>(module: Record<string, unknown>, name: string): T {\n const method = module[name]\n if (typeof method !== \"function\") {\n console.warn(`[BluetoothSdk] Native method \"${name}\" is unavailable ??rebuild the app (bun android / bun ios)`)\n return (async () => {\n throw new Error(`BluetoothSdk.${name} is not available in this native build. Rebuild the app.`)\n }) as T\n }\n return method.bind(module) as T\n}\n\nconst CAMERA_ROI_MIN = 0\nconst CAMERA_ROI_MAX = 2\nconst CAMERA_ROI_POSITION_VALUES: Record<CameraRoiPosition, CameraFovSetting[\"roiPosition\"]> = {\n center: 0,\n bottom: 1,\n top: 2,\n}\n\n// Named presets are a convenience layer over the numeric {fov, roiPosition} API.\n// The default is the full sensor; \"standard\" preserves the historical 102° crop.\nconst CAMERA_FOV_PRESETS: Record<CameraFovPreset, CameraFovSetting> = {\n narrow: {fov: 82, roiPosition: 0},\n standard: {fov: 102, roiPosition: 0},\n wide: {fov: CAMERA_FOV_MAX, roiPosition: 0},\n}\n\nfunction clampInteger(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, Math.round(value)))\n}\n\nfunction normalizeCameraFov(request: CameraFovRequest): CameraFovSetting {\n if (\"preset\" in request) {\n return CAMERA_FOV_PRESETS[request.preset] ?? CAMERA_FOV_PRESETS.standard\n }\n\n const roiPosition = request.roiPosition ?? \"center\"\n\n return {\n fov: clampInteger(Number.isFinite(request.fov) ? request.fov : CAMERA_FOV_DEFAULT, CAMERA_FOV_MIN, CAMERA_FOV_MAX),\n roiPosition: clampInteger(CAMERA_ROI_POSITION_VALUES[roiPosition] ?? 0, CAMERA_ROI_MIN, CAMERA_ROI_MAX) as\n | 0\n | 1\n | 2,\n }\n}\n\nfunction searchResultsForModel(status: Partial<PublicBluetoothStatus>, 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(\n NativeBluetoothSdkModule,\n) 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 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.setCalendarEvents = function (events: CalendarEvent[]) {\n return this.updateBluetoothSettings({calendar_events: events})\n}\n\nNativeBluetoothSdkModule.setHeadUpAngle = function (angleDegrees: number) {\n return this.updateBluetoothSettings({head_up_angle: angleDegrees})\n}\n\nNativeBluetoothSdkModule.setImuEnabled = function (enabled: boolean) {\n return this.updateBluetoothSettings({imu_enabled: enabled})\n}\n\nNativeBluetoothSdkModule.setScreenDisabled = function (disabled: boolean) {\n return this.updateBluetoothSettings({screen_disabled: disabled})\n}\n\nNativeBluetoothSdkModule.setVoiceActivityDetectionEnabled = function (enabled: boolean) {\n return this.updateBluetoothSettings({voice_activity_detection_enabled: enabled})\n}\n\nNativeBluetoothSdkModule.setLoudnessGateEnabled = function (enabled: boolean) {\n return this.updateBluetoothSettings({loudness_gate_enabled: enabled})\n}\n\nconst nativeSetCameraFov = bindNativeMethod<(fov: CameraFovSetting) => MaybePromise<CameraFovResult>>(\n NativeBluetoothSdkModule as unknown as Record<string, unknown>,\n \"setCameraFov\",\n)\nNativeBluetoothSdkModule.setCameraFov = function (request: CameraFovRequest) {\n const setting = normalizeCameraFov(request)\n return Promise.resolve(nativeSetCameraFov(setting))\n}\n\nconst nativeSetLegacyCameraFov = bindNativeMethod<(fov: CameraFovSetting) => MaybePromise<CameraFovResult>>(\n NativeBluetoothSdkModule as unknown as Record<string, unknown>,\n \"setLegacyCameraFov\",\n)\nNativeBluetoothSdkModule.setLegacyCameraFov = function (request: CameraFovRequest) {\n return Promise.resolve(nativeSetLegacyCameraFov(normalizeCameraFov(request)))\n}\n\nconst nativeRestoreLegacyCameraFov = bindNativeMethod<() => MaybePromise<void>>(\n NativeBluetoothSdkModule as unknown as Record<string, unknown>,\n \"restoreLegacyCameraFov\",\n)\nNativeBluetoothSdkModule.restoreLegacyCameraFov = function () {\n return Promise.resolve(nativeRestoreLegacyCameraFov())\n}\n\nconst nativeSetCameraFovOverride = bindNativeMethod<\n (request: CameraFovSetting & {leaseId: string; ttlMs: number}) => MaybePromise<CameraFovResult>\n>(NativeBluetoothSdkModule as unknown as Record<string, unknown>, \"setCameraFovOverride\")\nNativeBluetoothSdkModule.setCameraFovOverride = function (request: CameraFovOverrideRequest) {\n const setting = normalizeCameraFov(request)\n const requestedTtl =\n typeof request.ttlMs === \"number\" && Number.isFinite(request.ttlMs) && request.ttlMs > 0\n ? Math.round(request.ttlMs)\n : 300_000\n return Promise.resolve(\n nativeSetCameraFovOverride({\n ...setting,\n leaseId: request.leaseId,\n ttlMs: Math.min(requestedTtl, 600_000),\n }),\n )\n}\n\nNativeBluetoothSdkModule.setMicState = function (\n enabled: boolean,\n useGlassesMic?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n) {\n return Promise.resolve(\n nativeSetMicState(enabled, useGlassesMic ?? true, sendTranscript ?? false, sendLc3Data ?? false),\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\nconst nativeStopScan = NativeBluetoothSdkModule.stopScan.bind(NativeBluetoothSdkModule)\nconst activeScanCancellations = new Set<() => Promise<void>>()\nNativeBluetoothSdkModule.stopScan = async function () {\n if (activeScanCancellations.size === 0) return nativeStopScan()\n await Promise.all([...activeScanCancellations].map(cancel => cancel()))\n}\n\nNativeBluetoothSdkModule.scan = async function (modelOrOptions: DeviceModel | ScanOptions, options?: ScanModelOptions) {\n if (activeScanCancellations.size > 0) await this.stopScan()\n const scanOptions = normalizeScanArgs(modelOrOptions, options)\n const timeoutMs = normalizeTimeoutMs(scanOptions.timeoutMs ?? scanOptions.timeout, DEFAULT_SCAN_TIMEOUT_MS)\n const session = createScanSession(\n {\n start: (model) => this.startScan(model),\n stop: nativeStopScan,\n subscribe: (onResults) =>\n this.onBluetoothStatus((status) => {\n if (Array.isArray(status.searchResults)) onResults(searchResultsForModel(status, scanOptions.model))\n }),\n getResults: async () => searchResultsForModel(await this.getBluetoothStatus(), scanOptions.model),\n // Older native binaries simply omit diagnostics until the host is rebuilt.\n getDiagnostic:\n typeof this.getScanDiagnostic === \"function\" ? () => this.getScanDiagnostic!(scanOptions.model) : undefined,\n },\n {...scanOptions, timeoutMs},\n )\n activeScanCancellations.add(session.cancel)\n try {\n return await session.result\n } finally {\n activeScanCancellations.delete(session.cancel)\n }\n}\n\nconst nativeRequestPhoto = NativeBluetoothSdkModule.requestPhoto.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.requestPhoto = function (params: PhotoRequestParams) {\n return nativeRequestPhoto(photoRequestParamsForNative(params) as unknown as PhotoRequestParams)\n}\n\nconst nativeWarmUpCamera = NativeBluetoothSdkModule.warmUpCamera.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.warmUpCamera = function (params: WarmUpCameraParams) {\n return nativeWarmUpCamera(warmUpCameraParamsForNative(params) as unknown as WarmUpCameraParams)\n}\n\nexport default NativeBluetoothSdkModule\nexport const BluetoothSdk = NativeBluetoothSdkModule as BluetoothSdkInternalModule\n"]}
|
|
1
|
+
{"version":3,"file":"BluetoothSdkModule.js","sourceRoot":"","sources":["../../src/_private/BluetoothSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAe,mBAAmB,EAAC,MAAM,MAAM,CAAA;AACtD,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAA;AAErC,OAAO,EAAC,uBAAuB,EAAC,MAAM,oBAAoB,CAAA;AAE1D,OAAO,EAML,kBAAkB,EAClB,cAAc,EACd,cAAc,GA8Cf,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAC,2BAA2B,EAAC,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAC,2BAA2B,EAAC,MAAM,uBAAuB,CAAA;AAmOjE,yDAAyD;AACzD,gGAAgG;AAChG,MAAM,wBAAwB,GAAG,mBAAmB,CAA2B,cAAc,CAAC,CAAA;AAC9F,uBAAuB,CAAC,wBAAwB,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAA;AAE9D,MAAM,uBAAuB,GAA6B;IACxD,aAAa,EAAE,IAAI;IACnB,+BAA+B,EAAE,IAAI;IACrC,YAAY,EAAE,IAAI;CACnB,CAAA;AAED,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAEtC,SAAS,gBAAgB,CAA0C,MAA+B,EAAE,IAAY;IAC9G,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3B,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,iCAAiC,IAAI,4DAA4D,CAAC,CAAA;QAC/G,OAAO,CAAC,KAAK,IAAI,EAAE;YACjB,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,0DAA0D,CAAC,CAAA;QACjG,CAAC,CAAM,CAAA;IACT,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAM,CAAA;AACjC,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,CAAA;AACxB,MAAM,cAAc,GAAG,CAAC,CAAA;AACxB,MAAM,0BAA0B,GAA+D;IAC7F,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,GAAG,EAAE,CAAC;CACP,CAAA;AAED,iFAAiF;AACjF,iFAAiF;AACjF,MAAM,kBAAkB,GAA8C;IACpE,MAAM,EAAE,EAAC,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAC;IACjC,QAAQ,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,EAAC;IACpC,IAAI,EAAE,EAAC,GAAG,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,EAAC;CAC5C,CAAA;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW;IAC3D,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAyB;IACnD,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;QACxB,OAAO,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAA;IAC1E,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,QAAQ,CAAA;IAEnD,OAAO;QACL,GAAG,EAAE,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,kBAAkB,EAAE,cAAc,EAAE,cAAc,CAAC;QAClH,WAAW,EAAE,YAAY,CAAC,0BAA0B,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,cAAc,CAGjG;KACN,CAAA;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAsC,EAAE,KAAkB;IACvF,OAAO,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,CAAA;AAC/E,CAAC;AAED,SAAS,iBAAiB,CAAC,cAAyC,EAAE,OAA0B;IAC9F,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,EAAC,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,EAAC,CAAA;IAC5C,CAAC;IACD,OAAO,cAAc,CAAA;AACvB,CAAC;AAED,SAAS,kBAAkB,CAAC,SAA6B,EAAE,gBAAwB;IACjF,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAA;AACpH,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAuB;IACxD,OAAO;QACL,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QACtB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAA;AACH,CAAC;AAED,SAAS,6BAA6B,CAAC,UAAuC;IAC5E,QAAQ,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,KAAK,WAAW;YACd,OAAO,EAAC,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC,WAAW,EAAC,CAAA;QAC7F,KAAK,UAAU;YACb,OAAO,EAAC,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;QAC5E,KAAK,YAAY;YACf,OAAO,EAAC,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;QAC9E,KAAK,SAAS;YACZ,OAAO,EAAC,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;QAC3E,KAAK,cAAc;YACjB,OAAO,EAAC,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;IAClF,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,MAA8B;IAChE,MAAM,EAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,EAAC,GAAG,MAAM,CAAA;IACnD,IAAI,MAAM,GAA4B,EAAC,GAAG,IAAI,EAAC,CAAA;IAC/C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG;YACP,GAAG,MAAM;YACT,GAAG,6BAA6B,CAAC,UAAU,CAAC;SAC7C,CAAA;IACH,CAAC;IACD,IAAI,IAAI,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,GAAG;YACP,GAAG,MAAM;YACT,aAAa,EAAE,IAAI;YACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,WAAW,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;SAChC,CAAA;IACH,CAAC;SAAM,IAAI,IAAI,EAAE,KAAK,KAAK,cAAc,EAAE,CAAC;QAC1C,MAAM,GAAG;YACP,GAAG,MAAM;YACT,aAAa,EAAE,KAAK;YACpB,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,EAAE;SAChB,CAAA;IACH,CAAC;IACD,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG;YACP,GAAG,MAAM;YACT,cAAc,EAAE,IAAI;YACpB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,eAAe,EAAE,OAAO,CAAC,QAAQ;YACjC,gBAAgB,EAAE,OAAO,CAAC,OAAO;SAClC,CAAA;IACH,CAAC;SAAM,IAAI,OAAO,EAAE,KAAK,KAAK,UAAU,EAAE,CAAC;QACzC,MAAM,GAAG;YACP,GAAG,MAAM;YACT,cAAc,EAAE,KAAK;YACrB,WAAW,EAAE,EAAE;YACf,eAAe,EAAE,EAAE;YACnB,gBAAgB,EAAE,EAAE;SACrB,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,mCAAmC;AACnC,MAAM,sBAAsB,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,IAAI,CAC3E,wBAAwB,CACY,CAAA;AACtC,wBAAwB,CAAC,gBAAgB,GAAG;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAA;AAClD,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,kBAAkB,CAAC,IAAI,CAC/E,wBAAwB,CACc,CAAA;AACxC,wBAAwB,CAAC,kBAAkB,GAAG;IAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAA;AACpD,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,IAAI,CAC3E,wBAAwB,CACY,CAAA;AACtC,wBAAwB,CAAC,gBAAgB,GAAG;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAA;AAClD,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAKrE,CAAA;AAEvB,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAKrE,CAAA;AAEvB,wBAAwB,CAAC,aAAa,GAAG,UAAU,MAA8B;IAC/E,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAA;AACnE,CAAC,CAAA;AAED,wBAAwB,CAAC,uBAAuB,GAAG,UAAU,MAA+B;IAC1F,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;AACzC,CAAC,CAAA;AAED,wBAAwB,CAAC,WAAW,GAAG,UAAU,IAAY,EAAE,CAAU,EAAE,CAAU,EAAE,IAAa;IAClG,OAAO,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAA;AAC7E,CAAC,CAAA;AAED,wBAAwB,CAAC,aAAa,GAAG,UAAU,KAAa,EAAE,QAAyB;IACzF,OAAO,IAAI,CAAC,uBAAuB,CAAC;QAClC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,eAAe,EAAE,QAAQ,EAAC,CAAC;QACxD,UAAU,EAAE,KAAK;KAClB,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,wBAAwB,CAAC,iBAAiB,GAAG,UAAU,OAAgB;IACrE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,eAAe,EAAE,OAAO,EAAC,CAAC,CAAA;AACjE,CAAC,CAAA;AAED,wBAAwB,CAAC,oBAAoB,GAAG,UAAU,MAAc,EAAE,KAAa;IACrF,OAAO,IAAI,CAAC,uBAAuB,CAAC;QAClC,gBAAgB,EAAE,MAAM;QACxB,eAAe,EAAE,KAAK;KACvB,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,wBAAwB,CAAC,gBAAgB,GAAG,UAAU,KAA0B;IAC9E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAC,CAAC,CAAA;AACxF,CAAC,CAAA;AAED,wBAAwB,CAAC,iBAAiB,GAAG,UAAU,MAAuB;IAC5E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,eAAe,EAAE,MAAM,EAAC,CAAC,CAAA;AAChE,CAAC,CAAA;AAED,wBAAwB,CAAC,cAAc,GAAG,UAAU,YAAoB;IACtE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,aAAa,EAAE,YAAY,EAAC,CAAC,CAAA;AACpE,CAAC,CAAA;AAED,wBAAwB,CAAC,aAAa,GAAG,UAAU,OAAgB;IACjE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,WAAW,EAAE,OAAO,EAAC,CAAC,CAAA;AAC7D,CAAC,CAAA;AAED,wBAAwB,CAAC,iBAAiB,GAAG,UAAU,QAAiB;IACtE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,eAAe,EAAE,QAAQ,EAAC,CAAC,CAAA;AAClE,CAAC,CAAA;AAED,wBAAwB,CAAC,gCAAgC,GAAG,UAAU,OAAgB;IACpF,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,gCAAgC,EAAE,OAAO,EAAC,CAAC,CAAA;AAClF,CAAC,CAAA;AAED,wBAAwB,CAAC,sBAAsB,GAAG,UAAU,OAAgB;IAC1E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,qBAAqB,EAAE,OAAO,EAAC,CAAC,CAAA;AACvE,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,gBAAgB,CACzC,wBAA8D,EAC9D,cAAc,CACf,CAAA;AACD,wBAAwB,CAAC,YAAY,GAAG,UAAU,OAAyB;IACzE,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;IAC3C,OAAO,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAA;AACrD,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,gBAAgB,CAC/C,wBAA8D,EAC9D,oBAAoB,CACrB,CAAA;AACD,wBAAwB,CAAC,kBAAkB,GAAG,UAAU,OAAyB;IAC/E,OAAO,OAAO,CAAC,OAAO,CAAC,wBAAwB,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAC/E,CAAC,CAAA;AAED,MAAM,4BAA4B,GAAG,gBAAgB,CACnD,wBAA8D,EAC9D,wBAAwB,CACzB,CAAA;AACD,wBAAwB,CAAC,sBAAsB,GAAG;IAChD,OAAO,OAAO,CAAC,OAAO,CAAC,4BAA4B,EAAE,CAAC,CAAA;AACxD,CAAC,CAAA;AAED,MAAM,0BAA0B,GAAG,gBAAgB,CAEjD,wBAA8D,EAAE,sBAAsB,CAAC,CAAA;AACzF,wBAAwB,CAAC,oBAAoB,GAAG,UAAU,OAAiC;IACzF,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;IAC3C,MAAM,YAAY,GAChB,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC;QACtF,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAC3B,CAAC,CAAC,OAAO,CAAA;IACb,OAAO,OAAO,CAAC,OAAO,CACpB,0BAA0B,CAAC;QACzB,GAAG,OAAO;QACV,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC;KACvC,CAAC,CACH,CAAA;AACH,CAAC,CAAA;AAED,wBAAwB,CAAC,WAAW,GAAG,UACrC,OAAgB,EAChB,aAAuB,EACvB,cAAwB,EACxB,WAAqB;IAErB,OAAO,OAAO,CAAC,OAAO,CACpB,iBAAiB,CAAC,OAAO,EAAE,aAAa,IAAI,IAAI,EAAE,cAAc,IAAI,KAAK,EAAE,WAAW,IAAI,KAAK,CAAC,CACjG,CAAA;AACH,CAAC,CAAA;AAED,wBAAwB,CAAC,eAAe,GAAG,UAAU,YAA2B;IAC9E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,aAAa,EAAE,YAAY,EAAC,CAAC,CAAA;AACpE,CAAC,CAAA;AAED,wBAAwB,CAAC,eAAe,GAAG,UAAU,QAAyB;IAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAA;IACjE,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAA;AACpC,CAAC,CAAA;AAED,wBAAwB,CAAC,iBAAiB,GAAG,UAAU,QAAiC;IACtF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAA;IACnE,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAA;AACpC,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,wBAAwB,CAAC,cAAc,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;AACnG,wBAAwB,CAAC,cAAc,GAAG,UAAU,OAAwB;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,oBAAoB,EAAE,CAAA;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC,yBAAyB,CAAC,EAAC,GAAG,uBAAuB,EAAE,GAAG,OAAO,EAAC,CAAC,CAAA;AACjF,CAAC,CAAA;AAED,wBAAwB,CAAC,OAAO,GAAG,UAAU,MAAc,EAAE,OAAwB;IACnF,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAC,GAAG,uBAAuB,EAAE,GAAG,OAAO,EAAC,CAAC,CAAA;AAClF,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,wBAAwB,CAAC,QAAQ,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;AACvF,MAAM,uBAAuB,GAAG,IAAI,GAAG,EAAuB,CAAA;AAC9D,wBAAwB,CAAC,QAAQ,GAAG,KAAK;IACvC,IAAI,uBAAuB,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,cAAc,EAAE,CAAA;IAC/D,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AACzE,CAAC,CAAA;AAED,wBAAwB,CAAC,IAAI,GAAG,KAAK,WAAW,cAAyC,EAAE,OAA0B;IACnH,IAAI,uBAAuB,CAAC,IAAI,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAA;IAC3D,MAAM,WAAW,GAAG,iBAAiB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;IAC9D,MAAM,SAAS,GAAG,kBAAkB,CAAC,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAA;IAC3G,MAAM,OAAO,GAAG,iBAAiB,CAC/B;QACE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QACvC,IAAI,EAAE,cAAc;QACpB,SAAS,EAAE,CAAC,SAAS,EAAE,EAAE,CACvB,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,EAAE,EAAE;YAChC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;gBAAE,SAAS,CAAC,qBAAqB,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;QACtG,CAAC,CAAC;QACJ,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,qBAAqB,CAAC,MAAM,IAAI,CAAC,kBAAkB,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC;QACjG,2EAA2E;QAC3E,aAAa,EACX,OAAO,IAAI,CAAC,iBAAiB,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAkB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9G,EACD,EAAC,GAAG,WAAW,EAAE,SAAS,EAAC,CAC5B,CAAA;IACD,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3C,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,MAAM,CAAA;IAC7B,CAAC;YAAS,CAAC;QACT,uBAAuB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAChD,CAAC;AACH,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;AAC/F,wBAAwB,CAAC,YAAY,GAAG,UAAU,MAA0B;IAC1E,OAAO,kBAAkB,CAAC,2BAA2B,CAAC,MAAM,CAAkC,CAAC,CAAA;AACjG,CAAC,CAAA;AAED,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,YAAY,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;AAC/F,wBAAwB,CAAC,YAAY,GAAG,UAAU,MAA0B;IAC1E,OAAO,kBAAkB,CAAC,2BAA2B,CAAC,MAAM,CAAkC,CAAC,CAAA;AACjG,CAAC,CAAA;AAED,eAAe,wBAAwB,CAAA;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAsD,CAAA","sourcesContent":["import {createScanSession} from \"./scanSession\"\nimport {NativeModule, requireNativeModule} from \"expo\"\nimport {Platform} from \"react-native\"\n\nimport {installNativeLogConsole} from \"./nativeLogConsole\"\n\nimport {\n BluetoothSettingsUpdate,\n BluetoothSdkModuleEvents,\n BluetoothStatus,\n PhotoCaptureDefaults,\n CalendarEvent,\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovOverrideRequest,\n CameraFovResult,\n CameraFovSetting,\n CameraRoiPosition,\n CameraStatusEvent,\n ConnectOptions,\n DashboardMenuItem,\n Device,\n DeviceModel,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesStatus,\n GalleryStatusEvent,\n HotspotStatusChangeEvent,\n MicPreference,\n NativePhoneNotification,\n NativeNotificationConfig,\n NativeNotificationStatus,\n ObservableStoreCategory,\n OtaQueryResult,\n OtaStartAckEvent,\n PhotoRequestParams,\n PhotoSuccessResponseEvent,\n PublicBluetoothStatus,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlSuccessResponseEvent,\n ScanDiagnostic,\n ScanModelOptions,\n ScanOptions,\n SettingsAckSuccessEvent,\n StreamStartRequest,\n StreamStatusEvent,\n VideoRecordingStartedStatusEvent,\n VideoRecordingSettings,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingStatusEvent,\n VersionInfoResult,\n WarmUpCameraParams,\n SavedWifiNetworksResult,\n WifiForgetResult,\n WifiSearchResult,\n WifiStatusChangeEvent,\n} from \"../BluetoothSdk.types\"\nimport {warmUpCameraParamsForNative} from \"./cameraRequestPayload\"\nimport {photoRequestParamsForNative} from \"./photoRequestPayload\"\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. Raw status getters/listeners stay here so React hooks can\n * shape native store snapshots before app code sees them.\n */\n\ntype GlassesListener = (changed: Partial<GlassesStatus>) => void\ntype BluetoothStatusListener = (changed: Partial<PublicBluetoothStatus>) => 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<PublicBluetoothStatus>\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 setDashboardContent(content: string): 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 getScanDiagnostic?: (model: DeviceModel) => Promise<ScanDiagnostic | null>\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 setCalendarEvents(events: CalendarEvent[]): Promise<void>\n setHeadUpAngle(angleDegrees: number): Promise<void>\n setImuEnabled(enabled: boolean): 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<WifiSearchResult[]>\n getSavedWifiNetworks(): Promise<SavedWifiNetworksResult>\n sendWifiCredentials(ssid: string, password: string): Promise<WifiStatusChangeEvent>\n forgetWifiNetwork(ssid: string): Promise<WifiForgetResult>\n setHotspotState(enabled: boolean): Promise<HotspotStatusChangeEvent>\n /** Enable or disable Wi-Fi ADB on Mentra Live (no-op on other devices). */\n setWifiAdbState(enabled: boolean): Promise<void>\n /** Set the glasses system clock when phone detects clock skew (Mentra Live and G2). */\n setSystemTime(timestampMs: number): Promise<void>\n /** Logs current WiFi frequency (MHz) and 5 GHz band to Android logcat. */\n logCurrentWifiFrequency(): Promise<void>\n\n // Gallery Commands\n setGalleryModeEnabled(enabled: boolean): Promise<SettingsAckSuccessEvent>\n setVoiceActivityDetectionEnabled(enabled: boolean): Promise<void>\n /** Mentra Live center-mic loudness / Barrier gate (cs_swit type 10). */\n setLoudnessGateEnabled(enabled: boolean): Promise<void>\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for text sensor size/crop).\n */\n setPhotoCaptureDefaults(settings: PhotoCaptureDefaults): Promise<SettingsAckSuccessEvent>\n setVideoRecordingDefaults(width: number, height: number, fps: number): Promise<SettingsAckSuccessEvent>\n setMaxVideoRecordingDuration(minutes: number): Promise<SettingsAckSuccessEvent>\n setCameraFov(request: CameraFovRequest): Promise<CameraFovResult>\n setLegacyCameraFov(request: CameraFovRequest): Promise<CameraFovResult>\n restoreLegacyCameraFov(): Promise<void>\n setCameraFovOverride(request: CameraFovOverrideRequest): Promise<CameraFovResult>\n releaseCameraFovOverride(leaseId: string): Promise<SettingsAckSuccessEvent>\n /**\n * Configure camera HAL tuning (ANR / gain) on Mentra Live glasses.\n * Sends a {@code camera_tuning_config} BLE message; the ASG client relays it as a\n * {@code camconfig} broadcast so the HAL picks up new parameters without a reboot.\n *\n * Scan-mode convention: pass `{anr: false, gain: false}` when activating scan mode\n * (disables ANR and pixsmart gain) and `{anr: true, gain: true}` to restore defaults.\n */\n setCameraTuningConfig(anrOn: boolean, gainOn: boolean): Promise<SettingsAckSuccessEvent>\n queryGalleryStatus(): Promise<GalleryStatusEvent>\n requestPhoto(params: PhotoRequestParams): Promise<PhotoSuccessResponseEvent>\n warmUpCamera(params: WarmUpCameraParams): Promise<CameraStatusEvent>\n stopCameraWarmUp(requestId: string): Promise<void>\n\n // OTA Commands\n setOtaVersionUrl(otaVersionUrl: string): void\n getOtaVersionUrl(): string\n checkForOtaUpdate(): Promise<boolean>\n startOtaUpdate(otaVersionUrl?: string | null): Promise<OtaStartAckEvent>\n sendOtaQueryStatus(): Promise<OtaQueryResult>\n startAr99OtaFromFile(path: string): Promise<boolean>\n cancelAr99Ota(): Promise<void>\n sendAr99FactoryReset(): Promise<void>\n buildAr99OtaSignature(\n secret: string,\n appName: string,\n currentVersion: string,\n serialNumber: string,\n nonce: string,\n ): string\n\n // Version Info Commands\n requestVersionInfo(): Promise<VersionInfoResult>\n\n // Video Recording Commands\n startVideoRecording(\n requestId: string,\n save: boolean,\n sound: boolean,\n settings?: VideoRecordingSettings,\n ): Promise<VideoRecordingStartedStatusEvent>\n stopVideoRecording(\n requestId: string,\n webhookUrl?: string,\n authToken?: string,\n ): Promise<VideoRecordingStoppedStatusEvent>\n queryVideoRecordingStatus(requestId: string): Promise<VideoRecordingStatusEvent>\n\n // Stream Commands\n startStream(params: StreamStartRequest): Promise<StreamStatusEvent>\n stopStream(): Promise<StreamStatusEvent>\n\n // Microphone Commands\n setMicState(enabled: boolean, useGlassesMic?: boolean, sendTranscript?: boolean, sendLc3Data?: boolean): 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 // Live PCM output stream (miniapp speaker.createStream). MentraOS-internal\n // ? 16-bit LE PCM chunks into a streaming AudioTrack (USAGE_MEDIA, so it\n // follows the phone's media route, e.g. A2DP to glasses). Implemented with\n // AudioTrack on Android and AVAudioEngine on iOS.\n /** Open a PCM stream session. One AudioTrack per id; caller manages ids. */\n pcmStreamOpen(streamId: string, sampleRate: number, channels: number, volume: number): Promise<void>\n /**\n * Append base64 PCM. Resolves with the queued-but-unplayed backlog in ms;\n * blocks (on a background dispatcher) while the backlog is above the\n * backpressure ceiling, so awaited writes self-throttle to realtime.\n */\n pcmStreamWrite(streamId: string, base64: string): Promise<{bufferedMs: number}>\n /** Drain the backlog, then stop. Resolves with the total played duration. */\n pcmStreamClose(streamId: string): Promise<{durationMs: number}>\n /** Stop immediately, dropping any backlog. Idempotent. */\n pcmStreamAbort(streamId: string): 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??5 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<RgbLedControlSuccessResponseEvent>\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 // TTS Commands\n setTtsModelDetails(path: string, languageCode: string): Promise<void>\n getTtsModelPath(): Promise<string>\n getTtsModelLanguage(): Promise<string>\n checkTtsModelAvailable(): Promise<boolean>\n validateTtsModel(path: string): Promise<boolean>\n generateTtsAudio(\n text: string,\n modelPath: string,\n outputPath: string,\n speakerId: number,\n speed: number,\n ): Promise<boolean>\n\n /** Android G2 content upload. iOS receives ANCS directly and rejects uploads. */\n sendPhoneNotification(notification: NativePhoneNotification): Promise<void>\n configureNativeNotifications(config: NativeNotificationConfig): Promise<void>\n getNativeNotificationStatus(): Promise<NativeNotificationStatus>\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\")\ninstallNativeLogConsole(NativeBluetoothSdkModule, Platform.OS)\n\nconst DEFAULT_CONNECT_OPTIONS: Required<ConnectOptions> = {\n saveAsDefault: true,\n cancelExistingConnectionAttempt: true,\n requiresAncs: true,\n}\n\nconst DEFAULT_SCAN_TIMEOUT_MS = 15_000\n\nfunction bindNativeMethod<T extends (...args: never[]) => unknown>(module: Record<string, unknown>, name: string): T {\n const method = module[name]\n if (typeof method !== \"function\") {\n console.warn(`[BluetoothSdk] Native method \"${name}\" is unavailable ??rebuild the app (bun android / bun ios)`)\n return (async () => {\n throw new Error(`BluetoothSdk.${name} is not available in this native build. Rebuild the app.`)\n }) as T\n }\n return method.bind(module) as T\n}\n\nconst CAMERA_ROI_MIN = 0\nconst CAMERA_ROI_MAX = 2\nconst CAMERA_ROI_POSITION_VALUES: Record<CameraRoiPosition, CameraFovSetting[\"roiPosition\"]> = {\n center: 0,\n bottom: 1,\n top: 2,\n}\n\n// Named presets are a convenience layer over the numeric {fov, roiPosition} API.\n// The default is the full sensor; \"standard\" preserves the historical 102° crop.\nconst CAMERA_FOV_PRESETS: Record<CameraFovPreset, CameraFovSetting> = {\n narrow: {fov: 82, roiPosition: 0},\n standard: {fov: 102, roiPosition: 0},\n wide: {fov: CAMERA_FOV_MAX, roiPosition: 0},\n}\n\nfunction clampInteger(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, Math.round(value)))\n}\n\nfunction normalizeCameraFov(request: CameraFovRequest): CameraFovSetting {\n if (\"preset\" in request) {\n return CAMERA_FOV_PRESETS[request.preset] ?? CAMERA_FOV_PRESETS.standard\n }\n\n const roiPosition = request.roiPosition ?? \"center\"\n\n return {\n fov: clampInteger(Number.isFinite(request.fov) ? request.fov : CAMERA_FOV_DEFAULT, CAMERA_FOV_MIN, CAMERA_FOV_MAX),\n roiPosition: clampInteger(CAMERA_ROI_POSITION_VALUES[roiPosition] ?? 0, CAMERA_ROI_MIN, CAMERA_ROI_MAX) as\n | 0\n | 1\n | 2,\n }\n}\n\nfunction searchResultsForModel(status: Partial<PublicBluetoothStatus>, 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(\n NativeBluetoothSdkModule,\n) 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 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.setCalendarEvents = function (events: CalendarEvent[]) {\n return this.updateBluetoothSettings({calendar_events: events})\n}\n\nNativeBluetoothSdkModule.setHeadUpAngle = function (angleDegrees: number) {\n return this.updateBluetoothSettings({head_up_angle: angleDegrees})\n}\n\nNativeBluetoothSdkModule.setImuEnabled = function (enabled: boolean) {\n return this.updateBluetoothSettings({imu_enabled: enabled})\n}\n\nNativeBluetoothSdkModule.setScreenDisabled = function (disabled: boolean) {\n return this.updateBluetoothSettings({screen_disabled: disabled})\n}\n\nNativeBluetoothSdkModule.setVoiceActivityDetectionEnabled = function (enabled: boolean) {\n return this.updateBluetoothSettings({voice_activity_detection_enabled: enabled})\n}\n\nNativeBluetoothSdkModule.setLoudnessGateEnabled = function (enabled: boolean) {\n return this.updateBluetoothSettings({loudness_gate_enabled: enabled})\n}\n\nconst nativeSetCameraFov = bindNativeMethod<(fov: CameraFovSetting) => MaybePromise<CameraFovResult>>(\n NativeBluetoothSdkModule as unknown as Record<string, unknown>,\n \"setCameraFov\",\n)\nNativeBluetoothSdkModule.setCameraFov = function (request: CameraFovRequest) {\n const setting = normalizeCameraFov(request)\n return Promise.resolve(nativeSetCameraFov(setting))\n}\n\nconst nativeSetLegacyCameraFov = bindNativeMethod<(fov: CameraFovSetting) => MaybePromise<CameraFovResult>>(\n NativeBluetoothSdkModule as unknown as Record<string, unknown>,\n \"setLegacyCameraFov\",\n)\nNativeBluetoothSdkModule.setLegacyCameraFov = function (request: CameraFovRequest) {\n return Promise.resolve(nativeSetLegacyCameraFov(normalizeCameraFov(request)))\n}\n\nconst nativeRestoreLegacyCameraFov = bindNativeMethod<() => MaybePromise<void>>(\n NativeBluetoothSdkModule as unknown as Record<string, unknown>,\n \"restoreLegacyCameraFov\",\n)\nNativeBluetoothSdkModule.restoreLegacyCameraFov = function () {\n return Promise.resolve(nativeRestoreLegacyCameraFov())\n}\n\nconst nativeSetCameraFovOverride = bindNativeMethod<\n (request: CameraFovSetting & {leaseId: string; ttlMs: number}) => MaybePromise<CameraFovResult>\n>(NativeBluetoothSdkModule as unknown as Record<string, unknown>, \"setCameraFovOverride\")\nNativeBluetoothSdkModule.setCameraFovOverride = function (request: CameraFovOverrideRequest) {\n const setting = normalizeCameraFov(request)\n const requestedTtl =\n typeof request.ttlMs === \"number\" && Number.isFinite(request.ttlMs) && request.ttlMs > 0\n ? Math.round(request.ttlMs)\n : 300_000\n return Promise.resolve(\n nativeSetCameraFovOverride({\n ...setting,\n leaseId: request.leaseId,\n ttlMs: Math.min(requestedTtl, 600_000),\n }),\n )\n}\n\nNativeBluetoothSdkModule.setMicState = function (\n enabled: boolean,\n useGlassesMic?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n) {\n return Promise.resolve(\n nativeSetMicState(enabled, useGlassesMic ?? true, sendTranscript ?? false, sendLc3Data ?? false),\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\nconst nativeStopScan = NativeBluetoothSdkModule.stopScan.bind(NativeBluetoothSdkModule)\nconst activeScanCancellations = new Set<() => Promise<void>>()\nNativeBluetoothSdkModule.stopScan = async function () {\n if (activeScanCancellations.size === 0) return nativeStopScan()\n await Promise.all([...activeScanCancellations].map(cancel => cancel()))\n}\n\nNativeBluetoothSdkModule.scan = async function (modelOrOptions: DeviceModel | ScanOptions, options?: ScanModelOptions) {\n if (activeScanCancellations.size > 0) await this.stopScan()\n const scanOptions = normalizeScanArgs(modelOrOptions, options)\n const timeoutMs = normalizeTimeoutMs(scanOptions.timeoutMs ?? scanOptions.timeout, DEFAULT_SCAN_TIMEOUT_MS)\n const session = createScanSession(\n {\n start: (model) => this.startScan(model),\n stop: nativeStopScan,\n subscribe: (onResults) =>\n this.onBluetoothStatus((status) => {\n if (Array.isArray(status.searchResults)) onResults(searchResultsForModel(status, scanOptions.model))\n }),\n getResults: async () => searchResultsForModel(await this.getBluetoothStatus(), scanOptions.model),\n // Older native binaries simply omit diagnostics until the host is rebuilt.\n getDiagnostic:\n typeof this.getScanDiagnostic === \"function\" ? () => this.getScanDiagnostic!(scanOptions.model) : undefined,\n },\n {...scanOptions, timeoutMs},\n )\n activeScanCancellations.add(session.cancel)\n try {\n return await session.result\n } finally {\n activeScanCancellations.delete(session.cancel)\n }\n}\n\nconst nativeRequestPhoto = NativeBluetoothSdkModule.requestPhoto.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.requestPhoto = function (params: PhotoRequestParams) {\n return nativeRequestPhoto(photoRequestParamsForNative(params) as unknown as PhotoRequestParams)\n}\n\nconst nativeWarmUpCamera = NativeBluetoothSdkModule.warmUpCamera.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.warmUpCamera = function (params: WarmUpCameraParams) {\n return nativeWarmUpCamera(warmUpCameraParamsForNative(params) as unknown as WarmUpCameraParams)\n}\n\nexport default NativeBluetoothSdkModule\nexport const BluetoothSdk = NativeBluetoothSdkModule as BluetoothSdkInternalModule\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export const BLUETOOTH_SDK_RELEASE_METADATA = Object.freeze({
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"familyBaseVersion": "3.2.0",
|
|
4
|
-
"releaseIdentity": "3.2.0-dev.
|
|
5
|
-
"releaseSetId": "mentra-3.2.0-dev.
|
|
6
|
-
"sourceCommit": "
|
|
7
|
-
"otaManifestUrl": "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.
|
|
8
|
-
"otaManifestSha256": "
|
|
4
|
+
"releaseIdentity": "3.2.0-dev.206",
|
|
5
|
+
"releaseSetId": "mentra-3.2.0-dev.206",
|
|
6
|
+
"sourceCommit": "3c22b92a5a53ce608c087503417ca5b3d16cc926",
|
|
7
|
+
"otaManifestUrl": "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.206.json",
|
|
8
|
+
"otaManifestSha256": "7bc5e09f2757b2c11da58c93459bb0a554f406dd0ae5b50b58db28b64b92c838"
|
|
9
9
|
});
|
|
10
10
|
//# sourceMappingURL=releaseMetadata.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,8BAA8B,GAA0C,MAAM,CAAC,MAAM,CAAC;IACjG,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,wHAAwH;IAC1I,mBAAmB,EAAE,kEAAkE;CACxF,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface BluetoothSdkReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const BLUETOOTH_SDK_RELEASE_METADATA: Readonly<BluetoothSdkReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"3.2.0\",\n \"releaseIdentity\": \"3.2.0-dev.
|
|
1
|
+
{"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,8BAA8B,GAA0C,MAAM,CAAC,MAAM,CAAC;IACjG,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,wHAAwH;IAC1I,mBAAmB,EAAE,kEAAkE;CACxF,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface BluetoothSdkReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const BLUETOOTH_SDK_RELEASE_METADATA: Readonly<BluetoothSdkReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"3.2.0\",\n \"releaseIdentity\": \"3.2.0-dev.206\",\n \"releaseSetId\": \"mentra-3.2.0-dev.206\",\n \"sourceCommit\": \"3c22b92a5a53ce608c087503417ca5b3d16cc926\",\n \"otaManifestUrl\": \"https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.206.json\",\n \"otaManifestSha256\": \"7bc5e09f2757b2c11da58c93459bb0a554f406dd0ae5b50b58db28b64b92c838\"\n})\n"]}
|
|
@@ -625,22 +625,11 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
625
625
|
return try await sdk.startStream(StreamRequest(values: params)).values
|
|
626
626
|
}
|
|
627
627
|
|
|
628
|
-
AsyncFunction("startExternallyManagedStream") { (params: [String: Any]) in
|
|
629
|
-
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
630
|
-
return try await sdk.startExternallyManagedStream(StreamRequest(values: params)).values
|
|
631
|
-
}
|
|
632
|
-
|
|
633
628
|
AsyncFunction("stopStream") {
|
|
634
629
|
let sdk = await MainActor.run { self.bluetoothSdk() }
|
|
635
630
|
return try await sdk.stopStream().values
|
|
636
631
|
}
|
|
637
632
|
|
|
638
|
-
AsyncFunction("sendExternallyManagedStreamKeepAlive") { (params: [String: Any]) in
|
|
639
|
-
await MainActor.run {
|
|
640
|
-
self.bluetoothSdk().sendExternallyManagedStreamKeepAlive(StreamKeepAliveRequest(values: params))
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
|
|
644
633
|
// MARK: - Audio Playback Monitoring
|
|
645
634
|
|
|
646
635
|
AsyncFunction("setOwnAppAudioPlaying") { (playing: Bool) in
|
|
@@ -11,7 +11,7 @@ enum BluetoothSdkDefaults {
|
|
|
11
11
|
static let voiceActivityDetectionEnabled = false
|
|
12
12
|
static let loudnessGateEnabled = false
|
|
13
13
|
private static let infoSdkVersionKey = "MentraBluetoothSdkVersion"
|
|
14
|
-
private static let swiftPackageSdkVersion = "3.2.0-dev.
|
|
14
|
+
private static let swiftPackageSdkVersion = "3.2.0-dev.206"
|
|
15
15
|
private static let swiftPackageSdkVersionPlaceholder = "__MENTRA" + "_BLUETOOTH_SDK_VERSION__"
|
|
16
16
|
|
|
17
17
|
private static func normalizedSdkVersion(_ value: String?) -> String? {
|
|
@@ -3,9 +3,9 @@ import Foundation
|
|
|
3
3
|
/// Generated by release CI. Do not edit in a release checkout.
|
|
4
4
|
enum GeneratedReleaseMetadata {
|
|
5
5
|
static let familyBaseVersion = "3.2.0"
|
|
6
|
-
static let releaseIdentity = "3.2.0-dev.
|
|
7
|
-
static let releaseSetId = "mentra-3.2.0-dev.
|
|
8
|
-
static let sourceCommit = "
|
|
9
|
-
static let otaManifestUrl = "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.
|
|
10
|
-
static let otaManifestSha256 = "
|
|
6
|
+
static let releaseIdentity = "3.2.0-dev.206"
|
|
7
|
+
static let releaseSetId = "mentra-3.2.0-dev.206"
|
|
8
|
+
static let sourceCommit = "3c22b92a5a53ce608c087503417ca5b3d16cc926"
|
|
9
|
+
static let otaManifestUrl = "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.206.json"
|
|
10
|
+
static let otaManifestSha256 = "7bc5e09f2757b2c11da58c93459bb0a554f406dd0ae5b50b58db28b64b92c838"
|
|
11
11
|
}
|
|
@@ -1,24 +1,6 @@
|
|
|
1
1
|
import CoreBluetooth
|
|
2
2
|
import Foundation
|
|
3
3
|
|
|
4
|
-
@MainActor
|
|
5
|
-
private final class ActiveStreamKeepAlive {
|
|
6
|
-
let streamId: String
|
|
7
|
-
let intervalSeconds: Int
|
|
8
|
-
var pendingAckId: String?
|
|
9
|
-
var missedAckCount = 0
|
|
10
|
-
var task: Task<Void, Never>?
|
|
11
|
-
/// Missed-ACK counting only begins once the stream is confirmed live/coming up, so a slow
|
|
12
|
-
/// startup (glasses can't ACK until they reach starting/streaming) can't trip a false
|
|
13
|
-
/// keep-alive timeout before the stream is ever up.
|
|
14
|
-
var armed = false
|
|
15
|
-
|
|
16
|
-
init(streamId: String, intervalSeconds: Int) {
|
|
17
|
-
self.streamId = streamId
|
|
18
|
-
self.intervalSeconds = intervalSeconds
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
4
|
@MainActor
|
|
23
5
|
private final class ActiveScanSession {
|
|
24
6
|
let model: DeviceModel
|
|
@@ -257,7 +239,6 @@ public final class MentraBluetoothSDK {
|
|
|
257
239
|
private static let otaBesVersionWaitMs = 5000
|
|
258
240
|
private static let otaMtkVersionWaitMs = 2000
|
|
259
241
|
private static let otaVersionPollMs = 100
|
|
260
|
-
private static let defaultStreamKeepAliveIntervalSeconds = 5
|
|
261
242
|
|
|
262
243
|
public weak var delegate: MentraBluetoothSDKDelegate?
|
|
263
244
|
|
|
@@ -274,7 +255,7 @@ public final class MentraBluetoothSDK {
|
|
|
274
255
|
private var suppressDefaultDeviceEvents = false
|
|
275
256
|
private var defaultDeviceApplyGeneration = 0
|
|
276
257
|
private var activeScanSessions: [UUID: ActiveScanSession] = [:]
|
|
277
|
-
private
|
|
258
|
+
private let streamSession = StreamSessionState()
|
|
278
259
|
private let analytics: BluetoothSdkAnalytics
|
|
279
260
|
private var pendingPhotoRequests: [String: PendingResponse<PhotoResponseEvent>] = [:]
|
|
280
261
|
private var pendingCameraStatusRequests: [String: PendingResponse<CameraStatusEvent>] = [:]
|
|
@@ -1181,14 +1162,10 @@ public final class MentraBluetoothSDK {
|
|
|
1181
1162
|
}
|
|
1182
1163
|
|
|
1183
1164
|
public func startStream(_ request: StreamRequest) async throws -> StreamStatusEvent {
|
|
1184
|
-
try
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
try await startStream(request, startSdkKeepAlive: false)
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
private func startStream(_ request: StreamRequest, startSdkKeepAlive: Bool) async throws -> StreamStatusEvent {
|
|
1165
|
+
try requireGlassesConnected(operation: "start stream")
|
|
1166
|
+
guard streamSession.supported else {
|
|
1167
|
+
throw BluetoothSdkError(code: "stream_control_unsupported", message: "Update the glasses software before starting a stream.")
|
|
1168
|
+
}
|
|
1192
1169
|
var values = request.values
|
|
1193
1170
|
let streamId = stringValue(values, "streamId").flatMap { $0.isEmpty ? nil : $0 } ?? "sdk-\(UUID().uuidString)"
|
|
1194
1171
|
values["streamId"] = streamId
|
|
@@ -1199,17 +1176,10 @@ public final class MentraBluetoothSDK {
|
|
|
1199
1176
|
// glasses' FIFO.
|
|
1200
1177
|
streamStartSeq += 1
|
|
1201
1178
|
pendingStreamStarts[streamId] = PendingStreamStart(seq: streamStartSeq, pending: pending)
|
|
1202
|
-
stopStreamKeepAliveMonitor()
|
|
1203
1179
|
DeviceManager.shared.startStream(values)
|
|
1204
1180
|
do {
|
|
1205
1181
|
let event = try await pending.wait(timeoutMs: 30000)
|
|
1206
1182
|
pendingStreamStarts.removeValue(forKey: streamId)
|
|
1207
|
-
if startSdkKeepAlive {
|
|
1208
|
-
startStreamKeepAliveMonitor(
|
|
1209
|
-
streamId: streamId,
|
|
1210
|
-
intervalSeconds: Self.defaultStreamKeepAliveIntervalSeconds
|
|
1211
|
-
)
|
|
1212
|
-
}
|
|
1213
1183
|
return event
|
|
1214
1184
|
} catch {
|
|
1215
1185
|
pendingStreamStarts.removeValue(forKey: streamId)
|
|
@@ -1217,10 +1187,6 @@ public final class MentraBluetoothSDK {
|
|
|
1217
1187
|
}
|
|
1218
1188
|
}
|
|
1219
1189
|
|
|
1220
|
-
func sendExternallyManagedStreamKeepAlive(_ request: StreamKeepAliveRequest) {
|
|
1221
|
-
DeviceManager.shared.keepStreamAlive(request.values)
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
1190
|
public func rgbLedControl(_ request: RgbLedRequest) async throws -> RgbLedControlResponseEvent {
|
|
1225
1191
|
let pending = PendingResponse<RgbLedControlResponseEvent>(operation: "RGB LED command \(request.requestId)")
|
|
1226
1192
|
pendingRgbLedRequests[request.requestId] = pending
|
|
@@ -1257,8 +1223,7 @@ public final class MentraBluetoothSDK {
|
|
|
1257
1223
|
// separate the pending starts the glasses consumed before it (lower
|
|
1258
1224
|
// seq) from starts sent after it (higher seq).
|
|
1259
1225
|
streamStartSeq += 1
|
|
1260
|
-
pendingStreamStop = (streamId:
|
|
1261
|
-
stopStreamKeepAliveMonitor()
|
|
1226
|
+
pendingStreamStop = (streamId: streamSession.currentStreamId, seq: streamStartSeq, pending: pending)
|
|
1262
1227
|
DeviceManager.shared.stopStream()
|
|
1263
1228
|
do {
|
|
1264
1229
|
let event = try await pending.wait(timeoutMs: 15000)
|
|
@@ -1639,7 +1604,6 @@ public final class MentraBluetoothSDK {
|
|
|
1639
1604
|
}
|
|
1640
1605
|
|
|
1641
1606
|
public func invalidate() {
|
|
1642
|
-
stopStreamKeepAliveMonitor()
|
|
1643
1607
|
resetWifiProtocolSession(sessionId: "", code: "sdk_closed")
|
|
1644
1608
|
if let bluetoothAvailabilityListenerId {
|
|
1645
1609
|
BluetoothAvailability.shared.removeStateListener(bluetoothAvailabilityListenerId)
|
|
@@ -1735,90 +1699,6 @@ public final class MentraBluetoothSDK {
|
|
|
1735
1699
|
}
|
|
1736
1700
|
}
|
|
1737
1701
|
|
|
1738
|
-
private func startStreamKeepAliveMonitor(streamId: String, intervalSeconds requestedIntervalSeconds: Int) {
|
|
1739
|
-
let intervalSeconds = requestedIntervalSeconds > 0 ? requestedIntervalSeconds : Self.defaultStreamKeepAliveIntervalSeconds
|
|
1740
|
-
let tracker = ActiveStreamKeepAlive(streamId: streamId, intervalSeconds: intervalSeconds)
|
|
1741
|
-
activeStreamKeepAlive = tracker
|
|
1742
|
-
sendNextStreamKeepAlive(for: tracker)
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
private func stopStreamKeepAliveMonitor() {
|
|
1746
|
-
activeStreamKeepAlive?.task?.cancel()
|
|
1747
|
-
activeStreamKeepAlive = nil
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
|
-
private func sendNextStreamKeepAlive(for tracker: ActiveStreamKeepAlive) {
|
|
1751
|
-
guard activeStreamKeepAlive === tracker else { return }
|
|
1752
|
-
|
|
1753
|
-
if tracker.armed, tracker.pendingAckId != nil {
|
|
1754
|
-
tracker.missedAckCount += 1
|
|
1755
|
-
if tracker.missedAckCount >= 3 {
|
|
1756
|
-
activeStreamKeepAlive = nil
|
|
1757
|
-
tracker.task?.cancel()
|
|
1758
|
-
let event = StreamStatusEvent(
|
|
1759
|
-
status: .error(
|
|
1760
|
-
streamId: tracker.streamId,
|
|
1761
|
-
errorDetails: "Stream keep-alive timed out after \(tracker.missedAckCount) missed ACKs",
|
|
1762
|
-
timestamp: Int(Date().timeIntervalSince1970 * 1000),
|
|
1763
|
-
resolvedConfig: nil
|
|
1764
|
-
)
|
|
1765
|
-
)
|
|
1766
|
-
delegate?.mentraBluetoothSDK(self, didReceive: .streamStatus(event))
|
|
1767
|
-
stopStreamKeepAliveMonitor()
|
|
1768
|
-
DeviceManager.shared.stopStream()
|
|
1769
|
-
return
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1773
|
-
let ackId = "ack-\(Int(Date().timeIntervalSince1970 * 1000))"
|
|
1774
|
-
tracker.pendingAckId = ackId
|
|
1775
|
-
DeviceManager.shared.keepStreamAlive(
|
|
1776
|
-
StreamKeepAliveRequest(streamId: tracker.streamId, ackId: ackId).values
|
|
1777
|
-
)
|
|
1778
|
-
|
|
1779
|
-
tracker.task?.cancel()
|
|
1780
|
-
tracker.task = Task { @MainActor [weak self, weak tracker] in
|
|
1781
|
-
guard let tracker else { return }
|
|
1782
|
-
try? await Task.sleep(nanoseconds: UInt64(tracker.intervalSeconds) * 1_000_000_000)
|
|
1783
|
-
self?.sendNextStreamKeepAlive(for: tracker)
|
|
1784
|
-
}
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
private func handleStreamKeepAliveAck(_ event: KeepAliveAckEvent) -> Bool {
|
|
1788
|
-
guard let tracker = activeStreamKeepAlive,
|
|
1789
|
-
event.streamId == tracker.streamId,
|
|
1790
|
-
event.ackId == tracker.pendingAckId
|
|
1791
|
-
else {
|
|
1792
|
-
return false
|
|
1793
|
-
}
|
|
1794
|
-
tracker.pendingAckId = nil
|
|
1795
|
-
tracker.missedAckCount = 0
|
|
1796
|
-
return true
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
private func handleStreamStatusForKeepAlive(_ status: StreamStatus) {
|
|
1800
|
-
guard let streamId = status.streamId,
|
|
1801
|
-
activeStreamKeepAlive?.streamId == streamId
|
|
1802
|
-
else {
|
|
1803
|
-
return
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
switch status.state {
|
|
1807
|
-
case .stopped, .stopping, .error, .reconnectFailed:
|
|
1808
|
-
stopStreamKeepAliveMonitor()
|
|
1809
|
-
default:
|
|
1810
|
-
// A non-terminal status means the stream is live or coming up and the glasses can
|
|
1811
|
-
// now ACK; arm the missed-ACK detector from here so a slow startup before the first
|
|
1812
|
-
// ACK can't trip a false keep-alive timeout. On the arming transition, drop any
|
|
1813
|
-
// pre-arm bookkeeping so a stale unacked id can't immediately count as a miss.
|
|
1814
|
-
if let tracker = activeStreamKeepAlive, !tracker.armed {
|
|
1815
|
-
tracker.armed = true
|
|
1816
|
-
tracker.pendingAckId = nil
|
|
1817
|
-
tracker.missedAckCount = 0
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
1702
|
private func handleStreamStatusForRequests(_ event: StreamStatusEvent) {
|
|
1823
1703
|
if let (streamId, start) = matchingStreamStart(for: event) {
|
|
1824
1704
|
// Preemption is only proven by statuses the start path emits after
|
|
@@ -2569,16 +2449,16 @@ public final class MentraBluetoothSDK {
|
|
|
2569
2449
|
let event = RgbLedControlResponseEvent(values: data)
|
|
2570
2450
|
handleRgbLedResponseForRequests(event)
|
|
2571
2451
|
delegate?.mentraBluetoothSDK(self, didReceive: .rgbLedControlResponse(event))
|
|
2452
|
+
case "stream_control_ready":
|
|
2453
|
+
streamSession.ready(sessionId: data["sid"] as? String, controlVersion: data["streamControlVersion"] as? Int)
|
|
2572
2454
|
case "stream_status":
|
|
2455
|
+
if data["revision"] != nil && !streamSession.accept(data) { return }
|
|
2573
2456
|
let event = StreamStatusEvent(values: data)
|
|
2574
2457
|
handleStreamStatusForRequests(event)
|
|
2575
|
-
handleStreamStatusForKeepAlive(event.status)
|
|
2576
2458
|
delegate?.mentraBluetoothSDK(self, didReceive: .streamStatus(event))
|
|
2577
2459
|
case "keep_alive_ack":
|
|
2578
2460
|
let event = KeepAliveAckEvent(values: data)
|
|
2579
|
-
|
|
2580
|
-
delegate?.mentraBluetoothSDK(self, didReceive: .keepAliveAck(event))
|
|
2581
|
-
}
|
|
2461
|
+
delegate?.mentraBluetoothSDK(self, didReceive: .keepAliveAck(event))
|
|
2582
2462
|
case "ota_start_ack":
|
|
2583
2463
|
var values = data
|
|
2584
2464
|
values["type"] = "ota_start_ack"
|
|
@@ -1022,17 +1022,17 @@ extension MentraLive: CBCentralManagerDelegate {
|
|
|
1022
1022
|
}
|
|
1023
1023
|
|
|
1024
1024
|
#if !os(macOS)
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1025
|
+
nonisolated func centralManager(
|
|
1026
|
+
_: CBCentralManager, didUpdateANCSAuthorizationFor peripheral: CBPeripheral
|
|
1027
|
+
) {
|
|
1028
|
+
DispatchQueue.main.async { [weak self] in
|
|
1029
|
+
guard let self, peripheral === self.connectedPeripheral else { return }
|
|
1030
|
+
Bridge.log(
|
|
1031
|
+
"LIVE: ANCS authorization updated: \(peripheral.ancsAuthorized ? "authorized" : "not authorized")"
|
|
1032
|
+
)
|
|
1033
|
+
self.enableAncsRelayIfAuthorized()
|
|
1034
|
+
}
|
|
1034
1035
|
}
|
|
1035
|
-
}
|
|
1036
1036
|
#endif
|
|
1037
1037
|
|
|
1038
1038
|
nonisolated func centralManager(
|
|
@@ -2154,6 +2154,8 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2154
2154
|
Bridge.log("Starting stream")
|
|
2155
2155
|
var json = message
|
|
2156
2156
|
json.removeValue(forKey: "timestamp")
|
|
2157
|
+
json["controllerProbeVersion"] = 1
|
|
2158
|
+
json["controllerId"] = StreamControllerProbe.controllerId
|
|
2157
2159
|
sendJson(json, wakeUp: true)
|
|
2158
2160
|
}
|
|
2159
2161
|
|
|
@@ -2461,16 +2463,16 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2461
2463
|
startConnectionTimeout()
|
|
2462
2464
|
|
|
2463
2465
|
#if os(macOS)
|
|
2464
|
-
|
|
2466
|
+
centralManager?.connect(peripheral, options: nil)
|
|
2465
2467
|
#else
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2468
|
+
// ANCS is hosted by iOS and is only exposed to authorized accessories.
|
|
2469
|
+
// The default requirement lets the system complete that authorization flow
|
|
2470
|
+
// before the glasses subscribe; apps that do not relay notifications can opt out.
|
|
2471
|
+
Bridge.log("LIVE: ANCS connection requirement \(requiresAncs ? "enabled" : "disabled")")
|
|
2472
|
+
centralManager?.connect(
|
|
2473
|
+
peripheral,
|
|
2474
|
+
options: MentraLiveConnectionOptions.coreBluetoothOptions(requiresAncs: requiresAncs)
|
|
2475
|
+
)
|
|
2474
2476
|
#endif
|
|
2475
2477
|
}
|
|
2476
2478
|
|
|
@@ -2479,23 +2481,23 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2479
2481
|
/// for old mobile clients that never send it.
|
|
2480
2482
|
private func enableAncsRelayIfAuthorized() {
|
|
2481
2483
|
#if !os(macOS)
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2484
|
+
guard !ancsRelayEnableRequested,
|
|
2485
|
+
let peripheral = connectedPeripheral,
|
|
2486
|
+
txCharacteristic != nil,
|
|
2487
|
+
rxCharacteristic?.isNotifying == true,
|
|
2488
|
+
peripheral.ancsAuthorized
|
|
2489
|
+
else {
|
|
2490
|
+
return
|
|
2491
|
+
}
|
|
2490
2492
|
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2493
|
+
let command: [String: Any] = [
|
|
2494
|
+
"C": "cs_ancs",
|
|
2495
|
+
"B": ["enabled": 1],
|
|
2496
|
+
]
|
|
2497
|
+
if sendRawK900Command(command) {
|
|
2498
|
+
ancsRelayEnableRequested = true
|
|
2499
|
+
Bridge.log("LIVE: Requested ANCS relay from compatible firmware")
|
|
2500
|
+
}
|
|
2499
2501
|
#endif
|
|
2500
2502
|
}
|
|
2501
2503
|
|
|
@@ -2802,6 +2804,10 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2802
2804
|
body: ["sid": glassesSessionId ?? ""]
|
|
2803
2805
|
)
|
|
2804
2806
|
readinessCompletedThisBleSession = true
|
|
2807
|
+
Bridge.sendTypedMessage("stream_control_ready", body: [
|
|
2808
|
+
"sid": json["sid"] as? String ?? "",
|
|
2809
|
+
"streamControlVersion": json["streamControlVersion"] as? Int ?? 0,
|
|
2810
|
+
])
|
|
2805
2811
|
handleGlassesReady()
|
|
2806
2812
|
|
|
2807
2813
|
case "battery_status":
|
|
@@ -2969,6 +2975,11 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2969
2975
|
let error = json["errorCode"] as? String ?? json["error"] as? String
|
|
2970
2976
|
Bridge.sendRgbLedControlResponse(requestId: requestId, success: success, error: error)
|
|
2971
2977
|
|
|
2978
|
+
case "stream_controller_probe":
|
|
2979
|
+
if let response = StreamControllerProbe.response(json) {
|
|
2980
|
+
sendJson(response)
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2972
2983
|
case "pong":
|
|
2973
2984
|
Bridge.log("LIVE: Received pong response - connection healthy")
|
|
2974
2985
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import CoreFoundation
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
/// Process-scoped native ownership survives BLE reconnects, not app termination.
|
|
5
|
+
enum StreamControllerProbe {
|
|
6
|
+
static let controllerId = UUID().uuidString
|
|
7
|
+
|
|
8
|
+
static func response(_ values: [String: Any]) -> [String: Any]? {
|
|
9
|
+
guard let version = values["protocolVersion"] as? NSNumber,
|
|
10
|
+
CFGetTypeID(version) != CFBooleanGetTypeID(), version.doubleValue == 1,
|
|
11
|
+
values["controllerId"] as? String == controllerId,
|
|
12
|
+
let streamId = values["streamId"] as? String, !streamId.isEmpty,
|
|
13
|
+
let probeId = values["probeId"] as? String, !probeId.isEmpty
|
|
14
|
+
else { return nil }
|
|
15
|
+
return ["type": "stream_controller_response", "protocolVersion": 1,
|
|
16
|
+
"controllerId": controllerId, "streamId": streamId, "probeId": probeId]
|
|
17
|
+
}
|
|
18
|
+
}
|