@mentra/engine 0.1.0-dev.0 → 0.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -1
- package/build/engine.d.ts +11 -3
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +7 -2
- package/build/engine.js.map +1 -1
- package/build/facades/dev.d.ts +3 -2
- package/build/facades/dev.d.ts.map +1 -1
- package/build/facades/dev.js +18 -12
- package/build/facades/dev.js.map +1 -1
- package/build/facades/gallery.js +1 -1
- package/build/facades/gallery.js.map +1 -1
- package/build/facades/glasses.d.ts +1 -0
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +19 -4
- package/build/facades/glasses.js.map +1 -1
- package/build/facades/glassesSettings.d.ts.map +1 -1
- package/build/facades/glassesSettings.js +1 -0
- package/build/facades/glassesSettings.js.map +1 -1
- package/build/facades/miniapps.d.ts +4 -0
- package/build/facades/miniapps.d.ts.map +1 -1
- package/build/facades/miniapps.js +5 -0
- package/build/facades/miniapps.js.map +1 -1
- package/build/facades/ota.d.ts +11 -2
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +19 -4
- package/build/facades/ota.js.map +1 -1
- package/build/facades/pairing.d.ts +4 -0
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +10 -8
- package/build/facades/pairing.js.map +1 -1
- package/build/facades/permissions.d.ts +10 -0
- package/build/facades/permissions.d.ts.map +1 -1
- package/build/facades/permissions.js +10 -0
- package/build/facades/permissions.js.map +1 -1
- package/build/facades/phoneNotifications.d.ts +0 -4
- package/build/facades/phoneNotifications.d.ts.map +1 -1
- package/build/facades/phoneNotifications.js +4 -14
- package/build/facades/phoneNotifications.js.map +1 -1
- package/build/index.d.ts +6 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -2
- package/build/index.js.map +1 -1
- package/build/internal.d.ts +3 -2
- package/build/internal.d.ts.map +1 -1
- package/build/internal.js +2 -1
- package/build/internal.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.d.ts +38 -0
- package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
- package/build/react/MentraLiveOtaFlow.js +528 -0
- package/build/react/MentraLiveOtaFlow.js.map +1 -0
- package/build/react/index.d.ts +2 -0
- package/build/react/index.d.ts.map +1 -0
- package/build/react/index.js +2 -0
- package/build/react/index.js.map +1 -0
- package/build/react/useEngineSnapshot.d.ts +2 -0
- package/build/react/useEngineSnapshot.d.ts.map +1 -0
- package/build/react/useEngineSnapshot.js +14 -0
- package/build/react/useEngineSnapshot.js.map +1 -0
- package/build/runtime/bootstrap.d.ts +24 -1
- package/build/runtime/bootstrap.d.ts.map +1 -1
- package/build/runtime/bootstrap.js +17 -0
- package/build/runtime/bootstrap.js.map +1 -1
- package/build/runtime/scanQrSeam.d.ts +7 -0
- package/build/runtime/scanQrSeam.d.ts.map +1 -0
- package/build/runtime/scanQrSeam.js +16 -0
- package/build/runtime/scanQrSeam.js.map +1 -0
- package/build/services/AppRegistry.d.ts +33 -57
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +193 -144
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/AudioCloudUplink.d.ts +12 -0
- package/build/services/AudioCloudUplink.d.ts.map +1 -1
- package/build/services/AudioCloudUplink.js +22 -1
- package/build/services/AudioCloudUplink.js.map +1 -1
- package/build/services/AudioPlaybackService.d.ts +41 -2
- package/build/services/AudioPlaybackService.d.ts.map +1 -1
- package/build/services/AudioPlaybackService.js +250 -33
- package/build/services/AudioPlaybackService.js.map +1 -1
- package/build/services/BlobStore.d.ts +2 -1
- package/build/services/BlobStore.d.ts.map +1 -1
- package/build/services/BlobStore.js +17 -9
- package/build/services/BlobStore.js.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.js +13 -1
- package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
- package/build/services/CloudClientService.d.ts +15 -0
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +93 -1
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DeviceEventRouter.js +5 -5
- package/build/services/DeviceEventRouter.js.map +1 -1
- package/build/services/ForegroundLocationPermission.d.ts +13 -0
- package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
- package/build/services/ForegroundLocationPermission.js +12 -0
- package/build/services/ForegroundLocationPermission.js.map +1 -0
- package/build/services/GlassesSettingsSync.d.ts.map +1 -1
- package/build/services/GlassesSettingsSync.js +9 -3
- package/build/services/GlassesSettingsSync.js.map +1 -1
- package/build/services/GlassesStatusProjection.d.ts +2 -1
- package/build/services/GlassesStatusProjection.d.ts.map +1 -1
- package/build/services/GlassesStatusProjection.js +15 -8
- package/build/services/GlassesStatusProjection.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts +29 -0
- package/build/services/HotspotOtaTransport.d.ts.map +1 -0
- package/build/services/HotspotOtaTransport.js +146 -0
- package/build/services/HotspotOtaTransport.js.map +1 -0
- package/build/services/HotspotShutdown.d.ts +17 -0
- package/build/services/HotspotShutdown.d.ts.map +1 -0
- package/build/services/HotspotShutdown.js +29 -0
- package/build/services/HotspotShutdown.js.map +1 -0
- package/build/services/LocalDisplayManager.d.ts +15 -0
- package/build/services/LocalDisplayManager.d.ts.map +1 -1
- package/build/services/LocalDisplayManager.js +106 -20
- package/build/services/LocalDisplayManager.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +74 -2
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +785 -291
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalMiniappStorage.d.ts +32 -0
- package/build/services/LocalMiniappStorage.d.ts.map +1 -0
- package/build/services/LocalMiniappStorage.js +66 -0
- package/build/services/LocalMiniappStorage.js.map +1 -0
- package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
- package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
- package/build/services/LocalMiniappUserIdentity.js +43 -0
- package/build/services/LocalMiniappUserIdentity.js.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js +18 -12
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/MicStateCoordinator.d.ts +42 -1
- package/build/services/MicStateCoordinator.d.ts.map +1 -1
- package/build/services/MicStateCoordinator.js +141 -3
- package/build/services/MicStateCoordinator.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +23 -3
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/MiniappLiveness.d.ts +12 -0
- package/build/services/MiniappLiveness.d.ts.map +1 -0
- package/build/services/MiniappLiveness.js +16 -0
- package/build/services/MiniappLiveness.js.map +1 -0
- package/build/services/NativeHttpResponse.d.ts +3 -0
- package/build/services/NativeHttpResponse.d.ts.map +1 -0
- package/build/services/NativeHttpResponse.js +6 -0
- package/build/services/NativeHttpResponse.js.map +1 -0
- package/build/services/OtaArtifactDownloader.d.ts +65 -0
- package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
- package/build/services/OtaArtifactDownloader.js +226 -0
- package/build/services/OtaArtifactDownloader.js.map +1 -0
- package/build/services/OtaAutoChain.d.ts +34 -0
- package/build/services/OtaAutoChain.d.ts.map +1 -0
- package/build/services/OtaAutoChain.js +83 -0
- package/build/services/OtaAutoChain.js.map +1 -0
- package/build/services/OtaErrorMapping.d.ts +18 -0
- package/build/services/OtaErrorMapping.d.ts.map +1 -0
- package/build/services/OtaErrorMapping.js +63 -0
- package/build/services/OtaErrorMapping.js.map +1 -0
- package/build/services/OtaInstallCoordinator.d.ts +94 -14
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +574 -130
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/OtaService.d.ts.map +1 -1
- package/build/services/OtaService.js +8 -1
- package/build/services/OtaService.js.map +1 -1
- package/build/services/OtaUpdateCheckService.d.ts +38 -3
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +142 -22
- package/build/services/OtaUpdateCheckService.js.map +1 -1
- package/build/services/PhoneCalendarHelpers.d.ts +32 -0
- package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
- package/build/services/PhoneCalendarHelpers.js +157 -0
- package/build/services/PhoneCalendarHelpers.js.map +1 -0
- package/build/services/PhoneCalendarService.d.ts +5 -0
- package/build/services/PhoneCalendarService.d.ts.map +1 -0
- package/build/services/PhoneCalendarService.js +45 -0
- package/build/services/PhoneCalendarService.js.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.js +194 -0
- package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +12 -10
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts +26 -2
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
- package/build/services/PhonePhotoCoordinator.js +79 -9
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts +8 -1
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
- package/build/services/PhoneStreamCoordinator.js +125 -13
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/PhoneVideoCoordinator.d.ts +2 -0
- package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
- package/build/services/PhoneVideoCoordinator.js +10 -0
- package/build/services/PhoneVideoCoordinator.js.map +1 -1
- package/build/services/SceneRenderer.d.ts.map +1 -1
- package/build/services/SceneRenderer.js +15 -0
- package/build/services/SceneRenderer.js.map +1 -1
- package/build/services/SentenceTtsPipeline.d.ts +31 -0
- package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
- package/build/services/SentenceTtsPipeline.js +67 -0
- package/build/services/SentenceTtsPipeline.js.map +1 -0
- package/build/services/SupportProfileSync.d.ts +22 -0
- package/build/services/SupportProfileSync.d.ts.map +1 -0
- package/build/services/SupportProfileSync.js +213 -0
- package/build/services/SupportProfileSync.js.map +1 -0
- package/build/services/TranscriptionRouting.d.ts +12 -0
- package/build/services/TranscriptionRouting.d.ts.map +1 -0
- package/build/services/TranscriptionRouting.js +24 -0
- package/build/services/TranscriptionRouting.js.map +1 -0
- package/build/services/TtsTextSanitizer.d.ts +5 -0
- package/build/services/TtsTextSanitizer.d.ts.map +1 -0
- package/build/services/TtsTextSanitizer.js +61 -0
- package/build/services/TtsTextSanitizer.js.map +1 -0
- package/build/services/WifiAdbRequest.d.ts +17 -0
- package/build/services/WifiAdbRequest.d.ts.map +1 -0
- package/build/services/WifiAdbRequest.js +35 -0
- package/build/services/WifiAdbRequest.js.map +1 -0
- package/build/services/asg/asgCameraApi.d.ts +43 -0
- package/build/services/asg/asgCameraApi.d.ts.map +1 -1
- package/build/services/asg/asgCameraApi.js +509 -26
- package/build/services/asg/asgCameraApi.js.map +1 -1
- package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
- package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportCoordinator.js +618 -0
- package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
- package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
- package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportLedger.js +78 -0
- package/build/services/asg/cameraRollExportLedger.js.map +1 -0
- package/build/services/asg/galleryNotices.d.ts +1 -1
- package/build/services/asg/galleryNotices.d.ts.map +1 -1
- package/build/services/asg/galleryNotices.js.map +1 -1
- package/build/services/asg/galleryPathMigration.d.ts +3 -0
- package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
- package/build/services/asg/galleryPathMigration.js +26 -0
- package/build/services/asg/galleryPathMigration.js.map +1 -0
- package/build/services/asg/gallerySettingsService.d.ts +1 -0
- package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
- package/build/services/asg/gallerySettingsService.js +2 -0
- package/build/services/asg/gallerySettingsService.js.map +1 -1
- package/build/services/asg/gallerySyncService.d.ts.map +1 -1
- package/build/services/asg/gallerySyncService.js +162 -56
- package/build/services/asg/gallerySyncService.js.map +1 -1
- package/build/services/asg/galleryTransferLedger.d.ts +58 -0
- package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
- package/build/services/asg/galleryTransferLedger.js +225 -0
- package/build/services/asg/galleryTransferLedger.js.map +1 -0
- package/build/services/asg/localNetworkTransport.d.ts +15 -0
- package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
- package/build/services/asg/localNetworkTransport.js +144 -0
- package/build/services/asg/localNetworkTransport.js.map +1 -0
- package/build/services/asg/localStorageService.d.ts +18 -0
- package/build/services/asg/localStorageService.d.ts.map +1 -1
- package/build/services/asg/localStorageService.js +168 -19
- package/build/services/asg/localStorageService.js.map +1 -1
- package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
- package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
- package/build/services/asg/mediaProcessingQueue.js +193 -62
- package/build/services/asg/mediaProcessingQueue.js.map +1 -1
- package/build/services/audioPlaybackAssets.d.ts +8 -0
- package/build/services/audioPlaybackAssets.d.ts.map +1 -0
- package/build/services/audioPlaybackAssets.js +7 -0
- package/build/services/audioPlaybackAssets.js.map +1 -0
- package/build/services/gallerySyncClock.js +1 -1
- package/build/services/gallerySyncClock.js.map +1 -1
- package/build/services/glassesClockSync.js +2 -2
- package/build/services/glassesClockSync.js.map +1 -1
- package/build/services/manifestActions.d.ts +7 -0
- package/build/services/manifestActions.d.ts.map +1 -0
- package/build/services/manifestActions.js +25 -0
- package/build/services/manifestActions.js.map +1 -0
- package/build/services/otaDisplayState.d.ts +22 -11
- package/build/services/otaDisplayState.d.ts.map +1 -1
- package/build/services/otaDisplayState.js +36 -14
- package/build/services/otaDisplayState.js.map +1 -1
- package/build/services/otaInstallPolicy.d.ts +15 -3
- package/build/services/otaInstallPolicy.d.ts.map +1 -1
- package/build/services/otaInstallPolicy.js +24 -3
- package/build/services/otaInstallPolicy.js.map +1 -1
- package/build/services/otaManifestUrl.d.ts +2 -0
- package/build/services/otaManifestUrl.d.ts.map +1 -0
- package/build/services/{asgOtaVersionUrl.js → otaManifestUrl.js} +15 -5
- package/build/services/otaManifestUrl.js.map +1 -0
- package/build/services/slimStreamStatus.d.ts +11 -0
- package/build/services/slimStreamStatus.d.ts.map +1 -1
- package/build/services/slimStreamStatus.js +14 -4
- package/build/services/slimStreamStatus.js.map +1 -1
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +11 -0
- package/build/stores/apps.js.map +1 -1
- package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
- package/build/stores/bluetoothSettingKeys.js +2 -0
- package/build/stores/bluetoothSettingKeys.js.map +1 -1
- package/build/stores/gallerySync.d.ts +2 -0
- package/build/stores/gallerySync.d.ts.map +1 -1
- package/build/stores/gallerySync.js +2 -0
- package/build/stores/gallerySync.js.map +1 -1
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js +3 -0
- package/build/stores/glasses.js.map +1 -1
- package/build/stores/settings.d.ts +17 -0
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +157 -17
- package/build/stores/settings.js.map +1 -1
- package/build/types/applet.d.ts +2 -0
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/build/types/asg.d.ts +7 -0
- package/build/types/asg.d.ts.map +1 -1
- package/build/types/asg.js.map +1 -1
- package/build/types/enums.d.ts +1 -0
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +1 -0
- package/build/types/enums.js.map +1 -1
- package/build/types/hardware.d.ts +1 -0
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +14 -0
- package/build/types/hardware.js.map +1 -1
- package/build/utils/configuredDevHost.d.ts +6 -0
- package/build/utils/configuredDevHost.d.ts.map +1 -0
- package/build/utils/configuredDevHost.js +19 -0
- package/build/utils/configuredDevHost.js.map +1 -0
- package/build/utils/devMiniappLaunch.d.ts +19 -8
- package/build/utils/devMiniappLaunch.d.ts.map +1 -1
- package/build/utils/devMiniappLaunch.js +144 -21
- package/build/utils/devMiniappLaunch.js.map +1 -1
- package/build/utils/diagnosticContext.d.ts.map +1 -1
- package/build/utils/diagnosticContext.js +15 -17
- package/build/utils/diagnosticContext.js.map +1 -1
- package/build/utils/hardware/hardware.d.ts.map +1 -1
- package/build/utils/hardware/hardware.js +7 -3
- package/build/utils/hardware/hardware.js.map +1 -1
- package/build/utils/miniappDiagnostics.d.ts +64 -0
- package/build/utils/miniappDiagnostics.d.ts.map +1 -0
- package/build/utils/miniappDiagnostics.js +173 -0
- package/build/utils/miniappDiagnostics.js.map +1 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
- package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
- package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
- package/build/utils/timers/timers.d.ts.map +1 -1
- package/build/utils/timers/timers.js +55 -18
- package/build/utils/timers/timers.js.map +1 -1
- package/package.json +25 -15
- package/src/assets/silence.wav +0 -0
- package/src/engine.ts +7 -2
- package/src/facades/dev.ts +17 -12
- package/src/facades/gallery.ts +1 -1
- package/src/facades/glasses.ts +17 -4
- package/src/facades/glassesSettings.ts +5 -0
- package/src/facades/miniapps.ts +7 -0
- package/src/facades/ota.ts +19 -4
- package/src/facades/pairing.ts +11 -7
- package/src/facades/permissions.ts +14 -0
- package/src/facades/phoneNotifications.ts +4 -13
- package/src/index.ts +26 -2
- package/src/internal.ts +3 -1
- package/src/react/MentraLiveOtaFlow.tsx +856 -0
- package/src/react/index.ts +7 -0
- package/src/react/useEngineSnapshot.ts +16 -0
- package/src/runtime/bootstrap.ts +33 -1
- package/src/runtime/scanQrSeam.ts +20 -0
- package/src/services/AppRegistry.ts +224 -149
- package/src/services/AudioCloudUplink.ts +23 -1
- package/src/services/AudioPlaybackService.ts +287 -38
- package/src/services/BlobStore.ts +22 -9
- package/src/services/CloudAudioSubscriptionSync.ts +13 -1
- package/src/services/CloudClientService.ts +96 -1
- package/src/services/DeviceEventRouter.ts +5 -5
- package/src/services/ForegroundLocationPermission.ts +24 -0
- package/src/services/GlassesSettingsSync.ts +9 -3
- package/src/services/GlassesStatusProjection.ts +16 -8
- package/src/services/HotspotOtaTransport.ts +184 -0
- package/src/services/HotspotShutdown.ts +41 -0
- package/src/services/LocalDisplayManager.ts +112 -21
- package/src/services/LocalMiniappRuntime.ts +967 -346
- package/src/services/LocalMiniappStorage.ts +82 -0
- package/src/services/LocalMiniappUserIdentity.ts +46 -0
- package/src/services/LocalSttFallbackCoordinator.ts +19 -12
- package/src/services/MicStateCoordinator.ts +169 -4
- package/src/services/MiniappLauncher.ts +30 -3
- package/src/services/MiniappLiveness.ts +24 -0
- package/src/services/NativeHttpResponse.ts +6 -0
- package/src/services/OtaArtifactDownloader.ts +312 -0
- package/src/services/OtaAutoChain.ts +106 -0
- package/src/services/OtaErrorMapping.ts +80 -0
- package/src/services/OtaInstallCoordinator.ts +645 -143
- package/src/services/OtaService.ts +11 -5
- package/src/services/OtaUpdateCheckService.ts +180 -20
- package/src/services/PhoneCalendarHelpers.ts +212 -0
- package/src/services/PhoneCalendarService.ts +65 -0
- package/src/services/PhoneCameraFovCoordinator.ts +210 -0
- package/src/services/PhoneNotificationsSync.ts +12 -10
- package/src/services/PhonePhotoCoordinator.ts +116 -18
- package/src/services/PhoneStreamCoordinator.ts +139 -25
- package/src/services/PhoneVideoCoordinator.ts +11 -0
- package/src/services/SceneRenderer.ts +16 -0
- package/src/services/SentenceTtsPipeline.ts +106 -0
- package/src/services/SupportProfileSync.ts +218 -0
- package/src/services/TranscriptionRouting.ts +37 -0
- package/src/services/TtsTextSanitizer.ts +66 -0
- package/src/services/WifiAdbRequest.ts +53 -0
- package/src/services/asg/asgCameraApi.ts +615 -33
- package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
- package/src/services/asg/cameraRollExportLedger.ts +122 -0
- package/src/services/asg/galleryNotices.ts +1 -0
- package/src/services/asg/galleryPathMigration.ts +22 -0
- package/src/services/asg/gallerySettingsService.ts +3 -0
- package/src/services/asg/gallerySyncService.ts +184 -73
- package/src/services/asg/galleryTransferLedger.ts +312 -0
- package/src/services/asg/localNetworkTransport.ts +169 -0
- package/src/services/asg/localStorageService.ts +179 -24
- package/src/services/asg/mediaProcessingQueue.ts +209 -62
- package/src/services/audioPlaybackAssets.ts +8 -0
- package/src/services/gallerySyncClock.ts +1 -1
- package/src/services/glassesClockSync.ts +2 -2
- package/src/services/manifestActions.ts +30 -0
- package/src/services/otaDisplayState.ts +57 -16
- package/src/services/otaInstallPolicy.ts +29 -3
- package/src/services/{asgOtaVersionUrl.ts → otaManifestUrl.ts} +16 -4
- package/src/services/slimStreamStatus.ts +16 -5
- package/src/stores/apps.ts +12 -0
- package/src/stores/bluetoothSettingKeys.ts +2 -0
- package/src/stores/gallerySync.ts +4 -0
- package/src/stores/glasses.ts +3 -0
- package/src/stores/settings.ts +179 -18
- package/src/types/applet.ts +2 -0
- package/src/types/asg.ts +7 -0
- package/src/types/enums.ts +2 -1
- package/src/types/hardware.ts +17 -0
- package/src/utils/configuredDevHost.ts +17 -0
- package/src/utils/devMiniappLaunch.ts +151 -23
- package/src/utils/diagnosticContext.ts +17 -17
- package/src/utils/hardware/hardware.ts +7 -9
- package/src/utils/miniappDiagnostics.ts +226 -0
- package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
- package/src/utils/timers/timers.ts +57 -21
- package/build/services/asgOtaVersionUrl.d.ts +0 -2
- package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
- package/build/services/asgOtaVersionUrl.js.map +0 -1
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import BluetoothSdk, {type CameraFovRequest, type CameraFovResult} from "@mentra/bluetooth-sdk/internal"
|
|
2
|
+
|
|
3
|
+
export const CAMERA_FOV_OVERRIDE_TTL_MS = 300_000
|
|
4
|
+
export const CAMERA_FOV_OVERRIDE_REFRESH_MS = 120_000
|
|
5
|
+
// Legacy ASG clients restart the camera HAL for an FOV update but cannot acknowledge
|
|
6
|
+
// when it is usable again. The ASG cooldown is 5s; retain a small settling margin so
|
|
7
|
+
// miniapps cannot submit a photo against the stale camera service.
|
|
8
|
+
const LEGACY_CAMERA_RESTART_SETTLE_MS = 7_000
|
|
9
|
+
|
|
10
|
+
interface OverrideEntry {
|
|
11
|
+
leaseId: string
|
|
12
|
+
fov: number
|
|
13
|
+
roiPosition: "center" | "bottom" | "top"
|
|
14
|
+
order: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let leaseCounter = 0
|
|
18
|
+
|
|
19
|
+
function mintLeaseId(): string {
|
|
20
|
+
leaseCounter = (leaseCounter + 1) & 0xffff
|
|
21
|
+
return `fov-${leaseCounter.toString(16).padStart(4, "0")}`
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isLegacyFovCompatibilityError(error: unknown): boolean {
|
|
25
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
26
|
+
return /timed out waiting for glasses response|not available|unknown method/i.test(message)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Serializes miniapp-owned FOV/ROI overrides. The last live owner wins; releasing it applies the
|
|
31
|
+
* previous owner or asks ASG to restore its persistent base. ASG refreshes are no-restart TTL
|
|
32
|
+
* extensions for crash safety.
|
|
33
|
+
*/
|
|
34
|
+
export class PhoneCameraFovCoordinator {
|
|
35
|
+
private readonly overrides = new Map<string, OverrideEntry>()
|
|
36
|
+
private effectiveLeaseId: string | undefined
|
|
37
|
+
private sequence = 0
|
|
38
|
+
private queue: Promise<unknown> = Promise.resolve()
|
|
39
|
+
private refreshTimer: ReturnType<typeof setTimeout> | undefined
|
|
40
|
+
private legacyMode = false
|
|
41
|
+
|
|
42
|
+
constructor(private readonly legacyRestartSettleMs = LEGACY_CAMERA_RESTART_SETTLE_MS) {}
|
|
43
|
+
|
|
44
|
+
/** Report-safe FOV ownership snapshot for incident diagnostics. */
|
|
45
|
+
getDiagnosticSnapshot(): Record<string, unknown> {
|
|
46
|
+
return {
|
|
47
|
+
owners: [...this.overrides.entries()]
|
|
48
|
+
.sort(([, a], [, b]) => b.order - a.order)
|
|
49
|
+
.map(([packageName, entry]) => ({
|
|
50
|
+
packageName,
|
|
51
|
+
effective: entry.leaseId === this.effectiveLeaseId,
|
|
52
|
+
fov: entry.fov,
|
|
53
|
+
roiPosition: entry.roiPosition,
|
|
54
|
+
})),
|
|
55
|
+
legacyMode: this.legacyMode,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
setOverride(packageName: string, request: CameraFovRequest): Promise<CameraFovResult> {
|
|
60
|
+
return this.enqueue(async () => {
|
|
61
|
+
const previous = this.overrides.get(packageName)
|
|
62
|
+
const leaseId = previous?.leaseId ?? mintLeaseId()
|
|
63
|
+
const order = ++this.sequence
|
|
64
|
+
try {
|
|
65
|
+
if (this.legacyMode) return this.setLegacyOverride(packageName, request, leaseId, order)
|
|
66
|
+
const result = await BluetoothSdk.setCameraFovOverride({
|
|
67
|
+
...request,
|
|
68
|
+
leaseId,
|
|
69
|
+
ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,
|
|
70
|
+
})
|
|
71
|
+
this.overrides.set(packageName, {
|
|
72
|
+
leaseId,
|
|
73
|
+
fov: result.fov,
|
|
74
|
+
roiPosition: result.roiPosition,
|
|
75
|
+
order,
|
|
76
|
+
})
|
|
77
|
+
this.effectiveLeaseId = leaseId
|
|
78
|
+
this.scheduleRefresh()
|
|
79
|
+
return result
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (!isLegacyFovCompatibilityError(error)) throw error
|
|
82
|
+
console.warn("[PhoneCameraFovCoordinator] override unavailable; using legacy FOV command", error)
|
|
83
|
+
const result = await this.setLegacyOverride(packageName, request, leaseId, order)
|
|
84
|
+
// Only cache compatibility mode after the fallback itself succeeds. A
|
|
85
|
+
// disconnect or missing native bridge must not permanently downgrade
|
|
86
|
+
// future requests on a healthy/newer glasses connection.
|
|
87
|
+
this.legacyMode = true
|
|
88
|
+
return result
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
releaseForApp(packageName: string): Promise<void> {
|
|
94
|
+
return this.enqueue(async () => {
|
|
95
|
+
const removed = this.overrides.get(packageName)
|
|
96
|
+
if (!removed) return
|
|
97
|
+
if (removed.leaseId !== this.effectiveLeaseId) {
|
|
98
|
+
this.overrides.delete(packageName)
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const next = [...this.overrides.entries()]
|
|
103
|
+
.filter(([candidatePackage]) => candidatePackage !== packageName)
|
|
104
|
+
.map(([, entry]) => entry)
|
|
105
|
+
.sort((a, b) => b.order - a.order)[0]
|
|
106
|
+
if (this.legacyMode) {
|
|
107
|
+
if (next) {
|
|
108
|
+
await this.applyLegacyFov({fov: next.fov, roiPosition: next.roiPosition})
|
|
109
|
+
this.overrides.delete(packageName)
|
|
110
|
+
this.effectiveLeaseId = next.leaseId
|
|
111
|
+
} else {
|
|
112
|
+
// Legacy commands are one-way and have no lease-release protocol.
|
|
113
|
+
// Ask native to replay its unchanged persistent base setting, then
|
|
114
|
+
// probe the modern override path again for the next ownership cycle.
|
|
115
|
+
await BluetoothSdk.restoreLegacyCameraFov()
|
|
116
|
+
await this.waitForLegacyCameraRestart()
|
|
117
|
+
this.overrides.delete(packageName)
|
|
118
|
+
this.clearRefresh()
|
|
119
|
+
this.effectiveLeaseId = undefined
|
|
120
|
+
this.legacyMode = false
|
|
121
|
+
}
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
if (next) {
|
|
125
|
+
await BluetoothSdk.setCameraFovOverride({
|
|
126
|
+
leaseId: next.leaseId,
|
|
127
|
+
fov: next.fov,
|
|
128
|
+
roiPosition: next.roiPosition,
|
|
129
|
+
ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,
|
|
130
|
+
})
|
|
131
|
+
// Commit phone-side ownership only after ASG accepted the replacement. On failure the
|
|
132
|
+
// closing app remains effective here, allowing unregister/reconnect cleanup to retry.
|
|
133
|
+
this.overrides.delete(packageName)
|
|
134
|
+
this.effectiveLeaseId = next.leaseId
|
|
135
|
+
this.scheduleRefresh()
|
|
136
|
+
} else {
|
|
137
|
+
await BluetoothSdk.releaseCameraFovOverride(removed.leaseId)
|
|
138
|
+
this.overrides.delete(packageName)
|
|
139
|
+
this.clearRefresh()
|
|
140
|
+
this.effectiveLeaseId = undefined
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private scheduleRefresh(): void {
|
|
146
|
+
if (this.legacyMode) return
|
|
147
|
+
this.clearRefresh()
|
|
148
|
+
const leaseId = this.effectiveLeaseId
|
|
149
|
+
if (!leaseId) return
|
|
150
|
+
this.refreshTimer = setTimeout(() => {
|
|
151
|
+
void this.enqueue(async () => {
|
|
152
|
+
if (this.effectiveLeaseId !== leaseId) return
|
|
153
|
+
const entry = [...this.overrides.values()].find((candidate) => candidate.leaseId === leaseId)
|
|
154
|
+
if (!entry) return
|
|
155
|
+
await BluetoothSdk.setCameraFovOverride({
|
|
156
|
+
leaseId,
|
|
157
|
+
fov: entry.fov,
|
|
158
|
+
roiPosition: entry.roiPosition,
|
|
159
|
+
ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,
|
|
160
|
+
})
|
|
161
|
+
this.scheduleRefresh()
|
|
162
|
+
}).catch((error) => console.warn("[PhoneCameraFovCoordinator] failed to refresh override", error))
|
|
163
|
+
}, CAMERA_FOV_OVERRIDE_REFRESH_MS)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private clearRefresh(): void {
|
|
167
|
+
if (this.refreshTimer) clearTimeout(this.refreshTimer)
|
|
168
|
+
this.refreshTimer = undefined
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private async setLegacyOverride(
|
|
172
|
+
packageName: string,
|
|
173
|
+
request: CameraFovRequest,
|
|
174
|
+
leaseId: string,
|
|
175
|
+
order: number,
|
|
176
|
+
): Promise<CameraFovResult> {
|
|
177
|
+
const result = await this.applyLegacyFov(request)
|
|
178
|
+
this.overrides.set(packageName, {
|
|
179
|
+
leaseId,
|
|
180
|
+
fov: result.fov,
|
|
181
|
+
roiPosition: result.roiPosition,
|
|
182
|
+
order,
|
|
183
|
+
})
|
|
184
|
+
this.effectiveLeaseId = leaseId
|
|
185
|
+
this.clearRefresh()
|
|
186
|
+
return result
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private async applyLegacyFov(request: CameraFovRequest): Promise<CameraFovResult> {
|
|
190
|
+
const result = await BluetoothSdk.setLegacyCameraFov(request)
|
|
191
|
+
await this.waitForLegacyCameraRestart()
|
|
192
|
+
return result
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private waitForLegacyCameraRestart(): Promise<void> {
|
|
196
|
+
if (this.legacyRestartSettleMs <= 0) return Promise.resolve()
|
|
197
|
+
return new Promise<void>((resolve) => setTimeout(resolve, this.legacyRestartSettleMs))
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private enqueue<T>(operation: () => Promise<T>): Promise<T> {
|
|
201
|
+
const result = this.queue.then(operation, operation)
|
|
202
|
+
this.queue = result.then(
|
|
203
|
+
() => undefined,
|
|
204
|
+
() => undefined,
|
|
205
|
+
)
|
|
206
|
+
return result
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export const phoneCameraFovCoordinator = new PhoneCameraFovCoordinator()
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Phone-notifications sync — engine-owned. Pushes the notification-forwarding
|
|
3
|
-
*
|
|
3
|
+
* operational kill switch + config (`android_notification_listener_enabled`
|
|
4
|
+
* and `notifications_blocklist`) to the native
|
|
4
5
|
* NotificationListener via `CrustModule.setNotificationConfig`, so
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* the blocklist reaches the listener for ANY host — not just the Mentra App,
|
|
7
|
+
* where this used to live in MantleManager. The Android service is desired by
|
|
8
|
+
* default now that its cold start is isolated from React Native. Native code
|
|
9
|
+
* keeps the component discoverable in Android's notification-access Settings,
|
|
10
|
+
* but only binds the service after access is granted. The debug setting remains
|
|
11
|
+
* a hidden emergency kill switch; Notify's running state gates presentation,
|
|
12
|
+
* not capture. Android-only; a no-op elsewhere. Started by `engine.start()`.
|
|
8
13
|
*/
|
|
9
14
|
import {shallow} from "zustand/shallow"
|
|
10
15
|
import CrustModule from "@mentra/crust"
|
|
@@ -15,12 +20,9 @@ let unsubscribe: (() => void) | null = null
|
|
|
15
20
|
|
|
16
21
|
function pushConfig(): void {
|
|
17
22
|
const s = useSettingsStore.getState()
|
|
18
|
-
const
|
|
23
|
+
const listenerEnabled = Boolean(s.getSetting(SETTINGS.android_notification_listener_enabled.key))
|
|
19
24
|
const blocklist = s.getSetting(SETTINGS.notifications_blocklist.key)
|
|
20
|
-
|
|
21
|
-
// Android-only, but CrustModule.setNotificationConfig is a safe no-op elsewhere;
|
|
22
|
-
// the Android-only gating lives on the facade's setEnabled/setBlocklist.
|
|
23
|
-
CrustModule.setNotificationConfig(enabled, Array.isArray(blocklist) ? blocklist : []).catch((err: unknown) =>
|
|
25
|
+
CrustModule.setNotificationConfig(listenerEnabled, Array.isArray(blocklist) ? blocklist : []).catch((err: unknown) =>
|
|
24
26
|
console.warn(`PhoneNotificationsSync: setNotificationConfig failed: ${(err as Error)?.message ?? err}`),
|
|
25
27
|
)
|
|
26
28
|
}
|
|
@@ -30,7 +32,7 @@ export function startPhoneNotificationsSync(): void {
|
|
|
30
32
|
pushConfig() // initial sync so the listener has the current config
|
|
31
33
|
unsubscribe = useSettingsStore.subscribe(
|
|
32
34
|
(state) => ({
|
|
33
|
-
|
|
35
|
+
listenerEnabled: state.getSetting(SETTINGS.android_notification_listener_enabled.key),
|
|
34
36
|
blocklist: state.getSetting(SETTINGS.notifications_blocklist.key),
|
|
35
37
|
}),
|
|
36
38
|
() => pushConfig(),
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import BluetoothSdk from "@mentra/bluetooth-sdk/internal"
|
|
22
|
-
import type {PhotoSize} from "@mentra/bluetooth-sdk/internal"
|
|
22
|
+
import type {PhotoSize, PhotoTransferMethod} from "@mentra/bluetooth-sdk/internal"
|
|
23
23
|
import {cloudClientService} from "./CloudClientService"
|
|
24
24
|
import {isGlassesConnected} from "./GlassesReadiness"
|
|
25
25
|
import {useGlassesStore} from "../stores/glasses"
|
|
@@ -49,10 +49,23 @@ export interface PhotoOpts {
|
|
|
49
49
|
/** Legacy cloud size names are normalized before the native take_photo command. */
|
|
50
50
|
size?: "low" | "medium" | "high" | "max" | "small" | "large" | "full"
|
|
51
51
|
mode?: "photo" | "text"
|
|
52
|
+
/** Select direct-only, phone-relayed BLE, or the default Wi-Fi/BLE fallback policy. */
|
|
53
|
+
transferMethod?: PhotoTransferMethod
|
|
52
54
|
compress?: "none" | "low" | "medium" | "high"
|
|
53
55
|
sound?: boolean
|
|
54
56
|
saveToGallery?: boolean
|
|
55
57
|
exposureTimeNs?: number
|
|
58
|
+
iso?: number | null
|
|
59
|
+
aeExposureDivisor?: number
|
|
60
|
+
isoCap?: number
|
|
61
|
+
noiseReduction?: boolean
|
|
62
|
+
edgeEnhancement?: boolean
|
|
63
|
+
/** ZSL preview buffering. */
|
|
64
|
+
zsl?: boolean
|
|
65
|
+
/** MFNR still capture. */
|
|
66
|
+
mfnr?: boolean
|
|
67
|
+
ispDigitalGain?: number
|
|
68
|
+
ispAnalogGain?: string
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
export interface PhotoTaken {
|
|
@@ -80,6 +93,15 @@ export class PhotoError extends Error {
|
|
|
80
93
|
}
|
|
81
94
|
}
|
|
82
95
|
|
|
96
|
+
function parsePhotoTransferMethod(value: unknown): PhotoTransferMethod | undefined {
|
|
97
|
+
if (value === undefined) return undefined
|
|
98
|
+
if (value === "auto" || value === "direct" || value === "ble") return value
|
|
99
|
+
throw new PhotoError(
|
|
100
|
+
"INVALID_ARGUMENT",
|
|
101
|
+
`Invalid transferMethod ${JSON.stringify(value)}. Expected "auto", "direct", or "ble".`,
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
83
105
|
interface ActiveRequest {
|
|
84
106
|
packageName: string
|
|
85
107
|
abort: AbortController
|
|
@@ -97,6 +119,8 @@ interface ActiveRequest {
|
|
|
97
119
|
* rejected successful captures while their upload was still in progress.
|
|
98
120
|
*/
|
|
99
121
|
export const CAPTURE_PIPELINE_TIMEOUT_MS = 45_000
|
|
122
|
+
export const CAMERA_WARM_UP_DEFAULT_DURATION_MS = 15_000
|
|
123
|
+
export const CAMERA_WARM_UP_MAX_DURATION_MS = 60_000
|
|
100
124
|
|
|
101
125
|
let bleRequestCounter = 0
|
|
102
126
|
|
|
@@ -120,8 +144,23 @@ export class PhonePhotoCoordinator {
|
|
|
120
144
|
private readonly activeRequests = new Map<string, ActiveRequest>()
|
|
121
145
|
/** Short BLE correlation id (4-char hex) → full cloud requestId. */
|
|
122
146
|
private readonly bleIdToCloud = new Map<string, string>()
|
|
147
|
+
private readonly activeWarmUps = new Map<
|
|
148
|
+
string,
|
|
149
|
+
{requestId: string; durationMs: number; expiryTimer?: ReturnType<typeof setTimeout>}
|
|
150
|
+
>()
|
|
151
|
+
|
|
152
|
+
/** Report-safe camera ownership snapshot for incident diagnostics. */
|
|
153
|
+
getDiagnosticSnapshot(): Record<string, unknown> {
|
|
154
|
+
return {
|
|
155
|
+
captureOwners: [...new Set([...this.activeRequests.values()].map((request) => request.packageName))].sort(),
|
|
156
|
+
warmUpOwners: [...this.activeWarmUps.keys()].sort(),
|
|
157
|
+
activeCaptureCount: this.activeRequests.size,
|
|
158
|
+
}
|
|
159
|
+
}
|
|
123
160
|
|
|
124
161
|
async takePhoto(packageName: string, opts: PhotoOpts): Promise<PhotoTaken> {
|
|
162
|
+
const transferMethod = parsePhotoTransferMethod(opts.transferMethod)
|
|
163
|
+
|
|
125
164
|
// Pre-check: if glasses aren't even connected, the BLE photo command
|
|
126
165
|
// would be sent into the void and we'd wait 30s for the cloud long-poll
|
|
127
166
|
// to time out. Fail fast with a typed error.
|
|
@@ -137,6 +176,10 @@ export class PhonePhotoCoordinator {
|
|
|
137
176
|
throw new PhotoError("GLASSES_NOT_CONNECTED", "Glasses are not connected", "command", "ble")
|
|
138
177
|
}
|
|
139
178
|
|
|
179
|
+
// Text-mode sensor resolution is owned by ASG constants; keep cloud metadata on a stable
|
|
180
|
+
// high-capacity tier and let the glasses ignore the public size when mode=text.
|
|
181
|
+
const captureSize = opts.size ?? "medium"
|
|
182
|
+
|
|
140
183
|
// 1) Presign via the cloud-v2 managed-photo service. Local miniapps use
|
|
141
184
|
// ONLY the cloud-v2 path: the runtime presigns upload+read URLs and the
|
|
142
185
|
// phone (as the device controller) delivers the bytes; the legacy
|
|
@@ -147,10 +190,16 @@ export class PhonePhotoCoordinator {
|
|
|
147
190
|
const flowStarted = performance.now()
|
|
148
191
|
try {
|
|
149
192
|
const presignStarted = performance.now()
|
|
150
|
-
const r = await cloudClientService.startManagedPhoto({
|
|
193
|
+
const r = await cloudClientService.startManagedPhoto({
|
|
194
|
+
size: opts.mode === "text" ? "max" : captureSize,
|
|
195
|
+
})
|
|
151
196
|
const presignMs = Math.round(performance.now() - presignStarted)
|
|
152
197
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
153
|
-
console.debug(
|
|
198
|
+
console.debug(
|
|
199
|
+
`[PhonePhotoCoordinator] presign ${presignMs}ms size=${opts.mode === "text" ? "max" : captureSize} mode=${
|
|
200
|
+
opts.mode ?? "photo"
|
|
201
|
+
}`,
|
|
202
|
+
)
|
|
154
203
|
}
|
|
155
204
|
requestId = r.requestId
|
|
156
205
|
uploadUrl = r.uploadUrl
|
|
@@ -204,21 +253,30 @@ export class PhonePhotoCoordinator {
|
|
|
204
253
|
|
|
205
254
|
// 3) Drive glasses over BLE. requestPhoto now resolves at terminal
|
|
206
255
|
// photo_response success, so run it beside the cloud poll instead of
|
|
207
|
-
// awaiting it before polling.
|
|
208
|
-
// (
|
|
256
|
+
// awaiting it before polling. Native defaults transferMethod to "auto"
|
|
257
|
+
// (Wi-Fi direct with BLE fallback) unless the miniapp forces BLE.
|
|
209
258
|
try {
|
|
210
259
|
void BluetoothSdk.requestPhoto({
|
|
211
260
|
requestId: bleRequestId,
|
|
212
261
|
appId: packageName,
|
|
213
|
-
size: normalizePhotoSize(
|
|
262
|
+
size: normalizePhotoSize(captureSize),
|
|
214
263
|
mode: opts.mode ?? "photo",
|
|
215
264
|
webhookUrl: uploadUrl,
|
|
216
265
|
authToken: null,
|
|
217
|
-
...(isLoopbackUpload ? {transferMethod: "ble" as const} : {}),
|
|
266
|
+
...(isLoopbackUpload ? {transferMethod: "ble" as const} : transferMethod ? {transferMethod} : {}),
|
|
218
267
|
compress: toNativeCompression(opts.compress),
|
|
219
268
|
save: opts.saveToGallery ?? false,
|
|
220
269
|
sound: opts.sound ?? true,
|
|
221
270
|
exposureTimeNs: opts.exposureTimeNs ?? null,
|
|
271
|
+
iso: opts.iso,
|
|
272
|
+
aeExposureDivisor: opts.aeExposureDivisor,
|
|
273
|
+
isoCap: opts.isoCap,
|
|
274
|
+
noiseReduction: opts.noiseReduction,
|
|
275
|
+
edgeEnhancement: opts.edgeEnhancement,
|
|
276
|
+
...(opts.zsl != null ? {zsl: opts.zsl} : {}),
|
|
277
|
+
...(opts.mfnr != null ? {mfnr: opts.mfnr} : {}),
|
|
278
|
+
ispDigitalGain: opts.ispDigitalGain,
|
|
279
|
+
ispAnalogGain: opts.ispAnalogGain,
|
|
222
280
|
}).catch((err) => {
|
|
223
281
|
const e = this.activeRequests.get(requestId)
|
|
224
282
|
if (!e) return
|
|
@@ -250,7 +308,9 @@ export class PhonePhotoCoordinator {
|
|
|
250
308
|
const result = await outcome
|
|
251
309
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
252
310
|
console.debug(
|
|
253
|
-
`[PhonePhotoCoordinator] takePhoto complete ${Math.round(
|
|
311
|
+
`[PhonePhotoCoordinator] takePhoto complete ${Math.round(
|
|
312
|
+
performance.now() - flowStarted,
|
|
313
|
+
)}ms requestId=${requestId}`,
|
|
254
314
|
)
|
|
255
315
|
}
|
|
256
316
|
return {
|
|
@@ -273,13 +333,20 @@ export class PhonePhotoCoordinator {
|
|
|
273
333
|
/**
|
|
274
334
|
* Pre-warm the glasses camera so the next takePhoto() is near-instant.
|
|
275
335
|
*
|
|
276
|
-
* Pure BLE — NO cloud presign, NO upload, NO long-poll. The
|
|
277
|
-
* requestId, sends the warm-up command, and resolves when the camera reports
|
|
336
|
+
* Pure BLE — NO cloud presign, NO upload, NO long-poll. The phone mints and owns
|
|
337
|
+
* the requestId, sends the warm-up command, and resolves when the camera reports
|
|
278
338
|
* ready (the native promise resolves on the ready status event).
|
|
279
339
|
*/
|
|
280
340
|
async warmUpCamera(
|
|
281
341
|
packageName: string,
|
|
282
|
-
opts: {
|
|
342
|
+
opts: {
|
|
343
|
+
size?: "low" | "medium" | "high" | "max"
|
|
344
|
+
mode?: "photo" | "text"
|
|
345
|
+
exposureTimeNs?: number
|
|
346
|
+
durationMs?: number
|
|
347
|
+
zsl?: boolean
|
|
348
|
+
mfnr?: boolean
|
|
349
|
+
},
|
|
283
350
|
): Promise<void> {
|
|
284
351
|
// Pre-check: if glasses aren't connected, the BLE warm-up command would be
|
|
285
352
|
// sent into the void. Fail fast with a typed error.
|
|
@@ -287,17 +354,53 @@ export class PhonePhotoCoordinator {
|
|
|
287
354
|
throw new PhotoError("GLASSES_NOT_CONNECTED", "Glasses are not connected", "command", "ble")
|
|
288
355
|
}
|
|
289
356
|
|
|
357
|
+
let lease: {requestId: string; durationMs: number; expiryTimer?: ReturnType<typeof setTimeout>} | undefined
|
|
290
358
|
try {
|
|
359
|
+
await this.stopWarmUpForApp(packageName)
|
|
360
|
+
const requestId = mintBleRequestId()
|
|
361
|
+
const requestedDuration =
|
|
362
|
+
typeof opts.durationMs === "number" && Number.isFinite(opts.durationMs) && opts.durationMs > 0
|
|
363
|
+
? Math.round(opts.durationMs)
|
|
364
|
+
: CAMERA_WARM_UP_DEFAULT_DURATION_MS
|
|
365
|
+
const durationMs = Math.min(requestedDuration, CAMERA_WARM_UP_MAX_DURATION_MS)
|
|
366
|
+
lease = {requestId, durationMs}
|
|
367
|
+
this.activeWarmUps.set(packageName, lease)
|
|
291
368
|
await BluetoothSdk.warmUpCamera({
|
|
369
|
+
requestId,
|
|
292
370
|
size: normalizePhotoSize(opts.size ?? "medium"),
|
|
371
|
+
mode: opts.mode ?? "photo",
|
|
293
372
|
exposureTimeNs: opts.exposureTimeNs ?? null,
|
|
294
|
-
durationMs
|
|
373
|
+
durationMs,
|
|
374
|
+
...(opts.zsl != null ? {zsl: opts.zsl} : {}),
|
|
375
|
+
...(opts.mfnr != null ? {mfnr: opts.mfnr} : {}),
|
|
295
376
|
})
|
|
377
|
+
if (this.activeWarmUps.get(packageName) === lease) {
|
|
378
|
+
lease.expiryTimer = setTimeout(() => {
|
|
379
|
+
if (this.activeWarmUps.get(packageName) === lease) {
|
|
380
|
+
this.activeWarmUps.delete(packageName)
|
|
381
|
+
}
|
|
382
|
+
}, durationMs)
|
|
383
|
+
}
|
|
296
384
|
} catch (err) {
|
|
385
|
+
if (lease && this.activeWarmUps.get(packageName) === lease) {
|
|
386
|
+
if (lease.expiryTimer) clearTimeout(lease.expiryTimer)
|
|
387
|
+
this.activeWarmUps.delete(packageName)
|
|
388
|
+
}
|
|
297
389
|
throw this.toPhotoError(err, "WARM_UP_FAILED", "command", "ble")
|
|
298
390
|
}
|
|
299
391
|
}
|
|
300
392
|
|
|
393
|
+
/** Release a miniapp's warm-up even if its original warmUpCamera promise is still opening. */
|
|
394
|
+
async stopWarmUpForApp(packageName: string): Promise<void> {
|
|
395
|
+
const active = this.activeWarmUps.get(packageName)
|
|
396
|
+
if (!active) return
|
|
397
|
+
await BluetoothSdk.stopCameraWarmUp(active.requestId)
|
|
398
|
+
if (this.activeWarmUps.get(packageName) === active) {
|
|
399
|
+
this.activeWarmUps.delete(packageName)
|
|
400
|
+
if (active.expiryTimer) clearTimeout(active.expiryTimer)
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
301
404
|
/** True iff this requestId (short BLE id or cloud id) is one we're currently waiting on. */
|
|
302
405
|
owns(requestId: string): boolean {
|
|
303
406
|
const cloudId = this.resolveCloudRequestId(requestId)
|
|
@@ -320,12 +423,7 @@ export class PhonePhotoCoordinator {
|
|
|
320
423
|
// cloud-v2 pending photo requests TTL out on their own; nothing to free.
|
|
321
424
|
}
|
|
322
425
|
|
|
323
|
-
private toPhotoError(
|
|
324
|
-
err: unknown,
|
|
325
|
-
fallbackCode: string,
|
|
326
|
-
stage?: PhotoStage,
|
|
327
|
-
transport?: PhotoTransport,
|
|
328
|
-
): PhotoError {
|
|
426
|
+
private toPhotoError(err: unknown, fallbackCode: string, stage?: PhotoStage, transport?: PhotoTransport): PhotoError {
|
|
329
427
|
if (err instanceof PhotoError) return err
|
|
330
428
|
const code = (err as {code?: string})?.code
|
|
331
429
|
const message = err instanceof Error ? err.message : String(err)
|