@mentra/engine 0.1.0-dev.0 → 3.1.0-dev.10
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 +55 -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/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 +24 -16
- 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 +14 -16
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +22 -7
- package/build/facades/ota.js.map +1 -1
- package/build/facades/pairing.d.ts +8 -5
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +12 -10
- 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 +10 -8
- package/build/index.d.ts.map +1 -1
- package/build/index.js +6 -5
- package/build/index.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.d.ts +38 -0
- package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
- package/build/react/MentraLiveOtaFlow.js +528 -0
- package/build/react/MentraLiveOtaFlow.js.map +1 -0
- package/build/react/index.d.ts +2 -0
- package/build/react/index.d.ts.map +1 -0
- package/build/react/index.js +2 -0
- package/build/react/index.js.map +1 -0
- package/build/react/useEngineSnapshot.d.ts +2 -0
- package/build/react/useEngineSnapshot.d.ts.map +1 -0
- package/build/react/useEngineSnapshot.js +14 -0
- package/build/react/useEngineSnapshot.js.map +1 -0
- package/build/runtime/bootstrap.d.ts +24 -1
- package/build/runtime/bootstrap.d.ts.map +1 -1
- package/build/runtime/bootstrap.js +17 -0
- package/build/runtime/bootstrap.js.map +1 -1
- package/build/runtime/scanQrSeam.d.ts +7 -0
- package/build/runtime/scanQrSeam.d.ts.map +1 -0
- package/build/runtime/scanQrSeam.js +16 -0
- package/build/runtime/scanQrSeam.js.map +1 -0
- package/build/services/AppRegistry.d.ts +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 +2 -1
- package/build/services/BlobStore.d.ts.map +1 -1
- package/build/services/BlobStore.js +17 -9
- package/build/services/BlobStore.js.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.js +13 -1
- package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
- package/build/services/CloudClientService.d.ts +15 -0
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +93 -1
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DeviceEventRouter.js +5 -5
- package/build/services/DeviceEventRouter.js.map +1 -1
- package/build/services/ForegroundLocationPermission.d.ts +13 -0
- package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
- package/build/services/ForegroundLocationPermission.js +12 -0
- package/build/services/ForegroundLocationPermission.js.map +1 -0
- package/build/services/GlassesSettingsSync.d.ts.map +1 -1
- package/build/services/GlassesSettingsSync.js +9 -3
- package/build/services/GlassesSettingsSync.js.map +1 -1
- package/build/services/GlassesStatusProjection.d.ts +2 -1
- package/build/services/GlassesStatusProjection.d.ts.map +1 -1
- package/build/services/GlassesStatusProjection.js +15 -8
- package/build/services/GlassesStatusProjection.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts +29 -0
- package/build/services/HotspotOtaTransport.d.ts.map +1 -0
- package/build/services/HotspotOtaTransport.js +146 -0
- package/build/services/HotspotOtaTransport.js.map +1 -0
- package/build/services/HotspotShutdown.d.ts +17 -0
- package/build/services/HotspotShutdown.d.ts.map +1 -0
- package/build/services/HotspotShutdown.js +29 -0
- package/build/services/HotspotShutdown.js.map +1 -0
- package/build/services/LocalDisplayManager.d.ts +15 -0
- package/build/services/LocalDisplayManager.d.ts.map +1 -1
- package/build/services/LocalDisplayManager.js +106 -20
- package/build/services/LocalDisplayManager.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +74 -2
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +785 -291
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalMiniappStorage.d.ts +32 -0
- package/build/services/LocalMiniappStorage.d.ts.map +1 -0
- package/build/services/LocalMiniappStorage.js +66 -0
- package/build/services/LocalMiniappStorage.js.map +1 -0
- package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
- package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
- package/build/services/LocalMiniappUserIdentity.js +43 -0
- package/build/services/LocalMiniappUserIdentity.js.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js +18 -12
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/MicStateCoordinator.d.ts +42 -1
- package/build/services/MicStateCoordinator.d.ts.map +1 -1
- package/build/services/MicStateCoordinator.js +141 -3
- package/build/services/MicStateCoordinator.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +23 -3
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/MiniappLiveness.d.ts +12 -0
- package/build/services/MiniappLiveness.d.ts.map +1 -0
- package/build/services/MiniappLiveness.js +16 -0
- package/build/services/MiniappLiveness.js.map +1 -0
- package/build/services/NativeHttpResponse.d.ts +3 -0
- package/build/services/NativeHttpResponse.d.ts.map +1 -0
- package/build/services/NativeHttpResponse.js +6 -0
- package/build/services/NativeHttpResponse.js.map +1 -0
- package/build/services/OtaArtifactDownloader.d.ts +65 -0
- package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
- package/build/services/OtaArtifactDownloader.js +226 -0
- package/build/services/OtaArtifactDownloader.js.map +1 -0
- package/build/services/OtaAutoChain.d.ts +34 -0
- package/build/services/OtaAutoChain.d.ts.map +1 -0
- package/build/services/OtaAutoChain.js +83 -0
- package/build/services/OtaAutoChain.js.map +1 -0
- package/build/services/OtaErrorMapping.d.ts +18 -0
- package/build/services/OtaErrorMapping.d.ts.map +1 -0
- package/build/services/OtaErrorMapping.js +63 -0
- package/build/services/OtaErrorMapping.js.map +1 -0
- package/build/services/OtaInstallCoordinator.d.ts +95 -15
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +577 -130
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/OtaService.d.ts.map +1 -1
- package/build/services/OtaService.js +8 -1
- package/build/services/OtaService.js.map +1 -1
- package/build/services/OtaUpdateCheckService.d.ts +39 -4
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +138 -22
- package/build/services/OtaUpdateCheckService.js.map +1 -1
- package/build/services/PhoneCalendarHelpers.d.ts +32 -0
- package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
- package/build/services/PhoneCalendarHelpers.js +157 -0
- package/build/services/PhoneCalendarHelpers.js.map +1 -0
- package/build/services/PhoneCalendarService.d.ts +5 -0
- package/build/services/PhoneCalendarService.d.ts.map +1 -0
- package/build/services/PhoneCalendarService.js +45 -0
- package/build/services/PhoneCalendarService.js.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.js +194 -0
- package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +12 -10
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts +26 -2
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
- package/build/services/PhonePhotoCoordinator.js +79 -9
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts +8 -1
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
- package/build/services/PhoneStreamCoordinator.js +125 -13
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/PhoneVideoCoordinator.d.ts +2 -0
- package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
- package/build/services/PhoneVideoCoordinator.js +10 -0
- package/build/services/PhoneVideoCoordinator.js.map +1 -1
- package/build/services/SceneRenderer.d.ts.map +1 -1
- package/build/services/SceneRenderer.js +15 -0
- package/build/services/SceneRenderer.js.map +1 -1
- package/build/services/SentenceTtsPipeline.d.ts +31 -0
- package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
- package/build/services/SentenceTtsPipeline.js +67 -0
- package/build/services/SentenceTtsPipeline.js.map +1 -0
- package/build/services/SupportProfileSync.d.ts +22 -0
- package/build/services/SupportProfileSync.d.ts.map +1 -0
- package/build/services/SupportProfileSync.js +213 -0
- package/build/services/SupportProfileSync.js.map +1 -0
- package/build/services/TranscriptionRouting.d.ts +12 -0
- package/build/services/TranscriptionRouting.d.ts.map +1 -0
- package/build/services/TranscriptionRouting.js +24 -0
- package/build/services/TranscriptionRouting.js.map +1 -0
- package/build/services/TtsTextSanitizer.d.ts +5 -0
- package/build/services/TtsTextSanitizer.d.ts.map +1 -0
- package/build/services/TtsTextSanitizer.js +61 -0
- package/build/services/TtsTextSanitizer.js.map +1 -0
- package/build/services/WifiAdbRequest.d.ts +17 -0
- package/build/services/WifiAdbRequest.d.ts.map +1 -0
- package/build/services/WifiAdbRequest.js +35 -0
- package/build/services/WifiAdbRequest.js.map +1 -0
- package/build/services/asg/asgCameraApi.d.ts +43 -0
- package/build/services/asg/asgCameraApi.d.ts.map +1 -1
- package/build/services/asg/asgCameraApi.js +509 -26
- package/build/services/asg/asgCameraApi.js.map +1 -1
- package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
- package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportCoordinator.js +618 -0
- package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
- package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
- package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportLedger.js +78 -0
- package/build/services/asg/cameraRollExportLedger.js.map +1 -0
- package/build/services/asg/galleryNotices.d.ts +1 -1
- package/build/services/asg/galleryNotices.d.ts.map +1 -1
- package/build/services/asg/galleryNotices.js.map +1 -1
- package/build/services/asg/galleryPathMigration.d.ts +3 -0
- package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
- package/build/services/asg/galleryPathMigration.js +26 -0
- package/build/services/asg/galleryPathMigration.js.map +1 -0
- package/build/services/asg/gallerySettingsService.d.ts +1 -0
- package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
- package/build/services/asg/gallerySettingsService.js +2 -0
- package/build/services/asg/gallerySettingsService.js.map +1 -1
- package/build/services/asg/gallerySyncService.d.ts.map +1 -1
- package/build/services/asg/gallerySyncService.js +162 -56
- package/build/services/asg/gallerySyncService.js.map +1 -1
- package/build/services/asg/galleryTransferLedger.d.ts +58 -0
- package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
- package/build/services/asg/galleryTransferLedger.js +225 -0
- package/build/services/asg/galleryTransferLedger.js.map +1 -0
- package/build/services/asg/localNetworkTransport.d.ts +15 -0
- package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
- package/build/services/asg/localNetworkTransport.js +144 -0
- package/build/services/asg/localNetworkTransport.js.map +1 -0
- package/build/services/asg/localStorageService.d.ts +18 -0
- package/build/services/asg/localStorageService.d.ts.map +1 -1
- package/build/services/asg/localStorageService.js +168 -19
- package/build/services/asg/localStorageService.js.map +1 -1
- package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
- package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
- package/build/services/asg/mediaProcessingQueue.js +193 -62
- package/build/services/asg/mediaProcessingQueue.js.map +1 -1
- package/build/services/audioPlaybackAssets.d.ts +8 -0
- package/build/services/audioPlaybackAssets.d.ts.map +1 -0
- package/build/services/audioPlaybackAssets.js +7 -0
- package/build/services/audioPlaybackAssets.js.map +1 -0
- package/build/services/gallerySyncClock.js +1 -1
- package/build/services/gallerySyncClock.js.map +1 -1
- package/build/services/glassesClockSync.d.ts.map +1 -1
- package/build/services/glassesClockSync.js +6 -2
- package/build/services/glassesClockSync.js.map +1 -1
- package/build/services/manifestActions.d.ts +7 -0
- package/build/services/manifestActions.d.ts.map +1 -0
- package/build/services/manifestActions.js +25 -0
- package/build/services/manifestActions.js.map +1 -0
- package/build/services/otaDisplayState.d.ts +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 +16 -4
- package/build/services/otaInstallPolicy.d.ts.map +1 -1
- package/build/services/otaInstallPolicy.js +24 -3
- package/build/services/otaInstallPolicy.js.map +1 -1
- package/build/services/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/slimStreamStatus.d.ts +11 -0
- package/build/services/slimStreamStatus.d.ts.map +1 -1
- package/build/services/slimStreamStatus.js +14 -4
- package/build/services/slimStreamStatus.js.map +1 -1
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +11 -0
- package/build/stores/apps.js.map +1 -1
- package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
- package/build/stores/bluetoothSettingKeys.js +2 -0
- package/build/stores/bluetoothSettingKeys.js.map +1 -1
- package/build/stores/gallerySync.d.ts +2 -0
- package/build/stores/gallerySync.d.ts.map +1 -1
- package/build/stores/gallerySync.js +2 -0
- package/build/stores/gallerySync.js.map +1 -1
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js +3 -0
- package/build/stores/glasses.js.map +1 -1
- package/build/stores/settings.d.ts +17 -0
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +157 -17
- package/build/stores/settings.js.map +1 -1
- package/build/types/applet.d.ts +2 -0
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/build/types/asg.d.ts +7 -0
- package/build/types/asg.d.ts.map +1 -1
- package/build/types/asg.js.map +1 -1
- package/build/types/enums.d.ts +2 -25
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +2 -27
- package/build/types/enums.js.map +1 -1
- package/build/types/hardware.d.ts +4 -13
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +15 -3
- package/build/types/hardware.js.map +1 -1
- package/build/types/index.d.ts +2 -6
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js +2 -6
- 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/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 +59 -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/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 +23 -8
- package/src/facades/pairing.ts +15 -11
- 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 +39 -13
- package/src/react/MentraLiveOtaFlow.tsx +856 -0
- package/src/react/index.ts +7 -0
- package/src/react/useEngineSnapshot.ts +16 -0
- package/src/runtime/bootstrap.ts +33 -1
- package/src/runtime/scanQrSeam.ts +20 -0
- package/src/services/AppRegistry.ts +240 -149
- package/src/services/AudioCloudUplink.ts +23 -1
- package/src/services/AudioPlaybackService.ts +287 -38
- package/src/services/BlobStore.ts +22 -9
- package/src/services/CloudAudioSubscriptionSync.ts +13 -1
- package/src/services/CloudClientService.ts +96 -1
- package/src/services/DeviceEventRouter.ts +5 -5
- package/src/services/ForegroundLocationPermission.ts +24 -0
- package/src/services/GlassesSettingsSync.ts +9 -3
- package/src/services/GlassesStatusProjection.ts +16 -8
- package/src/services/HotspotOtaTransport.ts +184 -0
- package/src/services/HotspotShutdown.ts +41 -0
- package/src/services/LocalDisplayManager.ts +112 -21
- package/src/services/LocalMiniappRuntime.ts +967 -346
- package/src/services/LocalMiniappStorage.ts +82 -0
- package/src/services/LocalMiniappUserIdentity.ts +46 -0
- package/src/services/LocalSttFallbackCoordinator.ts +19 -12
- package/src/services/MicStateCoordinator.ts +169 -4
- package/src/services/MiniappLauncher.ts +30 -3
- package/src/services/MiniappLiveness.ts +24 -0
- package/src/services/NativeHttpResponse.ts +6 -0
- package/src/services/OtaArtifactDownloader.ts +312 -0
- package/src/services/OtaAutoChain.ts +106 -0
- package/src/services/OtaErrorMapping.ts +80 -0
- package/src/services/OtaInstallCoordinator.ts +649 -144
- package/src/services/OtaService.ts +11 -5
- package/src/services/OtaUpdateCheckService.ts +181 -21
- package/src/services/PhoneCalendarHelpers.ts +212 -0
- package/src/services/PhoneCalendarService.ts +65 -0
- package/src/services/PhoneCameraFovCoordinator.ts +210 -0
- package/src/services/PhoneNotificationsSync.ts +12 -10
- package/src/services/PhonePhotoCoordinator.ts +116 -18
- package/src/services/PhoneStreamCoordinator.ts +139 -25
- package/src/services/PhoneVideoCoordinator.ts +11 -0
- package/src/services/SceneRenderer.ts +16 -0
- package/src/services/SentenceTtsPipeline.ts +106 -0
- package/src/services/SupportProfileSync.ts +218 -0
- package/src/services/TranscriptionRouting.ts +37 -0
- package/src/services/TtsTextSanitizer.ts +66 -0
- package/src/services/WifiAdbRequest.ts +53 -0
- package/src/services/asg/asgCameraApi.ts +615 -33
- package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
- package/src/services/asg/cameraRollExportLedger.ts +122 -0
- package/src/services/asg/galleryNotices.ts +1 -0
- package/src/services/asg/galleryPathMigration.ts +22 -0
- package/src/services/asg/gallerySettingsService.ts +3 -0
- package/src/services/asg/gallerySyncService.ts +184 -73
- package/src/services/asg/galleryTransferLedger.ts +312 -0
- package/src/services/asg/localNetworkTransport.ts +169 -0
- package/src/services/asg/localStorageService.ts +179 -24
- package/src/services/asg/mediaProcessingQueue.ts +209 -62
- package/src/services/audioPlaybackAssets.ts +8 -0
- package/src/services/gallerySyncClock.ts +1 -1
- package/src/services/glassesClockSync.ts +6 -2
- package/src/services/manifestActions.ts +30 -0
- package/src/services/otaDisplayState.ts +58 -17
- package/src/services/otaInstallPolicy.ts +30 -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/slimStreamStatus.ts +16 -5
- package/src/stores/apps.ts +12 -0
- package/src/stores/bluetoothSettingKeys.ts +2 -0
- package/src/stores/gallerySync.ts +4 -0
- package/src/stores/glasses.ts +3 -0
- package/src/stores/settings.ts +179 -18
- package/src/types/applet.ts +2 -0
- package/src/types/asg.ts +7 -0
- package/src/types/enums.ts +3 -28
- package/src/types/hardware.ts +20 -13
- package/src/types/index.ts +2 -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/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
|
@@ -26,10 +26,13 @@ import {permissions, PermissionFeatures} from "../../facades/permissions"
|
|
|
26
26
|
import {asgCameraApi} from "./asgCameraApi"
|
|
27
27
|
import {gallerySettingsService} from "./gallerySettingsService"
|
|
28
28
|
import {gallerySyncNotifications} from "./gallerySyncNotifications"
|
|
29
|
+
import {localNetworkTransport} from "./localNetworkTransport"
|
|
29
30
|
import {localStorageService} from "./localStorageService"
|
|
30
31
|
import {mediaProcessingQueue} from "./mediaProcessingQueue"
|
|
31
32
|
import {validateCaptureMetadataForDownload} from "./galleryMediaValidation"
|
|
32
33
|
import {emitGalleryNotice} from "./galleryNotices"
|
|
34
|
+
import {galleryTransferLedger} from "./galleryTransferLedger"
|
|
35
|
+
import {cameraRollExportCoordinator} from "./cameraRollExportCoordinator"
|
|
33
36
|
|
|
34
37
|
// Timing constants
|
|
35
38
|
const TIMING = {
|
|
@@ -111,6 +114,8 @@ class GallerySyncService {
|
|
|
111
114
|
this.hotspotListenerRegistered = true
|
|
112
115
|
this.isInitialized = true
|
|
113
116
|
|
|
117
|
+
void cameraRollExportCoordinator.initialize()
|
|
118
|
+
|
|
114
119
|
// console.log("[GallerySyncService] Initialized")
|
|
115
120
|
|
|
116
121
|
// Check for resumable sync on startup
|
|
@@ -121,6 +126,7 @@ class GallerySyncService {
|
|
|
121
126
|
* Cleanup - remove event listeners
|
|
122
127
|
*/
|
|
123
128
|
cleanup(): void {
|
|
129
|
+
void localNetworkTransport.disconnect()
|
|
124
130
|
if (this.hotspotListenerRegistered) {
|
|
125
131
|
GlobalEventEmitter.removeListener("hotspot_status_change", this.handleHotspotStatusChange)
|
|
126
132
|
GlobalEventEmitter.removeListener("hotspot_error", this.handleHotspotError)
|
|
@@ -137,6 +143,7 @@ class GallerySyncService {
|
|
|
137
143
|
this.appStateSubscription.remove()
|
|
138
144
|
this.appStateSubscription = null
|
|
139
145
|
}
|
|
146
|
+
cameraRollExportCoordinator.cleanup()
|
|
140
147
|
|
|
141
148
|
if (this.hotspotConnectionTimeout) {
|
|
142
149
|
BgTimer.clearTimeout(this.hotspotConnectionTimeout!)
|
|
@@ -149,6 +156,10 @@ class GallerySyncService {
|
|
|
149
156
|
}
|
|
150
157
|
|
|
151
158
|
this.syncStartPromise = null
|
|
159
|
+
useGallerySyncStore.getState().setSyncStarting(false)
|
|
160
|
+
this.waitingForWifiRetry = false
|
|
161
|
+
this.wifiSettingsOpenedAt = null
|
|
162
|
+
this.startAborted = false
|
|
152
163
|
this.isInitialized = false
|
|
153
164
|
console.log("[GallerySyncService] Cleaned up")
|
|
154
165
|
}
|
|
@@ -191,6 +202,7 @@ class GallerySyncService {
|
|
|
191
202
|
}
|
|
192
203
|
|
|
193
204
|
gallerySyncNotifications.showSyncError("Glasses disconnected")
|
|
205
|
+
void localNetworkTransport.disconnect()
|
|
194
206
|
}
|
|
195
207
|
|
|
196
208
|
/**
|
|
@@ -202,6 +214,9 @@ class GallerySyncService {
|
|
|
202
214
|
return
|
|
203
215
|
}
|
|
204
216
|
|
|
217
|
+
// Camera-roll backfill is phone-local and must resume independently of glasses/WiFi.
|
|
218
|
+
void cameraRollExportCoordinator.resume("app foreground")
|
|
219
|
+
|
|
205
220
|
// Only auto-retry if we were waiting for WiFi
|
|
206
221
|
if (!this.waitingForWifiRetry) {
|
|
207
222
|
return
|
|
@@ -217,14 +232,23 @@ class GallerySyncService {
|
|
|
217
232
|
if (!glassesConnected) {
|
|
218
233
|
console.log("[GallerySyncService] Glasses disconnected - not retrying sync")
|
|
219
234
|
this.waitingForWifiRetry = false
|
|
235
|
+
this.wifiSettingsOpenedAt = null
|
|
220
236
|
return
|
|
221
237
|
}
|
|
222
238
|
|
|
239
|
+
// The user has returned from the WiFi settings prompt, so the previous
|
|
240
|
+
// "Sync failed" state is no longer actionable. Make the button available
|
|
241
|
+
// immediately while the native WiFi state catches up; a successful check
|
|
242
|
+
// below will start the sync automatically.
|
|
243
|
+
if (store.syncState === "error" && store.lastError?.startsWith("WiFi disabled")) {
|
|
244
|
+
store.setSyncState("idle")
|
|
245
|
+
}
|
|
246
|
+
|
|
223
247
|
// Check if WiFi is now enabled (Android only)
|
|
224
248
|
// Use retry logic because WiFi status takes time to propagate after user enables it
|
|
225
249
|
if (Platform.OS === "android") {
|
|
226
250
|
const MAX_RETRIES = 5
|
|
227
|
-
const RETRY_DELAY_MS = 1000
|
|
251
|
+
const RETRY_DELAY_MS = 1000
|
|
228
252
|
|
|
229
253
|
console.log("[GallerySyncService] Waiting for WiFi to initialize (may take a moment after enabling)...")
|
|
230
254
|
|
|
@@ -232,35 +256,28 @@ class GallerySyncService {
|
|
|
232
256
|
try {
|
|
233
257
|
await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), RETRY_DELAY_MS))
|
|
234
258
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
)
|
|
259
|
+
// NetInfo can remain stale after Android's WiFi settings close. Use
|
|
260
|
+
// the same native source as the normal sync preflight.
|
|
261
|
+
const wifiEnabled = await WifiManager.isEnabled()
|
|
262
|
+
console.log(`[GallerySyncService] WiFi check attempt ${attempt}/${MAX_RETRIES}: enabled=${wifiEnabled}`)
|
|
239
263
|
|
|
240
|
-
if (
|
|
264
|
+
if (wifiEnabled) {
|
|
241
265
|
console.log("[GallerySyncService] ✅ WiFi is now enabled - auto-retrying sync")
|
|
242
266
|
this.waitingForWifiRetry = false
|
|
243
267
|
this.wifiSettingsOpenedAt = null // Clear cooldown timestamp
|
|
244
|
-
// Clear previous error state
|
|
245
|
-
store.setSyncState("idle")
|
|
246
268
|
// Auto-retry sync
|
|
247
269
|
await this.startSync()
|
|
248
270
|
return
|
|
249
271
|
}
|
|
250
|
-
|
|
251
|
-
// If this was the last attempt, log and give up
|
|
252
|
-
if (attempt === MAX_RETRIES) {
|
|
253
|
-
console.log(
|
|
254
|
-
"[GallerySyncService] ❌ WiFi still disabled after all retries - user may need to tap sync manually",
|
|
255
|
-
)
|
|
256
|
-
this.waitingForWifiRetry = false
|
|
257
|
-
this.wifiSettingsOpenedAt = null // Clear cooldown timestamp
|
|
258
|
-
}
|
|
259
272
|
} catch (error) {
|
|
260
273
|
console.warn(`[GallerySyncService] Failed to check WiFi status on attempt ${attempt}:`, error)
|
|
261
274
|
// Continue to next retry
|
|
262
275
|
}
|
|
263
276
|
}
|
|
277
|
+
|
|
278
|
+
console.log("[GallerySyncService] WiFi not detected after retries - leaving sync available for manual retry")
|
|
279
|
+
this.waitingForWifiRetry = false
|
|
280
|
+
this.wifiSettingsOpenedAt = null
|
|
264
281
|
}
|
|
265
282
|
}
|
|
266
283
|
|
|
@@ -367,8 +384,10 @@ class GallerySyncService {
|
|
|
367
384
|
return this.syncStartPromise
|
|
368
385
|
}
|
|
369
386
|
|
|
387
|
+
useGallerySyncStore.getState().setSyncStarting(true)
|
|
370
388
|
this.syncStartPromise = this.runStartSync().finally(() => {
|
|
371
389
|
this.syncStartPromise = null
|
|
390
|
+
useGallerySyncStore.getState().setSyncStarting(false)
|
|
372
391
|
})
|
|
373
392
|
return this.syncStartPromise
|
|
374
393
|
}
|
|
@@ -491,9 +510,6 @@ class GallerySyncService {
|
|
|
491
510
|
hotspotEnabled: glassesHotspot !== null,
|
|
492
511
|
})
|
|
493
512
|
|
|
494
|
-
// Reset processing queue only after pre-flight passes — avoids clobbering an active session
|
|
495
|
-
mediaProcessingQueue.reset()
|
|
496
|
-
|
|
497
513
|
// Request all permissions upfront so user isn't interrupted during WiFi/download
|
|
498
514
|
console.log("[GallerySyncService] 🔐 Step 1/6: Requesting permissions...")
|
|
499
515
|
|
|
@@ -526,6 +542,23 @@ class GallerySyncService {
|
|
|
526
542
|
return
|
|
527
543
|
}
|
|
528
544
|
|
|
545
|
+
if (Platform.OS === "android") {
|
|
546
|
+
console.log("[GallerySyncService] 📡 Checking local WiFi permission...")
|
|
547
|
+
const hasLocalWifiPermission = await permissions.check(PermissionFeatures.LOCAL_WIFI)
|
|
548
|
+
if (!hasLocalWifiPermission) {
|
|
549
|
+
const granted = await permissions.request(PermissionFeatures.LOCAL_WIFI)
|
|
550
|
+
if (!granted) {
|
|
551
|
+
store.setSyncError("Local WiFi permission is required for gallery sync")
|
|
552
|
+
await gallerySyncNotifications.showSyncError("Allow WiFi access to connect to your glasses")
|
|
553
|
+
return
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (this.shouldAbortPreFlight()) {
|
|
557
|
+
console.log("[GallerySyncService] Pre-flight aborted after local WiFi permission")
|
|
558
|
+
return
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
529
562
|
// 3. Camera roll permission (if auto-save is enabled)
|
|
530
563
|
const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll()
|
|
531
564
|
console.log(`[GallerySyncService] 📸 Auto-save to camera roll: ${shouldAutoSave}`)
|
|
@@ -536,9 +569,10 @@ class GallerySyncService {
|
|
|
536
569
|
console.log("[GallerySyncService] ⚠️ Camera roll permission not granted - requesting...")
|
|
537
570
|
const granted = await MediaLibraryPermissions.requestPermission()
|
|
538
571
|
if (!granted) {
|
|
539
|
-
console.warn("[GallerySyncService] ❌ Camera roll permission denied -
|
|
540
|
-
|
|
541
|
-
|
|
572
|
+
console.warn("[GallerySyncService] ❌ Camera roll permission denied - auto-save sync cannot continue")
|
|
573
|
+
store.setSyncError("Camera-roll permission required while automatic saving is enabled")
|
|
574
|
+
emitGalleryNotice({code: "camera_roll_permission_required"})
|
|
575
|
+
return
|
|
542
576
|
} else {
|
|
543
577
|
console.log("[GallerySyncService] ✅ Camera roll permission granted")
|
|
544
578
|
}
|
|
@@ -739,12 +773,21 @@ class GallerySyncService {
|
|
|
739
773
|
console.log("[GallerySyncService] ➡️ Will request hotspot activation")
|
|
740
774
|
}
|
|
741
775
|
|
|
776
|
+
// Every fallible pre-flight gate has passed. It is now safe to replace the previous
|
|
777
|
+
// in-memory queue; startFileDownload immediately recovers its durable ledger work.
|
|
778
|
+
mediaProcessingQueue.reset()
|
|
779
|
+
|
|
742
780
|
if (isAlreadyConnected && currentGlassesHotspot) {
|
|
743
|
-
console.log("[GallerySyncService] 🚀 Skipping hotspot request - already connected!")
|
|
744
781
|
const hotspotInfo: HotspotInfo = currentGlassesHotspot
|
|
745
782
|
store.setHotspotInfo(hotspotInfo)
|
|
746
783
|
store.setSyncState("connecting_wifi")
|
|
747
|
-
|
|
784
|
+
if (localNetworkTransport.supportsScopedConnection() && !localNetworkTransport.isScopedConnectionActive()) {
|
|
785
|
+
console.log("[GallerySyncService] 📡 System SSID matches; establishing scoped glasses transport")
|
|
786
|
+
await this.connectToHotspotWifi(hotspotInfo)
|
|
787
|
+
} else {
|
|
788
|
+
console.log("[GallerySyncService] 🚀 Skipping hotspot request - already connected!")
|
|
789
|
+
await this.startFileDownload(hotspotInfo)
|
|
790
|
+
}
|
|
748
791
|
return
|
|
749
792
|
}
|
|
750
793
|
|
|
@@ -900,7 +943,7 @@ class GallerySyncService {
|
|
|
900
943
|
console.log(`[GallerySyncService] 📡 Current WiFi SSID: "${preConnectSSID}"`)
|
|
901
944
|
|
|
902
945
|
// Check if already connected (shouldn't happen, but good to verify)
|
|
903
|
-
if (preConnectSSID === hotspotInfo.ssid) {
|
|
946
|
+
if (!localNetworkTransport.supportsScopedConnection() && preConnectSSID === hotspotInfo.ssid) {
|
|
904
947
|
console.log("[GallerySyncService] ✅ Already connected to target SSID! Proceeding to download.")
|
|
905
948
|
appStateSubscription.remove()
|
|
906
949
|
|
|
@@ -919,8 +962,7 @@ class GallerySyncService {
|
|
|
919
962
|
console.warn("[GallerySyncService] ⚠️ Error code:", preError?.code)
|
|
920
963
|
}
|
|
921
964
|
|
|
922
|
-
|
|
923
|
-
console.log(`[GallerySyncService] 🔌 Calling WifiManager.connectToProtectedSSID...`)
|
|
965
|
+
console.log(`[GallerySyncService] 🔌 Connecting the glasses-local transport...`)
|
|
924
966
|
console.log(`[GallerySyncService] 🔌 Parameters:`)
|
|
925
967
|
console.log(`[GallerySyncService] - SSID: "${hotspotInfo.ssid}"`)
|
|
926
968
|
console.log(`[GallerySyncService] - Password: ${"*".repeat(hotspotInfo.password.length)}`)
|
|
@@ -931,10 +973,10 @@ class GallerySyncService {
|
|
|
931
973
|
appBackgrounded = false // Reset flag for this attempt
|
|
932
974
|
appBackgroundTime = null
|
|
933
975
|
|
|
934
|
-
await
|
|
976
|
+
await localNetworkTransport.connect(hotspotInfo.ssid, hotspotInfo.password)
|
|
935
977
|
|
|
936
978
|
const connectCallDuration = Date.now() - connectCallStartTime
|
|
937
|
-
console.log(`[GallerySyncService] ✅
|
|
979
|
+
console.log(`[GallerySyncService] ✅ Glasses-local transport connected successfully`)
|
|
938
980
|
console.log(`[GallerySyncService] ⏱️ Library call duration: ${connectCallDuration}ms`)
|
|
939
981
|
console.log(`[GallerySyncService] 📱 App was backgrounded during call: ${appBackgrounded}`)
|
|
940
982
|
if (appBackgrounded && appBackgroundTime) {
|
|
@@ -960,9 +1002,9 @@ class GallerySyncService {
|
|
|
960
1002
|
lastSeenSSID = currentSSID || "null"
|
|
961
1003
|
|
|
962
1004
|
console.log(
|
|
963
|
-
`[GallerySyncService] 🍎 Verify poll ${
|
|
964
|
-
|
|
965
|
-
}"`,
|
|
1005
|
+
`[GallerySyncService] 🍎 Verify poll ${
|
|
1006
|
+
i + 1
|
|
1007
|
+
}/${maxVerifyAttempts}: Current="${currentSSID}", Target="${hotspotInfo.ssid}"`,
|
|
966
1008
|
)
|
|
967
1009
|
|
|
968
1010
|
if (currentSSID === hotspotInfo.ssid) {
|
|
@@ -1014,7 +1056,9 @@ class GallerySyncService {
|
|
|
1014
1056
|
|
|
1015
1057
|
// Final verification: Check SSID one more time before starting download
|
|
1016
1058
|
try {
|
|
1017
|
-
const finalSSID =
|
|
1059
|
+
const finalSSID = localNetworkTransport.isScopedConnectionActive()
|
|
1060
|
+
? hotspotInfo.ssid
|
|
1061
|
+
: await WifiManager.getCurrentWifiSSID()
|
|
1018
1062
|
console.log(`[GallerySyncService] 📶 Final SSID check before download: "${finalSSID}"`)
|
|
1019
1063
|
if (Platform.OS === "android") {
|
|
1020
1064
|
// Some local builds can have stale generated typings for the Bluetooth SDK module.
|
|
@@ -1050,7 +1094,7 @@ class GallerySyncService {
|
|
|
1050
1094
|
const probeTimeout = BgTimer.setTimeout(() => probeController.abort(), 1000) // 1 second timeout per probe
|
|
1051
1095
|
|
|
1052
1096
|
const probeStartTime = Date.now()
|
|
1053
|
-
const probeResponse = await fetch(`http://${hotspotInfo.ip}:8089/api/health`, {
|
|
1097
|
+
const probeResponse = await localNetworkTransport.fetch(`http://${hotspotInfo.ip}:8089/api/health`, {
|
|
1054
1098
|
method: "GET",
|
|
1055
1099
|
signal: probeController.signal,
|
|
1056
1100
|
})
|
|
@@ -1252,14 +1296,49 @@ class GallerySyncService {
|
|
|
1252
1296
|
await this.closeHotspot()
|
|
1253
1297
|
}
|
|
1254
1298
|
} finally {
|
|
1299
|
+
// Release the scoped Android Network on every terminal path. This is idempotent with
|
|
1300
|
+
// closeHotspot(), and intentionally leaves Android 9/iOS legacy routing unchanged.
|
|
1301
|
+
await localNetworkTransport.disconnect()
|
|
1255
1302
|
// L2: Guarantee listener cleanup on all exit paths (cancel, success, error, exhaustion)
|
|
1256
1303
|
appStateSubscription.remove()
|
|
1257
1304
|
}
|
|
1258
1305
|
}
|
|
1259
1306
|
|
|
1260
1307
|
private async fetchSyncManifest(clientId: string, lastSyncTime: number): Promise<SyncManifestData> {
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1308
|
+
const v3 = typeof asgCameraApi.getV3Manifest === "function" ? await asgCameraApi.getV3Manifest() : null
|
|
1309
|
+
if (v3) {
|
|
1310
|
+
const downloadedFiles = await localStorageService.getDownloadedFiles()
|
|
1311
|
+
await localStorageService.reconcileRemoteCaptures(
|
|
1312
|
+
v3.captures.map((capture) => capture.capture_id),
|
|
1313
|
+
downloadedFiles,
|
|
1314
|
+
)
|
|
1315
|
+
return {
|
|
1316
|
+
api_version: 3,
|
|
1317
|
+
client_id: clientId,
|
|
1318
|
+
// The ledger is a crash-recovery journal, not proof that app-private media survived an
|
|
1319
|
+
// Android restore or reinstall. Suppress a remote capture only when both records agree.
|
|
1320
|
+
captures: v3.captures.filter(
|
|
1321
|
+
(capture) =>
|
|
1322
|
+
!downloadedFiles[capture.capture_id] || !galleryTransferLedger.isLocallyCommitted(capture.capture_id),
|
|
1323
|
+
),
|
|
1324
|
+
changed_files: [],
|
|
1325
|
+
deleted_files: [],
|
|
1326
|
+
server_time: v3.server_time,
|
|
1327
|
+
total_changed: v3.captures.length,
|
|
1328
|
+
total_size: v3.captures.reduce((total, capture) => total + capture.total_size, 0),
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
// Old firmware remains on the exact v2 endpoint/schema. Avoid expensive inline thumbnails;
|
|
1332
|
+
// video thumbnails are fetched as small side downloads with their primary media.
|
|
1333
|
+
const syncResponse = await asgCameraApi.syncWithServer(clientId, lastSyncTime, false)
|
|
1334
|
+
const data = (syncResponse.data || syncResponse) as SyncManifestData
|
|
1335
|
+
if (data.captures) {
|
|
1336
|
+
data.captures = data.captures.filter((capture) => !galleryTransferLedger.isLocallyCommitted(capture.capture_id))
|
|
1337
|
+
}
|
|
1338
|
+
data.changed_files = (data.changed_files || []).filter(
|
|
1339
|
+
(file) => !galleryTransferLedger.isFileLocallyCommitted(file.name),
|
|
1340
|
+
)
|
|
1341
|
+
return data
|
|
1263
1342
|
}
|
|
1264
1343
|
|
|
1265
1344
|
/**
|
|
@@ -1328,6 +1407,13 @@ class GallerySyncService {
|
|
|
1328
1407
|
asgCameraApi.setServer(hotspotInfo.ip, 8089)
|
|
1329
1408
|
console.log("[GallerySyncService] ✅ API client configured")
|
|
1330
1409
|
|
|
1410
|
+
const recovery = await mediaProcessingQueue.retryPending()
|
|
1411
|
+
if (recovery.retried > 0 || recovery.failed > 0) {
|
|
1412
|
+
console.log(
|
|
1413
|
+
`[GallerySyncService] ♻️ Recovery: ${recovery.retried} completed, ${recovery.failed} still pending`,
|
|
1414
|
+
)
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1331
1417
|
// Get sync state and files to download
|
|
1332
1418
|
// IMPORTANT: This creates a SNAPSHOT of files at this moment based on last_sync_time.
|
|
1333
1419
|
// Any photos taken AFTER this call (during the sync) will NOT be included in this sync.
|
|
@@ -1367,18 +1453,24 @@ class GallerySyncService {
|
|
|
1367
1453
|
|
|
1368
1454
|
if (isSyncManifestEmpty(syncData)) {
|
|
1369
1455
|
console.log("[GallerySyncService] ✅ No new files to sync - already up to date!")
|
|
1370
|
-
|
|
1456
|
+
if (galleryTransferLedger.hasPendingRecovery()) {
|
|
1457
|
+
store.setSyncError("Gallery export or acknowledgement needs retry")
|
|
1458
|
+
} else {
|
|
1459
|
+
store.setSyncComplete()
|
|
1460
|
+
}
|
|
1371
1461
|
await this.onSyncComplete(0, 0)
|
|
1372
1462
|
return
|
|
1373
1463
|
}
|
|
1374
1464
|
|
|
1375
1465
|
// Detect API version and route to appropriate download path
|
|
1376
|
-
const useCaptures = syncData.api_version
|
|
1466
|
+
const useCaptures = (syncData.api_version || 0) >= 2 && syncData.captures && syncData.captures.length > 0
|
|
1377
1467
|
|
|
1378
1468
|
if (useCaptures) {
|
|
1379
1469
|
// New capture-aware sync path
|
|
1380
1470
|
const captures: CaptureGroup[] = syncData.captures!
|
|
1381
|
-
console.log(
|
|
1471
|
+
console.log(
|
|
1472
|
+
`[GallerySyncService] 📊 Found ${captures.length} captures to download (api_version=${syncData.api_version})`,
|
|
1473
|
+
)
|
|
1382
1474
|
|
|
1383
1475
|
captures.slice(0, 5).forEach((c: CaptureGroup, idx: number) => {
|
|
1384
1476
|
console.log(
|
|
@@ -1500,7 +1592,7 @@ class GallerySyncService {
|
|
|
1500
1592
|
(current, total, fileName, fileProgress, downloadedFile) => {
|
|
1501
1593
|
// CRITICAL: This callback MUST NOT throw!
|
|
1502
1594
|
// RNFS progress callbacks run inside native bridge — throwing here causes
|
|
1503
|
-
// EXC_BAD_ACCESS. Cancellation is handled via AbortSignal →
|
|
1595
|
+
// EXC_BAD_ACCESS. Cancellation is handled via AbortSignal → the active transport.
|
|
1504
1596
|
|
|
1505
1597
|
// Check if cancelled — just return, abort signal will stop the download
|
|
1506
1598
|
if (this.abortController?.signal.aborted) {
|
|
@@ -1597,6 +1689,7 @@ class GallerySyncService {
|
|
|
1597
1689
|
shouldAutoSave: !!shouldAutoSave,
|
|
1598
1690
|
thumbnailPath: downloadedFile.thumbnailPath,
|
|
1599
1691
|
deleteFromGlasses: [downloadedFile.name],
|
|
1692
|
+
protocolVersion: 1,
|
|
1600
1693
|
})
|
|
1601
1694
|
}
|
|
1602
1695
|
}
|
|
@@ -1634,25 +1727,6 @@ class GallerySyncService {
|
|
|
1634
1727
|
}
|
|
1635
1728
|
}
|
|
1636
1729
|
|
|
1637
|
-
// Save downloaded files metadata (skip auxiliary files from gallery entries)
|
|
1638
|
-
for (const photoInfo of downloadResult.downloaded) {
|
|
1639
|
-
// Skip HDR brackets and IMU sidecars — they shouldn't appear as separate gallery items
|
|
1640
|
-
const isAuxiliary =
|
|
1641
|
-
photoInfo.name?.match(/_ev-?\d+\.(jpg|jpeg)$/i) ||
|
|
1642
|
-
photoInfo.name?.match(/\.imu\.json$/i) ||
|
|
1643
|
-
photoInfo.name?.match(/\/ev-?\d+\.jpe?g$/i) ||
|
|
1644
|
-
photoInfo.name?.match(/\/imu\.json$/i)
|
|
1645
|
-
if (isAuxiliary) continue
|
|
1646
|
-
|
|
1647
|
-
const downloadedFile = localStorageService.convertToDownloadedFile(
|
|
1648
|
-
photoInfo,
|
|
1649
|
-
photoInfo.filePath || "",
|
|
1650
|
-
photoInfo.thumbnailPath,
|
|
1651
|
-
defaultWearable,
|
|
1652
|
-
)
|
|
1653
|
-
await localStorageService.saveDownloadedFile(downloadedFile)
|
|
1654
|
-
}
|
|
1655
|
-
|
|
1656
1730
|
// Update queue index to final position
|
|
1657
1731
|
await localStorageService.updateSyncQueueIndex(files.length)
|
|
1658
1732
|
|
|
@@ -1667,6 +1741,17 @@ class GallerySyncService {
|
|
|
1667
1741
|
await mediaProcessingQueue.waitUntilDrained()
|
|
1668
1742
|
console.log("[GallerySyncService] ✅ Processing queue drained")
|
|
1669
1743
|
|
|
1744
|
+
// Download success is not destination success. Export, validation, metadata, and
|
|
1745
|
+
// acknowledgement failures are reported asynchronously by the processing queue; fold them
|
|
1746
|
+
// back into the legacy result so its timestamp watermark cannot skip the source forever.
|
|
1747
|
+
const processingFailures = new Set(useGallerySyncStore.getState().failedFiles)
|
|
1748
|
+
for (const file of files) {
|
|
1749
|
+
if (processingFailures.has(file.name) && !downloadResult.failed.includes(file.name)) {
|
|
1750
|
+
downloadResult.failed.push(file.name)
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
failedCount = downloadResult.failed.length
|
|
1754
|
+
|
|
1670
1755
|
// Update sync state — only advance watermark if files were downloaded.
|
|
1671
1756
|
// If any failed, set it before the oldest failure so they get retried.
|
|
1672
1757
|
let syncWatermark = serverTime
|
|
@@ -1730,8 +1815,11 @@ class GallerySyncService {
|
|
|
1730
1815
|
).toFixed(2)} MB`,
|
|
1731
1816
|
)
|
|
1732
1817
|
|
|
1733
|
-
|
|
1734
|
-
|
|
1818
|
+
if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {
|
|
1819
|
+
store.setSyncError(`${failedCount || "Some"} gallery items need retry`)
|
|
1820
|
+
} else {
|
|
1821
|
+
store.setSyncComplete()
|
|
1822
|
+
}
|
|
1735
1823
|
await this.onSyncComplete(downloadedCount, failedCount)
|
|
1736
1824
|
} catch (error: any) {
|
|
1737
1825
|
mediaProcessingQueue.abort()
|
|
@@ -1795,7 +1883,9 @@ class GallerySyncService {
|
|
|
1795
1883
|
|
|
1796
1884
|
try {
|
|
1797
1885
|
console.log(
|
|
1798
|
-
`[GallerySyncService] 📦 Downloading capture ${i + 1}/${captures.length}: ${capture.capture_id} (${
|
|
1886
|
+
`[GallerySyncService] 📦 Downloading capture ${i + 1}/${captures.length}: ${capture.capture_id} (${
|
|
1887
|
+
capture.files.length
|
|
1888
|
+
} files)`,
|
|
1799
1889
|
)
|
|
1800
1890
|
|
|
1801
1891
|
validateCaptureMetadataForDownload(capture)
|
|
@@ -1833,6 +1923,7 @@ class GallerySyncService {
|
|
|
1833
1923
|
bracketPaths: result.bracketPaths,
|
|
1834
1924
|
sidecarPath: result.sidecarPath,
|
|
1835
1925
|
thumbnailData: capture.thumbnail_data,
|
|
1926
|
+
thumbnailPath: result.thumbnailPath,
|
|
1836
1927
|
captureDir: result.captureDir,
|
|
1837
1928
|
timestamp: capture.timestamp,
|
|
1838
1929
|
totalSize: capture.total_size,
|
|
@@ -1841,6 +1932,7 @@ class GallerySyncService {
|
|
|
1841
1932
|
shouldProcess: !!shouldProcessImages,
|
|
1842
1933
|
shouldAutoSave: !!shouldAutoSave,
|
|
1843
1934
|
deleteFromGlasses: [capture.capture_id],
|
|
1935
|
+
protocolVersion: capture.files.some((file) => !!file.etag) ? 3 : 2,
|
|
1844
1936
|
})
|
|
1845
1937
|
} catch (captureError: any) {
|
|
1846
1938
|
if (captureError?.message === "Sync cancelled") throw captureError
|
|
@@ -1929,7 +2021,11 @@ class GallerySyncService {
|
|
|
1929
2021
|
})
|
|
1930
2022
|
}
|
|
1931
2023
|
|
|
1932
|
-
|
|
2024
|
+
if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {
|
|
2025
|
+
store.setSyncError(`${failedCount || "Some"} gallery items need retry`)
|
|
2026
|
+
} else {
|
|
2027
|
+
store.setSyncComplete()
|
|
2028
|
+
}
|
|
1933
2029
|
await this.onSyncComplete(downloadedCount, failedCount)
|
|
1934
2030
|
} catch (error: any) {
|
|
1935
2031
|
mediaProcessingQueue.abort()
|
|
@@ -1993,13 +2089,25 @@ class GallerySyncService {
|
|
|
1993
2089
|
// console.error(`[GallerySyncService] Failed to get post-sync inventory:`, error)
|
|
1994
2090
|
// }
|
|
1995
2091
|
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2092
|
+
const hasPendingRecovery = galleryTransferLedger.hasPendingRecovery()
|
|
2093
|
+
if (!hasPendingRecovery && failedCount === 0) {
|
|
2094
|
+
console.log("[GallerySyncService] 🧹 Clearing completed sync queue...")
|
|
2095
|
+
await localStorageService.clearSyncQueue()
|
|
2096
|
+
} else {
|
|
2097
|
+
console.log("[GallerySyncService] ♻️ Keeping recovery state for unfinished export/ack work")
|
|
2098
|
+
}
|
|
1999
2099
|
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2100
|
+
if (hasPendingRecovery || failedCount > 0) {
|
|
2101
|
+
console.log("[GallerySyncService] 📱 Showing retry-required notification...")
|
|
2102
|
+
await gallerySyncNotifications.showSyncError(
|
|
2103
|
+
failedCount > 0
|
|
2104
|
+
? `${failedCount} gallery item${failedCount === 1 ? "" : "s"} will be retried`
|
|
2105
|
+
: "Gallery export or acknowledgement will be retried",
|
|
2106
|
+
)
|
|
2107
|
+
} else {
|
|
2108
|
+
console.log("[GallerySyncService] 📱 Showing completion notification...")
|
|
2109
|
+
await gallerySyncNotifications.showSyncComplete(downloadedCount, 0)
|
|
2110
|
+
}
|
|
2003
2111
|
|
|
2004
2112
|
// Close hotspot if we opened it
|
|
2005
2113
|
const store = useGallerySyncStore.getState()
|
|
@@ -2013,8 +2121,10 @@ class GallerySyncService {
|
|
|
2013
2121
|
// Clear glasses gallery count immediately after successful sync
|
|
2014
2122
|
// This ensures UI shows 0 items remaining right away
|
|
2015
2123
|
// The subsequent query will update this if new photos were taken during sync
|
|
2016
|
-
|
|
2017
|
-
|
|
2124
|
+
if (!hasPendingRecovery && failedCount === 0) {
|
|
2125
|
+
console.log("[GallerySyncService] 🔄 Clearing glasses gallery count (synced all items)")
|
|
2126
|
+
store.clearGlassesGalleryStatus()
|
|
2127
|
+
}
|
|
2018
2128
|
|
|
2019
2129
|
// Auto-reset to idle after 4 seconds to clear "Sync complete!" message,
|
|
2020
2130
|
// then query glasses for any new content taken during the sync.
|
|
@@ -2082,6 +2192,7 @@ class GallerySyncService {
|
|
|
2082
2192
|
|
|
2083
2193
|
try {
|
|
2084
2194
|
console.log("[GallerySyncService] Closing hotspot...")
|
|
2195
|
+
await localNetworkTransport.disconnect()
|
|
2085
2196
|
await BluetoothSdk.setHotspotState(false)
|
|
2086
2197
|
store.setSyncServiceOpenedHotspot(false)
|
|
2087
2198
|
store.setHotspotInfo(null)
|
|
@@ -2149,7 +2260,7 @@ class GallerySyncService {
|
|
|
2149
2260
|
|
|
2150
2261
|
/** True while pre-flight startSync work is in flight (before sync state transitions). */
|
|
2151
2262
|
isSyncStarting(): boolean {
|
|
2152
|
-
return
|
|
2263
|
+
return useGallerySyncStore.getState().syncStarting
|
|
2153
2264
|
}
|
|
2154
2265
|
|
|
2155
2266
|
/**
|