@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
|
@@ -10,16 +10,11 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Started by `engine.start()`. Idempotent.
|
|
12
12
|
*/
|
|
13
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
14
|
-
import type {OtaStatus} from "@mentra/bluetooth-sdk/internal"
|
|
13
|
+
import BluetoothSdk, {type OtaStatus} from "@mentra/bluetooth-sdk"
|
|
15
14
|
import GlobalEventEmitter from "../utils/GlobalEventEmitter"
|
|
16
15
|
import {useGlassesStore} from "../stores/glasses"
|
|
17
16
|
import {handleOtaClockSkewFromGlasses} from "./glassesClockSync"
|
|
18
|
-
import {
|
|
19
|
-
legacyOtaProgressFromOtaStatusEvent,
|
|
20
|
-
normalizeOtaStatusEvent,
|
|
21
|
-
otaStatusFromNormalized,
|
|
22
|
-
} from "./otaLegacyMapping"
|
|
17
|
+
import {legacyOtaProgressFromOtaStatusEvent, normalizeOtaStatusEvent, otaStatusFromNormalized} from "./otaLegacyMapping"
|
|
23
18
|
|
|
24
19
|
let subs: Array<{remove: () => void}> = []
|
|
25
20
|
|
|
@@ -40,6 +35,16 @@ export function startOtaService(): void {
|
|
|
40
35
|
}),
|
|
41
36
|
)
|
|
42
37
|
|
|
38
|
+
// The glasses process restarted under a live BLE link (sid changed in
|
|
39
|
+
// glasses_ready/version_info_1). The physical connection never dropped, so this is
|
|
40
|
+
// the ONLY reconnect-edge signal the OTA coordinator gets after an APK install.
|
|
41
|
+
subs.push(
|
|
42
|
+
BluetoothSdk.addListener("glasses_session_changed", (event) => {
|
|
43
|
+
console.log(`[OTA] glasses_session_changed ${event.previous_sid || "<none>"} -> ${event.sid}`)
|
|
44
|
+
GlobalEventEmitter.emit("glasses_session_changed", {previousSid: event.previous_sid, sid: event.sid})
|
|
45
|
+
}),
|
|
46
|
+
)
|
|
47
|
+
|
|
43
48
|
// Install progress / lifecycle. Updates both the new (otaStatus) and the legacy
|
|
44
49
|
// (otaProgress) store shapes; auto-fixes clock skew on the relevant failures.
|
|
45
50
|
subs.push(
|
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
2
|
-
import
|
|
1
|
+
import BluetoothSdk, {type OtaUpdateInfo} from "@mentra/bluetooth-sdk"
|
|
2
|
+
import {ENGINE_RELEASE_METADATA} from "../generated/releaseMetadata"
|
|
3
3
|
import {getGlassesSystemTimeMs, isGlassesConnected, useGlassesStore, waitForGlassesState} from "../stores/glasses"
|
|
4
4
|
import {maybeFixGlassesClockFromVersionInfo} from "./glassesClockSync"
|
|
5
|
-
import {
|
|
5
|
+
import {hasConfiguredModernOtaManifestPin, resolveOtaManifestUrl} from "./otaManifestUrl"
|
|
6
|
+
import {resolveOtaReleaseVersion} from "./otaReleaseVersion"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Phone-side mirror of ASG's `DOWNGRADE_FLOOR_VERSION_CODE`. Set to the versionCode of the first
|
|
10
|
+
* release shipping the shared media root (the first downgrade-safe build). A non-positive value
|
|
11
|
+
* means downgrades are disabled, so the phone must NOT offer them — offering a downgrade the
|
|
12
|
+
* glasses' `DowngradeGate` will refuse leaves the version-change session with no install and the
|
|
13
|
+
* glasses reporting a bare "complete", which would otherwise present as false success. Keep this
|
|
14
|
+
* in lockstep with the ASG/recovery constant at release time.
|
|
15
|
+
*/
|
|
16
|
+
export const DOWNGRADE_FLOOR_VERSION_CODE = 0
|
|
6
17
|
|
|
7
18
|
export interface VersionInfo {
|
|
8
19
|
versionCode: number
|
|
@@ -18,14 +29,17 @@ export interface MtkPatch {
|
|
|
18
29
|
start_firmware: string
|
|
19
30
|
end_firmware: string
|
|
20
31
|
url: string
|
|
32
|
+
sha256?: string
|
|
21
33
|
}
|
|
22
34
|
|
|
23
35
|
export interface BesFirmware {
|
|
24
36
|
version: string
|
|
25
37
|
url: string
|
|
38
|
+
sha256?: string
|
|
26
39
|
}
|
|
27
40
|
|
|
28
41
|
export interface VersionJson {
|
|
42
|
+
releaseVersion?: string
|
|
29
43
|
apps?: {
|
|
30
44
|
[packageName: string]: VersionInfo
|
|
31
45
|
}
|
|
@@ -46,9 +60,25 @@ export interface OtaCheckResult {
|
|
|
46
60
|
updates: string[]
|
|
47
61
|
mtkPatch: MtkPatch | null
|
|
48
62
|
besVersion: string | null
|
|
63
|
+
/** True when the pending APK step installs an OLDER build than the glasses currently run. */
|
|
64
|
+
isApkDowngrade: boolean
|
|
65
|
+
/**
|
|
66
|
+
* Raw manifest JSON (stringified) this check actually fetched, or null when the
|
|
67
|
+
* fetch failed. Lets change-watchers baseline on exactly what the check saw,
|
|
68
|
+
* instead of racing it with a second fetch of the same URL.
|
|
69
|
+
*/
|
|
70
|
+
manifestBody: string | null
|
|
71
|
+
/** Coordinated release identity for the selected OTA pin. */
|
|
72
|
+
releaseVersion: string | null
|
|
73
|
+
/**
|
|
74
|
+
* Why the check failed, when it did. "network" is retryable (connection/server
|
|
75
|
+
* trouble); "pin_unavailable" is permanent for this app build (manifest 404/gone,
|
|
76
|
+
* unparseable, or carrying no valid ASG pin) — the remedy is updating the app.
|
|
77
|
+
*/
|
|
78
|
+
checkFailureReason?: "network" | "pin_unavailable"
|
|
49
79
|
}
|
|
50
80
|
|
|
51
|
-
export type OtaCheckSkippedReason = "disconnected" | "missing_build"
|
|
81
|
+
export type OtaCheckSkippedReason = "disconnected" | "missing_build" | "dev_build"
|
|
52
82
|
|
|
53
83
|
export interface OtaCheckCurrentGlassesResult extends OtaCheckResult {
|
|
54
84
|
updateInfo: OtaUpdateInfo | null
|
|
@@ -66,6 +96,8 @@ export interface OtaCheckCurrentGlassesOptions {
|
|
|
66
96
|
waitForMtkVersionMs?: number
|
|
67
97
|
refreshVersionInfo?: boolean
|
|
68
98
|
fixClockBeforeCheck?: boolean
|
|
99
|
+
/** Downgrade floor override (defaults to DOWNGRADE_FLOOR_VERSION_CODE); for tests. */
|
|
100
|
+
floorVersionCode?: number
|
|
69
101
|
}
|
|
70
102
|
|
|
71
103
|
function emptyCheckResult(skippedReason?: OtaCheckSkippedReason): OtaCheckCurrentGlassesResult {
|
|
@@ -76,6 +108,9 @@ function emptyCheckResult(skippedReason?: OtaCheckSkippedReason): OtaCheckCurren
|
|
|
76
108
|
updates: [],
|
|
77
109
|
mtkPatch: null,
|
|
78
110
|
besVersion: null,
|
|
111
|
+
isApkDowngrade: false,
|
|
112
|
+
manifestBody: null,
|
|
113
|
+
releaseVersion: null,
|
|
79
114
|
updateInfo: null,
|
|
80
115
|
isRequired: true,
|
|
81
116
|
skippedReason,
|
|
@@ -86,46 +121,90 @@ function glassesConnectedNow(): boolean {
|
|
|
86
121
|
return isGlassesConnected(useGlassesStore.getState().connection)
|
|
87
122
|
}
|
|
88
123
|
|
|
89
|
-
|
|
124
|
+
type ManifestFetchResult = {json: VersionJson | null; failureReason?: "network" | "pin_unavailable"}
|
|
125
|
+
|
|
126
|
+
async function fetchVersionInfoDetailed(url: string): Promise<ManifestFetchResult> {
|
|
90
127
|
try {
|
|
91
128
|
const response = await fetch(url)
|
|
92
129
|
if (!response.ok) {
|
|
93
|
-
console.
|
|
94
|
-
|
|
130
|
+
console.warn("Failed to fetch version info:", response.status)
|
|
131
|
+
// 4xx: the manifest does not exist (or is gone) — permanent for this app
|
|
132
|
+
// build, retrying cannot help. Everything else is transient server/network
|
|
133
|
+
// trouble and retryable.
|
|
134
|
+
return {
|
|
135
|
+
json: null,
|
|
136
|
+
failureReason: response.status >= 400 && response.status < 500 ? "pin_unavailable" : "network",
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
return {json: await response.json()}
|
|
141
|
+
} catch (parseError) {
|
|
142
|
+
console.warn("OTA: manifest is not valid JSON:", parseError)
|
|
143
|
+
return {json: null, failureReason: "pin_unavailable"}
|
|
95
144
|
}
|
|
96
|
-
return await response.json()
|
|
97
145
|
} catch (error) {
|
|
98
|
-
console.
|
|
99
|
-
return null
|
|
146
|
+
console.warn("OTA: Error fetching version info:", error)
|
|
147
|
+
return {json: null, failureReason: "network"}
|
|
100
148
|
}
|
|
101
149
|
}
|
|
102
150
|
|
|
151
|
+
export async function fetchVersionInfo(url: string): Promise<VersionJson | null> {
|
|
152
|
+
return (await fetchVersionInfoDetailed(url)).json
|
|
153
|
+
}
|
|
154
|
+
|
|
103
155
|
export function checkVersionUpdateAvailable(
|
|
104
156
|
currentBuildNumber: string | undefined,
|
|
105
157
|
versionJson: VersionJson | null,
|
|
158
|
+
floorVersionCode: number = DOWNGRADE_FLOOR_VERSION_CODE,
|
|
106
159
|
): boolean {
|
|
160
|
+
return getApkUpdateDirection(currentBuildNumber, versionJson, floorVersionCode) !== null
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Direction of the pending APK change, or null when the glasses already match the manifest.
|
|
165
|
+
* Every apps-shaped manifest the phone drives is an exact pin, so both directions are
|
|
166
|
+
* actionable (mirroring the glasses-side `DowngradeGate`); the ancient top-level manifest
|
|
167
|
+
* shape stays upgrade-only, and zeroed rescue pins are never actionable.
|
|
168
|
+
*/
|
|
169
|
+
export function getApkUpdateDirection(
|
|
170
|
+
currentBuildNumber: string | undefined,
|
|
171
|
+
versionJson: VersionJson | null,
|
|
172
|
+
floorVersionCode: number = DOWNGRADE_FLOOR_VERSION_CODE,
|
|
173
|
+
): "upgrade" | "downgrade" | null {
|
|
107
174
|
if (!currentBuildNumber || !versionJson) {
|
|
108
|
-
return
|
|
175
|
+
return null
|
|
109
176
|
}
|
|
110
177
|
|
|
111
178
|
const currentVersion = parseInt(currentBuildNumber, 10)
|
|
112
179
|
if (isNaN(currentVersion)) {
|
|
113
|
-
return
|
|
180
|
+
return null
|
|
114
181
|
}
|
|
115
182
|
|
|
116
183
|
let serverVersion: number | undefined
|
|
184
|
+
let exactPin = false
|
|
117
185
|
|
|
118
|
-
|
|
119
|
-
|
|
186
|
+
const appEntry = versionJson.apps?.["com.mentra.asg_client"]
|
|
187
|
+
if (appEntry) {
|
|
188
|
+
serverVersion = appEntry.versionCode
|
|
189
|
+
exactPin = true
|
|
120
190
|
} else if (versionJson.versionCode) {
|
|
121
191
|
serverVersion = versionJson.versionCode
|
|
122
192
|
}
|
|
123
193
|
|
|
124
194
|
if (!serverVersion || isNaN(serverVersion)) {
|
|
125
|
-
return
|
|
195
|
+
return null
|
|
126
196
|
}
|
|
127
197
|
|
|
128
|
-
|
|
198
|
+
if (serverVersion > currentVersion) {
|
|
199
|
+
return "upgrade"
|
|
200
|
+
}
|
|
201
|
+
// Downgrades require an exact pin AND a target at/above the enabled floor. A non-positive floor
|
|
202
|
+
// disables downgrades entirely, matching ASG's fail-closed DowngradeGate — so the phone never
|
|
203
|
+
// offers what the glasses would refuse.
|
|
204
|
+
if (serverVersion < currentVersion && exactPin && floorVersionCode > 0 && serverVersion >= floorVersionCode) {
|
|
205
|
+
return "downgrade"
|
|
206
|
+
}
|
|
207
|
+
return null
|
|
129
208
|
}
|
|
130
209
|
|
|
131
210
|
export function getLatestVersionInfo(versionJson: VersionJson | null): VersionInfo | null {
|
|
@@ -184,7 +263,7 @@ export function checkBesUpdate(besFirmware: BesFirmware | undefined, currentVers
|
|
|
184
263
|
return compareVersions(besFirmware.version, currentVersion) > 0
|
|
185
264
|
}
|
|
186
265
|
|
|
187
|
-
function compareVersions(version1: string, version2: string): number {
|
|
266
|
+
export function compareVersions(version1: string, version2: string): number {
|
|
188
267
|
if (version1.includes(".") && version2.includes(".")) {
|
|
189
268
|
const parts1 = version1.split(".")
|
|
190
269
|
const parts2 = version2.split(".")
|
|
@@ -208,14 +287,64 @@ export async function checkForOtaUpdate(
|
|
|
208
287
|
currentBuildNumber: string,
|
|
209
288
|
currentMtkVersion?: string,
|
|
210
289
|
currentBesVersion?: string,
|
|
290
|
+
floorVersionCode: number = DOWNGRADE_FLOOR_VERSION_CODE,
|
|
211
291
|
): Promise<OtaCheckResult> {
|
|
212
292
|
try {
|
|
213
293
|
console.log("OTA: Checking for OTA update - URL: " + otaVersionUrl + ", current build: " + currentBuildNumber)
|
|
214
|
-
const
|
|
294
|
+
const fetched = await fetchVersionInfoDetailed(otaVersionUrl)
|
|
295
|
+
const versionJson = fetched.json
|
|
296
|
+
if (!versionJson) {
|
|
297
|
+
return {
|
|
298
|
+
hasCheckCompleted: false,
|
|
299
|
+
updateAvailable: false,
|
|
300
|
+
latestVersionInfo: null,
|
|
301
|
+
updates: [],
|
|
302
|
+
mtkPatch: null,
|
|
303
|
+
besVersion: null,
|
|
304
|
+
isApkDowngrade: false,
|
|
305
|
+
manifestBody: null,
|
|
306
|
+
releaseVersion: null,
|
|
307
|
+
checkFailureReason: fetched.failureReason ?? "network",
|
|
308
|
+
}
|
|
309
|
+
}
|
|
215
310
|
const latestVersionInfo = getLatestVersionInfo(versionJson)
|
|
216
311
|
|
|
217
|
-
|
|
218
|
-
|
|
312
|
+
// A manifest whose ASG pin is missing/zeroed cannot verify anything for modern
|
|
313
|
+
// glasses (zeroed pins are only legitimate in the frozen legacy rescue manifests
|
|
314
|
+
// that pre-39 glasses are checked against). Report the check as FAILED rather
|
|
315
|
+
// than silently completing as "up to date" — an unverifiable state must never
|
|
316
|
+
// present as a verified one.
|
|
317
|
+
const currentVersionNumber = parseInt(currentBuildNumber, 10)
|
|
318
|
+
const pinnedEntry = versionJson?.apps?.["com.mentra.asg_client"]
|
|
319
|
+
const pinnedVersion = pinnedEntry?.versionCode ?? versionJson?.versionCode
|
|
320
|
+
if (
|
|
321
|
+
versionJson &&
|
|
322
|
+
Number.isFinite(currentVersionNumber) &&
|
|
323
|
+
currentVersionNumber >= 39 &&
|
|
324
|
+
!(typeof pinnedVersion === "number" && pinnedVersion > 0)
|
|
325
|
+
) {
|
|
326
|
+
console.error(
|
|
327
|
+
`OTA: manifest at ${otaVersionUrl} has no valid ASG pin (versionCode=${String(pinnedVersion)}) - treating check as failed`,
|
|
328
|
+
)
|
|
329
|
+
return {
|
|
330
|
+
hasCheckCompleted: false,
|
|
331
|
+
updateAvailable: false,
|
|
332
|
+
latestVersionInfo: null,
|
|
333
|
+
updates: [],
|
|
334
|
+
mtkPatch: null,
|
|
335
|
+
besVersion: null,
|
|
336
|
+
isApkDowngrade: false,
|
|
337
|
+
manifestBody: null,
|
|
338
|
+
releaseVersion: null,
|
|
339
|
+
checkFailureReason: "pin_unavailable",
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const apkDirection = getApkUpdateDirection(currentBuildNumber, versionJson, floorVersionCode)
|
|
344
|
+
const apkUpdateAvailable = apkDirection !== null
|
|
345
|
+
console.log(
|
|
346
|
+
`OTA: APK update available: ${apkUpdateAvailable} (current: ${currentBuildNumber}, direction: ${apkDirection ?? "none"})`,
|
|
347
|
+
)
|
|
219
348
|
|
|
220
349
|
const mtkPatch = findMatchingMtkPatch(versionJson?.mtk_patches, currentMtkVersion)
|
|
221
350
|
const mtkUpdateAvailable = mtkPatch !== null
|
|
@@ -243,6 +372,14 @@ export async function checkForOtaUpdate(
|
|
|
243
372
|
updates,
|
|
244
373
|
mtkPatch,
|
|
245
374
|
besVersion: versionJson?.bes_firmware?.version || null,
|
|
375
|
+
isApkDowngrade: apkDirection === "downgrade",
|
|
376
|
+
manifestBody: versionJson ? JSON.stringify(versionJson) : null,
|
|
377
|
+
releaseVersion: resolveOtaReleaseVersion({
|
|
378
|
+
manifestReleaseVersion: versionJson.releaseVersion,
|
|
379
|
+
manifestUrl: otaVersionUrl,
|
|
380
|
+
packagedManifestUrl: ENGINE_RELEASE_METADATA.otaManifestUrl,
|
|
381
|
+
packagedReleaseIdentity: ENGINE_RELEASE_METADATA.releaseIdentity,
|
|
382
|
+
}),
|
|
246
383
|
}
|
|
247
384
|
} catch (error) {
|
|
248
385
|
console.error("Error checking for OTA update:", error)
|
|
@@ -253,6 +390,10 @@ export async function checkForOtaUpdate(
|
|
|
253
390
|
updates: [],
|
|
254
391
|
mtkPatch: null,
|
|
255
392
|
besVersion: null,
|
|
393
|
+
isApkDowngrade: false,
|
|
394
|
+
manifestBody: null,
|
|
395
|
+
releaseVersion: null,
|
|
396
|
+
checkFailureReason: "network",
|
|
256
397
|
}
|
|
257
398
|
}
|
|
258
399
|
}
|
|
@@ -266,16 +407,26 @@ export async function checkCurrentGlassesForUpdate(
|
|
|
266
407
|
waitForMtkVersionMs = 2000,
|
|
267
408
|
refreshVersionInfo = true,
|
|
268
409
|
fixClockBeforeCheck = true,
|
|
410
|
+
floorVersionCode = DOWNGRADE_FLOOR_VERSION_CODE,
|
|
269
411
|
} = options
|
|
270
412
|
|
|
271
413
|
if (!glassesConnectedNow()) {
|
|
272
414
|
return emptyCheckResult("disconnected")
|
|
273
415
|
}
|
|
274
416
|
|
|
417
|
+
if (!hasConfiguredModernOtaManifestPin()) {
|
|
418
|
+
console.log("OTA: check skipped - this app or Engine package has no embedded OTA manifest pin")
|
|
419
|
+
return emptyCheckResult("dev_build")
|
|
420
|
+
}
|
|
421
|
+
|
|
275
422
|
if (refreshVersionInfo) {
|
|
276
|
-
void BluetoothSdk.requestVersionInfo()
|
|
277
|
-
|
|
278
|
-
|
|
423
|
+
void BluetoothSdk.requestVersionInfo()
|
|
424
|
+
.then((versionInfo) => {
|
|
425
|
+
useGlassesStore.getState().setGlassesInfo(versionInfo)
|
|
426
|
+
})
|
|
427
|
+
.catch((error) => {
|
|
428
|
+
console.warn("OTA: Failed to request version_info from glasses:", error)
|
|
429
|
+
})
|
|
279
430
|
}
|
|
280
431
|
|
|
281
432
|
let buildNumber = useGlassesStore.getState().buildNumber
|
|
@@ -284,7 +435,10 @@ export async function checkCurrentGlassesForUpdate(
|
|
|
284
435
|
buildNumber = useGlassesStore.getState().buildNumber
|
|
285
436
|
}
|
|
286
437
|
|
|
287
|
-
if (!buildNumber) {
|
|
438
|
+
if (!buildNumber || !(parseInt(buildNumber, 10) > 0)) {
|
|
439
|
+
// Covers absent, non-numeric, and zero build numbers: a glasses version we
|
|
440
|
+
// cannot parse means nothing is verifiable, so skip rather than ghost an
|
|
441
|
+
// "up to date" result from a comparison that never really ran.
|
|
288
442
|
return emptyCheckResult("missing_build")
|
|
289
443
|
}
|
|
290
444
|
|
|
@@ -325,8 +479,18 @@ export async function checkCurrentGlassesForUpdate(
|
|
|
325
479
|
})
|
|
326
480
|
}
|
|
327
481
|
|
|
328
|
-
const manifestUrl =
|
|
329
|
-
|
|
482
|
+
const manifestUrl = resolveOtaManifestUrl(useGlassesStore.getState().otaVersionUrl, buildNumber)
|
|
483
|
+
if (!manifestUrl) {
|
|
484
|
+
console.log("OTA: check skipped - no OTA manifest pin resolved")
|
|
485
|
+
return emptyCheckResult("dev_build")
|
|
486
|
+
}
|
|
487
|
+
const result = await checkForOtaUpdate(
|
|
488
|
+
manifestUrl,
|
|
489
|
+
buildNumber,
|
|
490
|
+
mtkFirmwareVersion,
|
|
491
|
+
besFirmwareVersion,
|
|
492
|
+
floorVersionCode,
|
|
493
|
+
)
|
|
330
494
|
|
|
331
495
|
if (!result.hasCheckCompleted) {
|
|
332
496
|
return {
|
|
@@ -360,6 +524,7 @@ export async function checkCurrentGlassesForUpdate(
|
|
|
360
524
|
)
|
|
361
525
|
}
|
|
362
526
|
const updateAvailable = filteredUpdates.length > 0 && !!result.latestVersionInfo
|
|
527
|
+
const isApkDowngrade = result.isApkDowngrade && filteredUpdates.includes("apk")
|
|
363
528
|
const updateInfo = updateAvailable
|
|
364
529
|
? {
|
|
365
530
|
available: true,
|
|
@@ -367,6 +532,8 @@ export async function checkCurrentGlassesForUpdate(
|
|
|
367
532
|
versionName: result.latestVersionInfo?.versionName || "",
|
|
368
533
|
updates: filteredUpdates,
|
|
369
534
|
totalSize: 0,
|
|
535
|
+
...(filteredUpdates.includes("bes") && result.besVersion ? {besVersion: result.besVersion} : {}),
|
|
536
|
+
isDowngrade: isApkDowngrade,
|
|
370
537
|
}
|
|
371
538
|
: null
|
|
372
539
|
|
|
@@ -376,8 +543,19 @@ export async function checkCurrentGlassesForUpdate(
|
|
|
376
543
|
...result,
|
|
377
544
|
updateAvailable,
|
|
378
545
|
updates: filteredUpdates,
|
|
546
|
+
isApkDowngrade,
|
|
379
547
|
updateInfo,
|
|
380
|
-
|
|
548
|
+
// Required-update policy: an EXPLICIT isRequired in the manifest is the
|
|
549
|
+
// release-engineering escape hatch and wins in both directions. When absent,
|
|
550
|
+
// upgrades keep the historical forced default, but downgrades are always
|
|
551
|
+
// skippable — a version change that resets glasses settings must be
|
|
552
|
+
// declinable unless someone explicitly forced it.
|
|
553
|
+
isRequired:
|
|
554
|
+
result.latestVersionInfo?.isRequired === true
|
|
555
|
+
? true
|
|
556
|
+
: result.latestVersionInfo?.isRequired === false
|
|
557
|
+
? false
|
|
558
|
+
: !isApkDowngrade,
|
|
381
559
|
manifestUrl,
|
|
382
560
|
buildNumber,
|
|
383
561
|
mtkFirmwareVersion,
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import {MiniappErrorCode, type CalendarEvent} from "@mentra/miniapp"
|
|
2
|
+
|
|
3
|
+
const DEFAULT_LIMIT = 50
|
|
4
|
+
const MAX_LIMIT = 100
|
|
5
|
+
const MAX_RANGE_MS = 31 * 24 * 60 * 60 * 1000
|
|
6
|
+
|
|
7
|
+
export interface CalendarListRequest {
|
|
8
|
+
startsAt?: unknown
|
|
9
|
+
endsAt?: unknown
|
|
10
|
+
limit?: unknown
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class PhoneCalendarError extends Error {
|
|
14
|
+
constructor(
|
|
15
|
+
public readonly code: MiniappErrorCode,
|
|
16
|
+
message: string,
|
|
17
|
+
) {
|
|
18
|
+
super(message)
|
|
19
|
+
this.name = "PhoneCalendarError"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ValidatedCalendarListRequest {
|
|
24
|
+
startsAt: Date
|
|
25
|
+
endsAt: Date
|
|
26
|
+
limit: number
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface RawCalendarEvent {
|
|
30
|
+
id?: string
|
|
31
|
+
calendarId?: string
|
|
32
|
+
title?: string | null
|
|
33
|
+
startDate: string | Date
|
|
34
|
+
endDate: string | Date
|
|
35
|
+
timeZone?: string | null
|
|
36
|
+
allDay?: boolean
|
|
37
|
+
location?: string | null
|
|
38
|
+
notes?: string | null
|
|
39
|
+
url?: string | null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function validateCalendarListRequest(request: CalendarListRequest): ValidatedCalendarListRequest {
|
|
43
|
+
const startsAt = parseDate(request.startsAt, "startsAt")
|
|
44
|
+
const endsAt = parseDate(request.endsAt, "endsAt")
|
|
45
|
+
if (endsAt.getTime() <= startsAt.getTime()) {
|
|
46
|
+
throw new PhoneCalendarError(MiniappErrorCode.INVALID_ARGUMENT, "endsAt must be after startsAt")
|
|
47
|
+
}
|
|
48
|
+
if (endsAt.getTime() - startsAt.getTime() > MAX_RANGE_MS) {
|
|
49
|
+
throw new PhoneCalendarError(MiniappErrorCode.INVALID_ARGUMENT, "Calendar query range may not exceed 31 days")
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const limit = request.limit === undefined ? DEFAULT_LIMIT : request.limit
|
|
53
|
+
if (typeof limit !== "number" || !Number.isInteger(limit) || limit < 1 || limit > MAX_LIMIT) {
|
|
54
|
+
throw new PhoneCalendarError(
|
|
55
|
+
MiniappErrorCode.INVALID_ARGUMENT,
|
|
56
|
+
`limit must be an integer between 1 and ${MAX_LIMIT}`,
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
return {startsAt, endsAt, limit}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function parseDate(value: unknown, field: string): Date {
|
|
63
|
+
if (typeof value !== "string") {
|
|
64
|
+
throw new PhoneCalendarError(MiniappErrorCode.INVALID_ARGUMENT, `${field} must be an ISO 8601 string`)
|
|
65
|
+
}
|
|
66
|
+
const date = new Date(value)
|
|
67
|
+
if (Number.isNaN(date.getTime())) {
|
|
68
|
+
throw new PhoneCalendarError(MiniappErrorCode.INVALID_ARGUMENT, `${field} must be a valid ISO 8601 string`)
|
|
69
|
+
}
|
|
70
|
+
return date
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function extractHttpsLinks(...values: Array<string | null | undefined>): string[] {
|
|
74
|
+
const links = new Set<string>()
|
|
75
|
+
for (const value of values) {
|
|
76
|
+
for (const match of value?.match(/https:\/\/[^\s<>"']+/gi) ?? []) {
|
|
77
|
+
let link = match
|
|
78
|
+
while (".,;:!?)]}".includes(link[link.length - 1] ?? "")) link = link.slice(0, -1)
|
|
79
|
+
if (link) links.add(link)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return [...links]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface CalendarDateParts {
|
|
86
|
+
year: number
|
|
87
|
+
month: number
|
|
88
|
+
day: number
|
|
89
|
+
hour: number
|
|
90
|
+
minute: number
|
|
91
|
+
second: number
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function localDateParts(date: Date): CalendarDateParts {
|
|
95
|
+
return {
|
|
96
|
+
year: date.getFullYear(),
|
|
97
|
+
month: date.getMonth() + 1,
|
|
98
|
+
day: date.getDate(),
|
|
99
|
+
hour: date.getHours(),
|
|
100
|
+
minute: date.getMinutes(),
|
|
101
|
+
second: date.getSeconds(),
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function datePartsInTimeZone(date: Date, timeZone: string): CalendarDateParts | undefined {
|
|
106
|
+
try {
|
|
107
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
108
|
+
timeZone,
|
|
109
|
+
year: "numeric",
|
|
110
|
+
month: "2-digit",
|
|
111
|
+
day: "2-digit",
|
|
112
|
+
hour: "2-digit",
|
|
113
|
+
minute: "2-digit",
|
|
114
|
+
second: "2-digit",
|
|
115
|
+
hourCycle: "h23",
|
|
116
|
+
}).formatToParts(date)
|
|
117
|
+
const value = (type: Intl.DateTimeFormatPartTypes) => Number(parts.find((part) => part.type === type)?.value)
|
|
118
|
+
return {
|
|
119
|
+
year: value("year"),
|
|
120
|
+
month: value("month"),
|
|
121
|
+
day: value("day"),
|
|
122
|
+
hour: value("hour"),
|
|
123
|
+
minute: value("minute"),
|
|
124
|
+
second: value("second"),
|
|
125
|
+
}
|
|
126
|
+
} catch {
|
|
127
|
+
return undefined
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function timeZoneOffsetMinutes(date: Date, timeZone: string): number | undefined {
|
|
132
|
+
const parts = datePartsInTimeZone(date, timeZone)
|
|
133
|
+
if (!parts) return undefined
|
|
134
|
+
const representedAsUtc = Date.UTC(
|
|
135
|
+
parts.year,
|
|
136
|
+
parts.month - 1,
|
|
137
|
+
parts.day,
|
|
138
|
+
parts.hour,
|
|
139
|
+
parts.minute,
|
|
140
|
+
parts.second,
|
|
141
|
+
date.getUTCMilliseconds(),
|
|
142
|
+
)
|
|
143
|
+
return Math.round((representedAsUtc - date.getTime()) / 60_000)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function pad(value: number, length = 2): string {
|
|
147
|
+
return String(value).padStart(length, "0")
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function formatOffset(offsetMinutes: number): string {
|
|
151
|
+
if (offsetMinutes === 0) return "Z"
|
|
152
|
+
const sign = offsetMinutes < 0 ? "-" : "+"
|
|
153
|
+
const absolute = Math.abs(offsetMinutes)
|
|
154
|
+
return `${sign}${pad(Math.floor(absolute / 60))}:${pad(absolute % 60)}`
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function formatAllDayDate(value: string | Date, timeZone?: string | null): string {
|
|
158
|
+
const dateOnly = typeof value === "string" ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(value) : null
|
|
159
|
+
if (dateOnly) {
|
|
160
|
+
const [, year, month, day] = dateOnly
|
|
161
|
+
const localMidnight = new Date(Number(year), Number(month) - 1, Number(day))
|
|
162
|
+
let offsetMinutes = -localMidnight.getTimezoneOffset()
|
|
163
|
+
if (timeZone) {
|
|
164
|
+
// Resolve the offset at midnight in the event timezone. Repeating once
|
|
165
|
+
// accounts for the initial UTC guess landing across a DST boundary.
|
|
166
|
+
const wallTime = Date.UTC(Number(year), Number(month) - 1, Number(day))
|
|
167
|
+
let instant = new Date(wallTime)
|
|
168
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
169
|
+
const offset = timeZoneOffsetMinutes(instant, timeZone)
|
|
170
|
+
if (offset === undefined) break
|
|
171
|
+
offsetMinutes = offset
|
|
172
|
+
instant = new Date(wallTime - offset * 60_000)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return `${year}-${month}-${day}T00:00:00.000${formatOffset(offsetMinutes)}`
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const date = new Date(value)
|
|
179
|
+
const zonedParts = timeZone ? datePartsInTimeZone(date, timeZone) : undefined
|
|
180
|
+
const parts = zonedParts ?? localDateParts(date)
|
|
181
|
+
const offsetMinutes =
|
|
182
|
+
timeZone && zonedParts
|
|
183
|
+
? (timeZoneOffsetMinutes(date, timeZone) ?? -date.getTimezoneOffset())
|
|
184
|
+
: -date.getTimezoneOffset()
|
|
185
|
+
return `${pad(parts.year, 4)}-${pad(parts.month)}-${pad(parts.day)}T${pad(parts.hour)}:${pad(parts.minute)}:${pad(parts.second)}.${pad(date.getUTCMilliseconds(), 3)}${formatOffset(offsetMinutes)}`
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function normalizeCalendarEvent(event: RawCalendarEvent): CalendarEvent {
|
|
189
|
+
const startsAt = event.allDay
|
|
190
|
+
? formatAllDayDate(event.startDate, event.timeZone)
|
|
191
|
+
: new Date(event.startDate).toISOString()
|
|
192
|
+
const endsAt = event.allDay ? formatAllDayDate(event.endDate, event.timeZone) : new Date(event.endDate).toISOString()
|
|
193
|
+
const calendarId = event.calendarId ?? ""
|
|
194
|
+
const eventId = event.id ?? ""
|
|
195
|
+
return {
|
|
196
|
+
id: `${calendarId}:${eventId}:${startsAt}`,
|
|
197
|
+
calendarId,
|
|
198
|
+
title: event.title ?? "",
|
|
199
|
+
startsAt,
|
|
200
|
+
endsAt,
|
|
201
|
+
...(event.timeZone ? {timezone: event.timeZone} : {}),
|
|
202
|
+
allDay: !!event.allDay,
|
|
203
|
+
...(event.location ? {location: event.location} : {}),
|
|
204
|
+
...(event.notes ? {notes: event.notes} : {}),
|
|
205
|
+
...(event.url ? {url: event.url} : {}),
|
|
206
|
+
links: extractHttpsLinks(event.url, event.location, event.notes),
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function calendarEventOverlapsWindow(event: CalendarEvent, startsAt: Date, endsAt: Date): boolean {
|
|
211
|
+
return Date.parse(event.endsAt) > startsAt.getTime() && Date.parse(event.startsAt) < endsAt.getTime()
|
|
212
|
+
}
|