@mentra/engine 0.1.0-dev.0 → 3.1.0-beta.100
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 +73 -18
- package/build/bluetooth-sdk/debug.d.ts +2 -0
- package/build/bluetooth-sdk/debug.d.ts.map +1 -0
- package/build/bluetooth-sdk/debug.js +2 -0
- package/build/bluetooth-sdk/debug.js.map +1 -0
- package/build/bluetooth-sdk/index.d.ts +3 -0
- package/build/bluetooth-sdk/index.d.ts.map +1 -0
- package/build/bluetooth-sdk/index.js +3 -0
- package/build/bluetooth-sdk/index.js.map +1 -0
- package/build/bluetooth-sdk/ota-transport.d.ts +2 -0
- package/build/bluetooth-sdk/ota-transport.d.ts.map +1 -0
- package/build/bluetooth-sdk/ota-transport.js +2 -0
- package/build/bluetooth-sdk/ota-transport.js.map +1 -0
- package/build/bluetooth-sdk/photo-receiver.d.ts +3 -0
- package/build/bluetooth-sdk/photo-receiver.d.ts.map +1 -0
- package/build/bluetooth-sdk/photo-receiver.js +3 -0
- package/build/bluetooth-sdk/photo-receiver.js.map +1 -0
- package/build/bluetooth-sdk/react.d.ts +2 -0
- package/build/bluetooth-sdk/react.d.ts.map +1 -0
- package/build/bluetooth-sdk/react.js +2 -0
- package/build/bluetooth-sdk/react.js.map +1 -0
- package/build/bluetooth-sdk/types.d.ts +2 -0
- package/build/bluetooth-sdk/types.d.ts.map +1 -0
- package/build/bluetooth-sdk/types.js +2 -0
- package/build/bluetooth-sdk/types.js.map +1 -0
- package/build/engine.d.ts +29 -18
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +9 -4
- 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/display.d.ts +1 -1
- package/build/facades/display.d.ts.map +1 -1
- package/build/facades/display.js +1 -1
- package/build/facades/display.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 +4 -13
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +21 -6
- 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 +24 -21
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +31 -12
- package/build/facades/ota.js.map +1 -1
- package/build/facades/pairing.d.ts +12 -5
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +93 -17
- 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/facades/speech.d.ts +7 -6
- package/build/facades/speech.d.ts.map +1 -1
- package/build/facades/speech.js +1 -1
- package/build/facades/speech.js.map +1 -1
- package/build/generated/releaseMetadata.d.ts +12 -0
- package/build/generated/releaseMetadata.d.ts.map +1 -0
- package/build/generated/releaseMetadata.js +10 -0
- package/build/generated/releaseMetadata.js.map +1 -0
- package/build/index.d.ts +12 -10
- package/build/index.d.ts.map +1 -1
- package/build/index.js +7 -6
- package/build/index.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.d.ts +44 -0
- package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
- package/build/react/MentraLiveOtaFlow.js +430 -0
- package/build/react/MentraLiveOtaFlow.js.map +1 -0
- package/build/react/index.d.ts +3 -0
- package/build/react/index.d.ts.map +1 -0
- package/build/react/index.js +3 -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/react/useMentraLiveOta.d.ts +84 -0
- package/build/react/useMentraLiveOta.d.ts.map +1 -0
- package/build/react/useMentraLiveOta.js +627 -0
- package/build/react/useMentraLiveOta.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 +41 -57
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +208 -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 +4 -1
- package/build/services/BlobStore.d.ts.map +1 -1
- package/build/services/BlobStore.js +80 -19
- 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/DisplayProcessor.d.ts +3 -3
- package/build/services/DisplayProcessor.js +3 -3
- package/build/services/DisplayProcessor.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 +15 -1
- package/build/services/GlassesStatusProjection.d.ts.map +1 -1
- package/build/services/GlassesStatusProjection.js +18 -11
- 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 +147 -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 +17 -3
- package/build/services/LocalDisplayManager.d.ts.map +1 -1
- package/build/services/LocalDisplayManager.js +108 -23
- 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 +41 -0
- package/build/services/OtaAutoChain.d.ts.map +1 -0
- package/build/services/OtaAutoChain.js +91 -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 +120 -17
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +605 -136
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/OtaService.d.ts.map +1 -1
- package/build/services/OtaService.js +9 -2
- package/build/services/OtaService.js.map +1 -1
- package/build/services/OtaUpdateCheckService.d.ts +42 -4
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +158 -26
- 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 +80 -10
- 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/StreamLifecycleController.d.ts +3 -3
- package/build/services/StreamLifecycleController.js +3 -3
- package/build/services/StreamLifecycleController.js.map +1 -1
- 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 +145 -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.d.ts.map +1 -1
- package/build/services/glassesClockSync.js +7 -3
- 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 +23 -12
- 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 +20 -4
- package/build/services/otaInstallPolicy.d.ts.map +1 -1
- package/build/services/otaInstallPolicy.js +28 -3
- package/build/services/otaInstallPolicy.js.map +1 -1
- package/build/services/otaLegacyMapping.d.ts +1 -1
- package/build/services/otaLegacyMapping.d.ts.map +1 -1
- package/build/services/otaLegacyMapping.js.map +1 -1
- package/build/services/otaManifestPolicy.d.ts +14 -0
- package/build/services/otaManifestPolicy.d.ts.map +1 -0
- package/build/services/otaManifestPolicy.js +19 -0
- package/build/services/otaManifestPolicy.js.map +1 -0
- package/build/services/otaManifestUrl.d.ts +3 -0
- package/build/services/otaManifestUrl.d.ts.map +1 -0
- package/build/services/otaManifestUrl.js +38 -0
- package/build/services/otaManifestUrl.js.map +1 -0
- package/build/services/otaReleaseVersion.d.ts +10 -0
- package/build/services/otaReleaseVersion.d.ts.map +1 -0
- package/build/services/otaReleaseVersion.js +14 -0
- package/build/services/otaReleaseVersion.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/appVisibility.d.ts +3 -0
- package/build/stores/appVisibility.d.ts.map +1 -0
- package/build/stores/appVisibility.js +3 -0
- package/build/stores/appVisibility.js.map +1 -0
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +18 -1
- 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/core.d.ts +3 -3
- package/build/stores/core.d.ts.map +1 -1
- package/build/stores/core.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 +10 -4
- 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 +3 -1
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js +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/capabilities/even-realities-g1.d.ts.map +1 -1
- package/build/types/capabilities/even-realities-g1.js +2 -0
- package/build/types/capabilities/even-realities-g1.js.map +1 -1
- package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
- package/build/types/capabilities/even-realities-g2.js +2 -0
- package/build/types/capabilities/even-realities-g2.js.map +1 -1
- package/build/types/capabilities/mentra-display.d.ts.map +1 -1
- package/build/types/capabilities/mentra-display.js +2 -0
- package/build/types/capabilities/mentra-display.js.map +1 -1
- package/build/types/capabilities/mentra-live.d.ts.map +1 -1
- package/build/types/capabilities/mentra-live.js +2 -0
- package/build/types/capabilities/mentra-live.js.map +1 -1
- package/build/types/capabilities/nimo.d.ts +9 -0
- package/build/types/capabilities/nimo.d.ts.map +1 -0
- package/build/types/capabilities/nimo.js +57 -0
- package/build/types/capabilities/nimo.js.map +1 -0
- package/build/types/capabilities/none.d.ts.map +1 -1
- package/build/types/capabilities/none.js +2 -0
- package/build/types/capabilities/none.js.map +1 -1
- package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
- package/build/types/capabilities/simulated-glasses.js +2 -0
- package/build/types/capabilities/simulated-glasses.js.map +1 -1
- package/build/types/capabilities/vuzix-z100.d.ts.map +1 -1
- package/build/types/capabilities/vuzix-z100.js +2 -0
- package/build/types/capabilities/vuzix-z100.js.map +1 -1
- package/build/types/enums.d.ts +4 -26
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +3 -27
- package/build/types/enums.js.map +1 -1
- package/build/types/hardware.d.ts +6 -14
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +18 -4
- package/build/types/hardware.js.map +1 -1
- package/build/types/index.d.ts +3 -7
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js +3 -7
- package/build/types/index.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/display/composer/ColumnComposer.d.ts +1 -1
- package/build/utils/display/composer/ColumnComposer.js +1 -1
- package/build/utils/display/composer/ColumnComposer.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 +66 -31
- package/src/assets/silence.wav +0 -0
- package/src/bluetooth-sdk/debug.ts +1 -0
- package/src/bluetooth-sdk/index.ts +2 -0
- package/src/bluetooth-sdk/ota-transport.ts +1 -0
- package/src/bluetooth-sdk/photo-receiver.ts +2 -0
- package/src/bluetooth-sdk/react.ts +1 -0
- package/src/bluetooth-sdk/types.ts +1 -0
- package/src/engine.ts +9 -4
- package/src/facades/dev.ts +17 -12
- package/src/facades/display.ts +1 -1
- package/src/facades/gallery.ts +1 -1
- package/src/facades/glasses.ts +20 -7
- package/src/facades/glassesSettings.ts +5 -0
- package/src/facades/miniapps.ts +7 -0
- package/src/facades/ota.ts +41 -13
- package/src/facades/pairing.ts +103 -23
- package/src/facades/permissions.ts +14 -0
- package/src/facades/phoneNotifications.ts +4 -13
- package/src/facades/speech.ts +21 -7
- package/src/generated/releaseMetadata.ts +20 -0
- package/src/index.ts +42 -13
- package/src/react/MentraLiveOtaFlow.tsx +754 -0
- package/src/react/index.ts +21 -0
- package/src/react/useEngineSnapshot.ts +16 -0
- package/src/react/useMentraLiveOta.ts +793 -0
- package/src/runtime/bootstrap.ts +33 -1
- package/src/runtime/scanQrSeam.ts +20 -0
- package/src/services/AppRegistry.ts +240 -149
- package/src/services/AudioCloudUplink.ts +23 -1
- package/src/services/AudioPlaybackService.ts +287 -38
- package/src/services/BlobStore.ts +79 -19
- package/src/services/CloudAudioSubscriptionSync.ts +13 -1
- package/src/services/CloudClientService.ts +96 -1
- package/src/services/DeviceEventRouter.ts +5 -5
- package/src/services/DisplayProcessor.ts +3 -3
- package/src/services/ForegroundLocationPermission.ts +24 -0
- package/src/services/GlassesSettingsSync.ts +9 -3
- package/src/services/GlassesStatusProjection.ts +20 -11
- package/src/services/HotspotOtaTransport.ts +185 -0
- package/src/services/HotspotShutdown.ts +41 -0
- package/src/services/LocalDisplayManager.ts +114 -24
- 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 +130 -0
- package/src/services/OtaErrorMapping.ts +80 -0
- package/src/services/OtaInstallCoordinator.ts +680 -151
- package/src/services/OtaService.ts +12 -7
- package/src/services/OtaUpdateCheckService.ts +205 -27
- 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 +117 -19
- 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/StreamLifecycleController.ts +3 -3
- 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 +170 -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 +7 -3
- package/src/services/manifestActions.ts +30 -0
- package/src/services/otaDisplayState.ts +58 -17
- package/src/services/otaInstallPolicy.ts +34 -4
- package/src/services/otaLegacyMapping.ts +1 -1
- package/src/services/otaManifestPolicy.ts +42 -0
- package/src/services/otaManifestUrl.ts +44 -0
- package/src/services/otaReleaseVersion.ts +22 -0
- package/src/services/slimStreamStatus.ts +16 -5
- package/src/stores/appVisibility.ts +3 -0
- package/src/stores/apps.ts +19 -1
- package/src/stores/bluetoothSettingKeys.ts +2 -0
- package/src/stores/core.ts +4 -4
- package/src/stores/gallerySync.ts +4 -0
- package/src/stores/glasses.ts +16 -6
- package/src/stores/settings.ts +179 -18
- package/src/types/applet.ts +3 -1
- package/src/types/asg.ts +7 -0
- package/src/types/capabilities/even-realities-g1.ts +3 -0
- package/src/types/capabilities/even-realities-g2.ts +3 -0
- package/src/types/capabilities/mentra-display.ts +3 -0
- package/src/types/capabilities/mentra-live.ts +3 -0
- package/src/types/capabilities/nimo.ts +59 -0
- package/src/types/capabilities/none.ts +3 -0
- package/src/types/capabilities/simulated-glasses.ts +3 -0
- package/src/types/capabilities/vuzix-z100.ts +3 -0
- package/src/types/enums.ts +4 -28
- package/src/types/hardware.ts +23 -14
- package/src/types/index.ts +3 -6
- package/src/utils/configuredDevHost.ts +17 -0
- package/src/utils/devMiniappLaunch.ts +151 -23
- package/src/utils/diagnosticContext.ts +17 -17
- package/src/utils/display/composer/ColumnComposer.ts +1 -1
- 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/devtools.d.ts +0 -11
- package/build/devtools.d.ts.map +0 -1
- package/build/devtools.js +0 -13
- package/build/devtools.js.map +0 -1
- package/build/internal.d.ts +0 -66
- package/build/internal.d.ts.map +0 -1
- package/build/internal.js +0 -89
- package/build/internal.js.map +0 -1
- package/build/services/asgOtaVersionUrl.d.ts +0 -2
- package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
- package/build/services/asgOtaVersionUrl.js +0 -36
- package/build/services/asgOtaVersionUrl.js.map +0 -1
- package/src/devtools.ts +0 -13
- package/src/internal.ts +0 -158
- package/src/services/asgOtaVersionUrl.ts +0 -41
|
@@ -40,8 +40,15 @@ const LOG_TAG = "LocalMiniappRuntime"
|
|
|
40
40
|
/** Per-app blob quota: 1 GB. */
|
|
41
41
|
export const BLOB_QUOTA_BYTES = 1024 * 1024 * 1024
|
|
42
42
|
const ROOT_DIR_NAME = "mentra_blobs"
|
|
43
|
-
/** Cache dir root holding short-lived, properly-named copies handed to the OS share sheet (one
|
|
43
|
+
/** Cache dir root holding short-lived, properly-named copies handed to the OS share sheet (one subdir per stored blob). */
|
|
44
44
|
const SHARE_DIR_NAME = "mentra_blob_share"
|
|
45
|
+
/**
|
|
46
|
+
* Keep prepared share handoffs alive long enough for recipient apps to read
|
|
47
|
+
* them asynchronously (for example, an email composer attaching the file).
|
|
48
|
+
* Stale copies are collected before the next share; the OS may evict cache
|
|
49
|
+
* files sooner under storage pressure.
|
|
50
|
+
*/
|
|
51
|
+
const SHARE_CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1000
|
|
45
52
|
const META_KEY_ROOT = "mentraos_blobmeta_"
|
|
46
53
|
/** Cap md5 computation so we don't block the JS thread hashing a huge file. */
|
|
47
54
|
const MD5_MAX_BYTES = 50 * 1024 * 1024
|
|
@@ -97,22 +104,33 @@ interface ActiveReader {
|
|
|
97
104
|
export class BlobStore {
|
|
98
105
|
private readonly uploads = new Map<string, ActiveUpload>() // key: `${pkg} ${key}`
|
|
99
106
|
private readonly readers = new Map<string, ActiveReader>() // key: host handle id
|
|
100
|
-
/**
|
|
107
|
+
/** user + package → committed usage bytes, cached; invalidated on commit/delete/clear. */
|
|
101
108
|
private readonly usageCache = new Map<string, number>()
|
|
102
109
|
|
|
103
110
|
constructor(private readonly hooks: BlobStoreHooks) {}
|
|
104
111
|
|
|
105
112
|
// ---- path / meta helpers -------------------------------------------------
|
|
106
113
|
|
|
114
|
+
private currentIdentity(packageName: string): {userId: string; scope: string} {
|
|
115
|
+
const userId = this.hooks.getUserId().trim()
|
|
116
|
+
if (!userId) throw new Error("Mentra user identity is unavailable")
|
|
117
|
+
const scope = `${userId}\0${packageName}`
|
|
118
|
+
return {userId, scope}
|
|
119
|
+
}
|
|
120
|
+
|
|
107
121
|
private dirFor(packageName: string): Directory {
|
|
108
|
-
const
|
|
109
|
-
|
|
122
|
+
const dir = new Directory(
|
|
123
|
+
Paths.document,
|
|
124
|
+
ROOT_DIR_NAME,
|
|
125
|
+
sanitizeSegment(this.currentIdentity(packageName).userId),
|
|
126
|
+
sanitizeSegment(packageName),
|
|
127
|
+
)
|
|
110
128
|
if (!dir.exists) dir.create({intermediates: true})
|
|
111
129
|
return dir
|
|
112
130
|
}
|
|
113
131
|
|
|
114
132
|
private metaPrefix(packageName: string): string {
|
|
115
|
-
return `${META_KEY_ROOT}${sanitizeSegment(this.
|
|
133
|
+
return `${META_KEY_ROOT}${sanitizeSegment(this.currentIdentity(packageName).userId)}_${packageName}_`
|
|
116
134
|
}
|
|
117
135
|
|
|
118
136
|
private metaKey(packageName: string, key: string): string {
|
|
@@ -163,17 +181,19 @@ export class BlobStore {
|
|
|
163
181
|
}
|
|
164
182
|
|
|
165
183
|
private committedUsage(packageName: string): number {
|
|
166
|
-
const
|
|
184
|
+
const {scope} = this.currentIdentity(packageName)
|
|
185
|
+
const cached = this.usageCache.get(scope)
|
|
167
186
|
if (cached !== undefined) return cached
|
|
168
187
|
let total = 0
|
|
169
188
|
for (const m of this.allMeta(packageName)) total += m.bytes || 0
|
|
170
|
-
this.usageCache.set(
|
|
189
|
+
this.usageCache.set(scope, total)
|
|
171
190
|
return total
|
|
172
191
|
}
|
|
173
192
|
|
|
174
193
|
private bumpUsage(packageName: string, delta: number): void {
|
|
175
|
-
const
|
|
176
|
-
|
|
194
|
+
const {scope} = this.currentIdentity(packageName)
|
|
195
|
+
const cur = this.usageCache.get(scope)
|
|
196
|
+
if (cur !== undefined) this.usageCache.set(scope, Math.max(0, cur + delta))
|
|
177
197
|
}
|
|
178
198
|
|
|
179
199
|
private safeMd5(file: File, bytes: number): string | undefined {
|
|
@@ -509,7 +529,7 @@ export class BlobStore {
|
|
|
509
529
|
} catch {
|
|
510
530
|
/* best-effort */
|
|
511
531
|
}
|
|
512
|
-
this.usageCache.set(packageName, 0)
|
|
532
|
+
this.usageCache.set(this.currentIdentity(packageName).scope, 0)
|
|
513
533
|
this.hooks.sendResult(packageName, requestId, true)
|
|
514
534
|
} catch (err) {
|
|
515
535
|
this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, err)
|
|
@@ -585,6 +605,32 @@ export class BlobStore {
|
|
|
585
605
|
|
|
586
606
|
// ---- share ---------------------------------------------------------------
|
|
587
607
|
|
|
608
|
+
/** Best-effort GC for prepared share handoffs retained in the OS cache. */
|
|
609
|
+
private cleanupShareCache(now = Date.now()): void {
|
|
610
|
+
try {
|
|
611
|
+
const root = new Directory(Paths.cache, SHARE_DIR_NAME)
|
|
612
|
+
if (!root.exists) return
|
|
613
|
+
const cutoff = now - SHARE_CACHE_MAX_AGE_MS
|
|
614
|
+
for (const entry of root.list()) {
|
|
615
|
+
if (!(entry instanceof Directory)) continue
|
|
616
|
+
try {
|
|
617
|
+
const info = entry.info()
|
|
618
|
+
// modificationTime is available on both platforms; creationTime can
|
|
619
|
+
// be absent on Android versions before API 26. The directory id
|
|
620
|
+
// begins with Date.now().toString(36), which is a final fallback.
|
|
621
|
+
const encoded = entry.name.split("-", 1)[0]
|
|
622
|
+
const encodedTime = /^[0-9a-z]+$/.test(encoded) ? Number.parseInt(encoded, 36) : Number.NaN
|
|
623
|
+
const timestamp = info.modificationTime ?? info.creationTime ?? encodedTime
|
|
624
|
+
if (Number.isFinite(timestamp) && timestamp < cutoff) entry.delete()
|
|
625
|
+
} catch {
|
|
626
|
+
// Keep scanning if one cache entry disappears or is unreadable.
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
} catch {
|
|
630
|
+
// Cache cleanup must never prevent a share.
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
588
634
|
async handleShare(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {
|
|
589
635
|
const key = payload.key as string
|
|
590
636
|
const meta = this.readMeta(packageName, key)
|
|
@@ -602,23 +648,33 @@ export class BlobStore {
|
|
|
602
648
|
// applies to base64/data payloads, not file:// URLs), so sharing `file.uri`
|
|
603
649
|
// directly would hand the recipient a machine-named file. Copy to a temp
|
|
604
650
|
// file that carries the real display name + extension, share that, then
|
|
605
|
-
// clean it up.
|
|
651
|
+
// clean it up after the recipient has had time to consume it.
|
|
606
652
|
const shareName = shareFileName(meta)
|
|
607
|
-
//
|
|
608
|
-
//
|
|
609
|
-
//
|
|
610
|
-
//
|
|
653
|
+
// Key the cache directory by the immutable stored filename. Repeated or
|
|
654
|
+
// concurrent shares of the same blob can safely reference the same bytes,
|
|
655
|
+
// avoiding an extra full-sized cache copy for every share. Different blobs
|
|
656
|
+
// still get isolated directories even when they use the same display name.
|
|
657
|
+
// The file keeps `shareName` as its basename so the OS share sheet shows the
|
|
658
|
+
// right name + extension.
|
|
611
659
|
let tempDir: Directory | null = null
|
|
660
|
+
let cacheReady = false
|
|
612
661
|
try {
|
|
613
|
-
|
|
614
|
-
tempDir.
|
|
662
|
+
this.cleanupShareCache()
|
|
663
|
+
tempDir = new Directory(Paths.cache, SHARE_DIR_NAME, sanitizeSegment(meta.fileName))
|
|
664
|
+
if (!tempDir.exists) tempDir.create({intermediates: true})
|
|
615
665
|
const temp = new File(tempDir, shareName)
|
|
616
|
-
|
|
666
|
+
if (!temp.exists || temp.size !== meta.bytes) {
|
|
667
|
+
if (temp.exists) temp.delete()
|
|
668
|
+
file.copy(temp)
|
|
669
|
+
}
|
|
670
|
+
cacheReady = true
|
|
617
671
|
await Share.open({
|
|
618
672
|
url: temp.uri,
|
|
619
673
|
type: meta.mimeType || OCTET,
|
|
620
674
|
filename: shareName,
|
|
621
675
|
})
|
|
676
|
+
// Share.open resolves once the OS accepts the handoff. Recipient apps may
|
|
677
|
+
// still read the URI asynchronously, so retain this cache copy for GC.
|
|
622
678
|
this.hooks.sendResult(packageName, requestId, true, {success: true})
|
|
623
679
|
} catch (error: any) {
|
|
624
680
|
if (error?.message?.includes("User did not share")) {
|
|
@@ -628,7 +684,11 @@ export class BlobStore {
|
|
|
628
684
|
this.hooks.sendResult(packageName, requestId, true, {success: false})
|
|
629
685
|
}
|
|
630
686
|
} finally {
|
|
631
|
-
if
|
|
687
|
+
// Once a reusable cache entry is ready, retain it even if this particular
|
|
688
|
+
// sheet is cancelled or fails: another concurrent/recent share may still
|
|
689
|
+
// be reading the same file. Only remove an entry whose preparation did
|
|
690
|
+
// not finish; ready entries are collected after the retention window.
|
|
691
|
+
if (tempDir && !cacheReady) {
|
|
632
692
|
try {
|
|
633
693
|
if (tempDir.exists) tempDir.delete()
|
|
634
694
|
} catch {
|
|
@@ -19,7 +19,19 @@ export class CloudAudioSubscriptionSync {
|
|
|
19
19
|
private pendingKey = ""
|
|
20
20
|
|
|
21
21
|
public begin(nextKey: string): boolean {
|
|
22
|
-
|
|
22
|
+
// Exact duplicate of the write already in flight — nothing to do.
|
|
23
|
+
if (nextKey === this.pendingKey) {
|
|
24
|
+
return false
|
|
25
|
+
}
|
|
26
|
+
// Matches the last successfully applied set, but ONLY skip when nothing
|
|
27
|
+
// else is in flight. If a different write is pending (e.g. desired went
|
|
28
|
+
// fr-FR -> [] -> fr-FR while the [] write is still on the wire),
|
|
29
|
+
// lastAppliedKey is stale: it names what was applied BEFORE the in-flight
|
|
30
|
+
// write lands. Skipping here would drop the re-subscribe and strand the
|
|
31
|
+
// cloud on the intermediate (empty) set — captions silently die on any
|
|
32
|
+
// rapid A -> B -> A subscription churn. The cloud's own version counter
|
|
33
|
+
// resolves ordering between the concurrent writes, so sending both is safe.
|
|
34
|
+
if (nextKey === this.lastAppliedKey && this.pendingKey === "") {
|
|
23
35
|
return false
|
|
24
36
|
}
|
|
25
37
|
this.pendingKey = nextKey
|
|
@@ -13,21 +13,26 @@
|
|
|
13
13
|
* The local-miniapp path drives the cloud's transcription/translation through
|
|
14
14
|
* this service.
|
|
15
15
|
*/
|
|
16
|
-
import {CloudClient, setNativeUdp, setSecureStorage} from "@mentra/cloud-client/react-native"
|
|
16
|
+
import {CloudClient, setNativeHttp, setNativeUdp, setSecureStorage} from "@mentra/cloud-client/react-native"
|
|
17
17
|
import type {PreinstalledMiniappRegistry, RuntimeSnapshot} from "@mentra/cloud-client/react-native"
|
|
18
18
|
import type {SubjectTokenType} from "@mentra/cloud-client"
|
|
19
|
+
import {Platform} from "react-native"
|
|
19
20
|
import type {AudioSubscription, TranscriptionData, TranslationData} from "@mentra/cloud-protocol"
|
|
20
21
|
|
|
21
22
|
import BluetoothSdk from "@mentra/bluetooth-sdk/internal"
|
|
23
|
+
import CrustModule from "@mentra/crust"
|
|
22
24
|
import {getAuth, getConfigValues} from "../runtime/bootstrap"
|
|
23
25
|
import {useSettingsStore, SETTINGS} from "../stores/settings"
|
|
24
26
|
import {type CloudClientStatusSnapshot, type MiniappAuthToken} from "../runtime/config"
|
|
25
27
|
import {createCloudUdpSocket} from "../utils/cloudClient/RnUdpAdapter"
|
|
26
28
|
import {cloudSecureStore} from "../utils/cloudClient/cloudSecureStore"
|
|
29
|
+
import {storage as mmkvStorage} from "../utils/storage"
|
|
27
30
|
import {useCloudClientStatusStore} from "../stores/cloudClientStatus"
|
|
28
31
|
import {islandNotifications} from "./NotificationsEmitter"
|
|
29
32
|
import {BgTimer} from "../utils/timers"
|
|
30
33
|
import {logCloudV2TranscriptMetric} from "./CloudTranscriptE2EMetrics"
|
|
34
|
+
import {LocalMiniappUserIdentity} from "./LocalMiniappUserIdentity"
|
|
35
|
+
import {nativeHttpResponseBody} from "./NativeHttpResponse"
|
|
31
36
|
|
|
32
37
|
const LOG_TAG = "cloudClient"
|
|
33
38
|
type CloudCore = NonNullable<CloudClient["core"]>
|
|
@@ -37,6 +42,7 @@ type CloudCore = NonNullable<CloudClient["core"]>
|
|
|
37
42
|
// been continuously NOT connected for this long. A quick reconnect cancels it; brief
|
|
38
43
|
// flaps that recover don't fire. Raised as engine.notifications(connection_failed_persistent).
|
|
39
44
|
const CLOUD_PERSISTENT_FAILURE_MS = 60_000
|
|
45
|
+
const LOCAL_MINIAPP_USER_ID_KEY = "mentra.localMiniapp.userId"
|
|
40
46
|
|
|
41
47
|
/** Cancel the pending persistent-failure alarm + re-arm for the next outage. */
|
|
42
48
|
function clearPersistentFailureAlarm(): void {
|
|
@@ -72,6 +78,21 @@ let localDevRuntimeToken: {runtimeUrl: string; token: string; expiresAtMs: numbe
|
|
|
72
78
|
let lc3FrameSizeUnsubscribe: (() => void) | null = null
|
|
73
79
|
let coreTokenSyncPromise: Promise<string> | null = null
|
|
74
80
|
|
|
81
|
+
const localMiniappUserIdentity = new LocalMiniappUserIdentity({
|
|
82
|
+
get(): string | null {
|
|
83
|
+
const result = mmkvStorage.load<string>(LOCAL_MINIAPP_USER_ID_KEY)
|
|
84
|
+
return result.is_ok() ? result.value : null
|
|
85
|
+
},
|
|
86
|
+
set(userId: string): void {
|
|
87
|
+
const result = mmkvStorage.save(LOCAL_MINIAPP_USER_ID_KEY, userId)
|
|
88
|
+
if (result.is_error()) throw result.error
|
|
89
|
+
},
|
|
90
|
+
remove(): void {
|
|
91
|
+
const result = mmkvStorage.remove(LOCAL_MINIAPP_USER_ID_KEY)
|
|
92
|
+
if (result.is_error()) throw result.error
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
|
|
75
96
|
const transcriptListeners = new Set<(d: TranscriptionData) => void>()
|
|
76
97
|
const translationListeners = new Set<(d: TranslationData) => void>()
|
|
77
98
|
const statusListeners = new Set<(snapshot: CloudClientStatusSnapshot) => void>()
|
|
@@ -111,6 +132,7 @@ async function syncCoreAccessTokenToBluetoothInternal(): Promise<string> {
|
|
|
111
132
|
if (c !== client) {
|
|
112
133
|
throw new Error("cloud client changed while syncing core token")
|
|
113
134
|
}
|
|
135
|
+
localMiniappUserIdentity.remember(c.auth.identity.mentraUserId)
|
|
114
136
|
const result = await useSettingsStore.getState().setSetting(SETTINGS.core_token.key, token, false)
|
|
115
137
|
if (result.is_error()) {
|
|
116
138
|
throw result.error
|
|
@@ -261,6 +283,13 @@ function ensureAuthWatch(): void {
|
|
|
261
283
|
let reconnectPending = false
|
|
262
284
|
try {
|
|
263
285
|
const sub = auth.onStateChange((event, session) => {
|
|
286
|
+
if (event === "SIGNED_OUT") {
|
|
287
|
+
localMiniappUserIdentity.forget()
|
|
288
|
+
return
|
|
289
|
+
}
|
|
290
|
+
// A new sign-in may belong to a different account. Force the next
|
|
291
|
+
// storage request to resolve and persist that account's Core identity.
|
|
292
|
+
if (event === "SIGNED_IN") localMiniappUserIdentity.forget()
|
|
264
293
|
if (!session?.token) return
|
|
265
294
|
if (connected || reconnectPending) return
|
|
266
295
|
|
|
@@ -322,6 +351,24 @@ function ensureTransports(): void {
|
|
|
322
351
|
transportsReady = true
|
|
323
352
|
setNativeUdp(() => createCloudUdpSocket())
|
|
324
353
|
setSecureStorage(cloudSecureStore)
|
|
354
|
+
if (Platform.OS !== "android") return
|
|
355
|
+
setNativeHttp(async (input, init) => {
|
|
356
|
+
if (typeof input !== "string" || (init?.body != null && typeof init.body !== "string")) {
|
|
357
|
+
return globalThis.fetch(input, init)
|
|
358
|
+
}
|
|
359
|
+
const headers = Object.fromEntries(new Headers(init?.headers).entries())
|
|
360
|
+
const result = await CrustModule.nativeHttpRequest(
|
|
361
|
+
init?.method ?? "GET",
|
|
362
|
+
input,
|
|
363
|
+
headers,
|
|
364
|
+
(init?.body as string | undefined) ?? null,
|
|
365
|
+
)
|
|
366
|
+
return new Response(nativeHttpResponseBody(result.status, result.body), {
|
|
367
|
+
status: result.status,
|
|
368
|
+
statusText: result.statusText,
|
|
369
|
+
headers: result.headers,
|
|
370
|
+
})
|
|
371
|
+
})
|
|
325
372
|
}
|
|
326
373
|
|
|
327
374
|
function clearRuntimeEventSubscriptions(): void {
|
|
@@ -375,6 +422,12 @@ function construct(): void {
|
|
|
375
422
|
// LC3 at 16 kHz with the frame size the encoder emits.
|
|
376
423
|
audio: {codec: "lc3", sampleRate: 16000, frameSizeBytes: frameSizeBytes()},
|
|
377
424
|
auth,
|
|
425
|
+
timers: {
|
|
426
|
+
setTimeout: (callback, delayMs) => BgTimer.setTimeout(callback, delayMs),
|
|
427
|
+
clearTimeout: (handle) => BgTimer.clearTimeout(handle as number),
|
|
428
|
+
setInterval: (callback, intervalMs) => BgTimer.setInterval(callback, intervalMs),
|
|
429
|
+
clearInterval: (handle) => BgTimer.clearInterval(handle as number),
|
|
430
|
+
},
|
|
378
431
|
logger: cloudLogger,
|
|
379
432
|
})
|
|
380
433
|
|
|
@@ -399,6 +452,7 @@ function construct(): void {
|
|
|
399
452
|
if (c !== client) return
|
|
400
453
|
connected = true
|
|
401
454
|
console.log(`${LOG_TAG}: runtime connected`)
|
|
455
|
+
console.log(`${LOG_TAG}: debug: ws-session-debug connected`)
|
|
402
456
|
// Cloud is up — cancel any pending persistent-failure alarm and re-arm for the
|
|
403
457
|
// next outage.
|
|
404
458
|
clearPersistentFailureAlarm()
|
|
@@ -415,6 +469,9 @@ function construct(): void {
|
|
|
415
469
|
if (c !== client) return
|
|
416
470
|
connected = false
|
|
417
471
|
console.log(`${LOG_TAG}: runtime disconnected (${info.reason})`)
|
|
472
|
+
console.log(
|
|
473
|
+
`${LOG_TAG}: debug: ws-session-debug disconnected reason=${info.reason} willStayDown=${/superseded by newer session/i.test(info.reason)}`,
|
|
474
|
+
)
|
|
418
475
|
// Arm the persistent-failure alarm once; if we're still down when it fires, raise
|
|
419
476
|
// the notification. A reconnect within the window cancels it (onConnected above).
|
|
420
477
|
if (!persistentFailureTimer && !persistentFailureNotified) {
|
|
@@ -497,6 +554,34 @@ export const cloudClientService = {
|
|
|
497
554
|
return c.core.miniapps.getRegistry()
|
|
498
555
|
},
|
|
499
556
|
|
|
557
|
+
/**
|
|
558
|
+
* Resolve the stable Core-owned Mentra user id.
|
|
559
|
+
*
|
|
560
|
+
* Storage must use this identity rather than the short-lived Core access
|
|
561
|
+
* token. A previously verified id is restored from MMKV so local miniapps
|
|
562
|
+
* remain available after an offline process restart. On first sign-in,
|
|
563
|
+
* callers join the auth module's single-flight exchange/refresh instead of
|
|
564
|
+
* falling back to an anonymous namespace.
|
|
565
|
+
*/
|
|
566
|
+
async resolveMentraUserId(): Promise<string> {
|
|
567
|
+
return localMiniappUserIdentity.resolve(async () => {
|
|
568
|
+
if (!client) this.init()
|
|
569
|
+
const c = client
|
|
570
|
+
if (!c) throw new Error("cloud client not initialized")
|
|
571
|
+
|
|
572
|
+
await c.auth.getCoreToken()
|
|
573
|
+
if (c !== client) throw new Error("cloud client changed while resolving user identity")
|
|
574
|
+
return c.auth.identity.mentraUserId
|
|
575
|
+
})
|
|
576
|
+
},
|
|
577
|
+
|
|
578
|
+
/** Read the stable Mentra user id after async identity resolution. */
|
|
579
|
+
getMentraUserId(): string {
|
|
580
|
+
const userId = localMiniappUserIdentity.get()
|
|
581
|
+
if (!userId) throw new Error("Mentra user identity is unavailable")
|
|
582
|
+
return userId
|
|
583
|
+
},
|
|
584
|
+
|
|
500
585
|
async getMiniappAuthToken(
|
|
501
586
|
packageName: string,
|
|
502
587
|
opts?: {minTtlMs?: number; devAttestation?: string},
|
|
@@ -528,6 +613,11 @@ export const cloudClientService = {
|
|
|
528
613
|
clearPersistentFailureAlarm()
|
|
529
614
|
const wasConnected = connected
|
|
530
615
|
client = null
|
|
616
|
+
// stop() is part of the logout lifecycle and runs before the host emits
|
|
617
|
+
// SIGNED_OUT. Remove the persisted namespace owner here so a later account
|
|
618
|
+
// can never inherit it. A force-stop/process kill does not call stop(), so
|
|
619
|
+
// the cached id still survives the offline cold-start case.
|
|
620
|
+
localMiniappUserIdentity.forget()
|
|
531
621
|
localDevRuntimeToken = null
|
|
532
622
|
connected = false
|
|
533
623
|
resetRuntimeStatus()
|
|
@@ -660,6 +750,11 @@ export const cloudClientService = {
|
|
|
660
750
|
return getCoreClient().reports.complete(...args)
|
|
661
751
|
},
|
|
662
752
|
},
|
|
753
|
+
supportProfile: {
|
|
754
|
+
update(...args: Parameters<CloudCore["supportProfile"]["update"]>) {
|
|
755
|
+
return getCoreClient().supportProfile.update(...args)
|
|
756
|
+
},
|
|
757
|
+
},
|
|
663
758
|
},
|
|
664
759
|
|
|
665
760
|
hasAudioSubscriptions(): boolean {
|
|
@@ -201,17 +201,17 @@ export function startDeviceEventRouter(): void {
|
|
|
201
201
|
localMiniappRuntime.forwardEvent("head_up", {position: event.up ? "up" : "down", timestamp: Date.now()})
|
|
202
202
|
}),
|
|
203
203
|
)
|
|
204
|
-
// On-device STT transcripts → local miniapps
|
|
205
|
-
// active
|
|
206
|
-
//
|
|
207
|
-
//
|
|
204
|
+
// On-device STT transcripts → local miniapps only while the local engine is
|
|
205
|
+
// active (cloud fallback or an explicit forceLocal subscription). The runtime
|
|
206
|
+
// filters mixed local/cloud delivery per miniapp to avoid double-delivery.
|
|
207
|
+
// forwardEvent is subscriber-gated — a no-op when no miniapp listens.
|
|
208
208
|
// (Was MantleManager.handle_local_transcription; its offline-captions display branch
|
|
209
209
|
// went away with the pseudo captions renderer.)
|
|
210
210
|
subs.push(
|
|
211
211
|
BluetoothSdk.addListener("local_transcription", (event) => {
|
|
212
212
|
if (!localSttFallbackCoordinator.isActive()) return
|
|
213
213
|
const lang = event.transcribeLanguage ?? localSttFallbackCoordinator.getActiveLanguage() ?? "en-US"
|
|
214
|
-
localMiniappRuntime.forwardEvent(`transcription:${lang}`, event)
|
|
214
|
+
localMiniappRuntime.forwardEvent(`transcription:${lang}`, event, "local")
|
|
215
215
|
}),
|
|
216
216
|
)
|
|
217
217
|
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* DisplayProcessor
|
|
3
3
|
*
|
|
4
4
|
* Processes display events with pixel-accurate text wrapping using the same
|
|
5
|
-
* display
|
|
6
|
-
*
|
|
5
|
+
* Engine display utilities. This ensures the mobile preview matches exactly
|
|
6
|
+
* what is shown on the glasses.
|
|
7
7
|
*
|
|
8
8
|
* Key responsibilities:
|
|
9
9
|
* 1. Intercept display events before sending to native SGC
|
|
10
10
|
* 2. Wrap text using the correct device profile (G1, etc.)
|
|
11
11
|
* 3. Ensure GlassesDisplayMirror shows exactly what glasses will show
|
|
12
12
|
*
|
|
13
|
-
* @see
|
|
13
|
+
* @see notes/miniapp-display-api-redesign.md for the current display design
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ForegroundLocationPermissionResponse {
|
|
2
|
+
status: string
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface ForegroundLocationPermissionClient {
|
|
6
|
+
getForegroundPermissionsAsync(): Promise<ForegroundLocationPermissionResponse>
|
|
7
|
+
requestForegroundPermissionsAsync(): Promise<ForegroundLocationPermissionResponse>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resolve foreground location permission without invoking an Activity-bound
|
|
12
|
+
* Android permission request while the app is backgrounded.
|
|
13
|
+
*/
|
|
14
|
+
export async function resolveForegroundLocationPermission(
|
|
15
|
+
client: ForegroundLocationPermissionClient,
|
|
16
|
+
getAppState: () => string,
|
|
17
|
+
): Promise<ForegroundLocationPermissionResponse> {
|
|
18
|
+
const current = await client.getForegroundPermissionsAsync()
|
|
19
|
+
if (current.status === "granted" || getAppState() !== "active") {
|
|
20
|
+
return current
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return client.requestForegroundPermissionsAsync()
|
|
24
|
+
}
|
|
@@ -19,6 +19,7 @@ import {useSettingsStore, PAIRING_IDENTITY_KEYS} from "../stores/settings"
|
|
|
19
19
|
import {useGlassesStore} from "../stores/glasses"
|
|
20
20
|
import {createDebouncedPatchFlusher} from "../utils/debouncedPatch"
|
|
21
21
|
import {isGlassesConnected} from "./GlassesReadiness"
|
|
22
|
+
import micStateCoordinator from "./MicStateCoordinator"
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Change-pushes are debounced (300ms) and merged so a burst of setSetting
|
|
@@ -28,7 +29,10 @@ import {isGlassesConnected} from "./GlassesReadiness"
|
|
|
28
29
|
const flushBluetoothSettingsPatch = createDebouncedPatchFlusher<Record<string, unknown>>((patch) => {
|
|
29
30
|
// Settings can change while the glasses are disconnected — a native
|
|
30
31
|
// rejection must not surface as an unhandled promise rejection.
|
|
31
|
-
|
|
32
|
+
// Apply mic overrides at flush time, not enqueue time: raw PCM can stop
|
|
33
|
+
// during the debounce window and a captured VAD=false would then be stale.
|
|
34
|
+
const runtimePatch = micStateCoordinator.applyRuntimeOverrides(patch)
|
|
35
|
+
void Promise.resolve(BluetoothSdk.updateBluetoothSettings(runtimePatch)).catch((error) => {
|
|
32
36
|
console.warn("GlassesSettingsSync: updateBluetoothSettings failed:", error)
|
|
33
37
|
})
|
|
34
38
|
}, 300)
|
|
@@ -79,7 +83,8 @@ export async function pushAllBluetoothSettings(): Promise<void> {
|
|
|
79
83
|
// Returns the native write promise so callers can await the seed before the
|
|
80
84
|
// connect handshake replays settings to the glasses (otherwise the handshake
|
|
81
85
|
// can race ahead and replay stale native settings).
|
|
82
|
-
|
|
86
|
+
const settings = useSettingsStore.getState().getBluetoothSettings()
|
|
87
|
+
await BluetoothSdk.updateBluetoothSettings(micStateCoordinator.applyRuntimeOverrides(settings))
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
/**
|
|
@@ -91,7 +96,8 @@ export async function pushAllBluetoothSettings(): Promise<void> {
|
|
|
91
96
|
* with pre-promotion empties (wiping the pairing it had just made).
|
|
92
97
|
*/
|
|
93
98
|
export async function pushDeviceSettingsOnConnect(): Promise<void> {
|
|
94
|
-
|
|
99
|
+
const settings = stripPairingIdentity(useSettingsStore.getState().getBluetoothSettings())
|
|
100
|
+
await BluetoothSdk.updateBluetoothSettings(micStateCoordinator.applyRuntimeOverrides(settings))
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
export function startGlassesSettingsSync(): void {
|
|
@@ -11,22 +11,26 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Started by `engine.start()`. Idempotent.
|
|
13
13
|
*/
|
|
14
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
14
|
+
import BluetoothSdk, {type PublicGlassesStatus} from "@mentra/bluetooth-sdk"
|
|
15
15
|
import {useCoreStore} from "../stores/core"
|
|
16
16
|
import {useGlassesStore} from "../stores/glasses"
|
|
17
|
-
import localMiniappRuntime from "./LocalMiniappRuntime"
|
|
18
17
|
|
|
19
18
|
let unsubs: Array<() => void> = []
|
|
20
19
|
let projectionRunId = 0
|
|
20
|
+
let glassesStatusForwarder: ((status: Partial<PublicGlassesStatus>) => void) | null = null
|
|
21
|
+
let hydrationPromise: Promise<void> | null = null
|
|
21
22
|
|
|
22
|
-
export function startGlassesStatusProjection(
|
|
23
|
-
|
|
23
|
+
export function startGlassesStatusProjection(
|
|
24
|
+
forwarder?: (status: Partial<PublicGlassesStatus>) => void,
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
if (forwarder) glassesStatusForwarder = forwarder
|
|
27
|
+
if (unsubs.length) return hydrationPromise ?? Promise.resolve()
|
|
24
28
|
|
|
25
29
|
const runId = ++projectionRunId
|
|
26
30
|
let bluetoothEventSeen = false
|
|
27
31
|
let glassesEventSeen = false
|
|
28
32
|
|
|
29
|
-
|
|
33
|
+
const bluetoothHydration = BluetoothSdk.getBluetoothStatus()
|
|
30
34
|
.then((status) => {
|
|
31
35
|
if (runId !== projectionRunId || bluetoothEventSeen) return
|
|
32
36
|
useCoreStore.getState().setCoreInfo(status)
|
|
@@ -35,7 +39,7 @@ export function startGlassesStatusProjection(): void {
|
|
|
35
39
|
console.warn("GlassesStatusProjection: getBluetoothStatus failed", error)
|
|
36
40
|
})
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
const glassesHydration = BluetoothSdk.getGlassesStatus()
|
|
39
43
|
.then((status) => {
|
|
40
44
|
if (runId !== projectionRunId || glassesEventSeen) return
|
|
41
45
|
useGlassesStore.getState().setGlassesInfo(status)
|
|
@@ -46,28 +50,33 @@ export function startGlassesStatusProjection(): void {
|
|
|
46
50
|
|
|
47
51
|
// Bluetooth-adapter status -> core store.
|
|
48
52
|
unsubs.push(
|
|
49
|
-
BluetoothSdk.
|
|
53
|
+
BluetoothSdk.subscribeBluetoothStatus((changed) => {
|
|
50
54
|
bluetoothEventSeen = true
|
|
51
55
|
useCoreStore.getState().setCoreInfo(changed)
|
|
52
56
|
}),
|
|
53
57
|
)
|
|
54
58
|
|
|
55
|
-
// Glasses status -> glasses store (+
|
|
56
|
-
// OTA-available flag on disconnect).
|
|
59
|
+
// Glasses status -> glasses store (+ optional full-runtime forwarding to local
|
|
60
|
+
// miniapps; clear any stale OTA-available flag on disconnect).
|
|
57
61
|
unsubs.push(
|
|
58
|
-
BluetoothSdk.
|
|
62
|
+
BluetoothSdk.subscribeGlassesStatus((changed) => {
|
|
59
63
|
glassesEventSeen = true
|
|
60
64
|
useGlassesStore.getState().setGlassesInfo(changed)
|
|
61
|
-
|
|
65
|
+
glassesStatusForwarder?.(changed)
|
|
62
66
|
if (changed.connection?.state === "disconnected") {
|
|
63
67
|
useGlassesStore.getState().setOtaUpdateAvailable(null)
|
|
64
68
|
}
|
|
65
69
|
}),
|
|
66
70
|
)
|
|
71
|
+
|
|
72
|
+
hydrationPromise = Promise.allSettled([bluetoothHydration, glassesHydration]).then(() => undefined)
|
|
73
|
+
return hydrationPromise
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
export function stopGlassesStatusProjection(): void {
|
|
70
77
|
projectionRunId++
|
|
71
78
|
unsubs.forEach((unsub) => unsub())
|
|
72
79
|
unsubs = []
|
|
80
|
+
glassesStatusForwarder = null
|
|
81
|
+
hydrationPromise = null
|
|
73
82
|
}
|