@mentra/engine 0.1.0-dev.0 → 0.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -1
- package/build/engine.d.ts +11 -3
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +7 -2
- package/build/engine.js.map +1 -1
- package/build/facades/dev.d.ts +3 -2
- package/build/facades/dev.d.ts.map +1 -1
- package/build/facades/dev.js +18 -12
- package/build/facades/dev.js.map +1 -1
- package/build/facades/gallery.js +1 -1
- package/build/facades/gallery.js.map +1 -1
- package/build/facades/glasses.d.ts +1 -0
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +19 -4
- package/build/facades/glasses.js.map +1 -1
- package/build/facades/glassesSettings.d.ts.map +1 -1
- package/build/facades/glassesSettings.js +1 -0
- package/build/facades/glassesSettings.js.map +1 -1
- package/build/facades/miniapps.d.ts +4 -0
- package/build/facades/miniapps.d.ts.map +1 -1
- package/build/facades/miniapps.js +5 -0
- package/build/facades/miniapps.js.map +1 -1
- package/build/facades/ota.d.ts +11 -2
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +19 -4
- package/build/facades/ota.js.map +1 -1
- package/build/facades/pairing.d.ts +4 -0
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +10 -8
- package/build/facades/pairing.js.map +1 -1
- package/build/facades/permissions.d.ts +10 -0
- package/build/facades/permissions.d.ts.map +1 -1
- package/build/facades/permissions.js +10 -0
- package/build/facades/permissions.js.map +1 -1
- package/build/facades/phoneNotifications.d.ts +0 -4
- package/build/facades/phoneNotifications.d.ts.map +1 -1
- package/build/facades/phoneNotifications.js +4 -14
- package/build/facades/phoneNotifications.js.map +1 -1
- package/build/index.d.ts +6 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -2
- package/build/index.js.map +1 -1
- package/build/internal.d.ts +3 -2
- package/build/internal.d.ts.map +1 -1
- package/build/internal.js +2 -1
- package/build/internal.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.d.ts +38 -0
- package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
- package/build/react/MentraLiveOtaFlow.js +528 -0
- package/build/react/MentraLiveOtaFlow.js.map +1 -0
- package/build/react/index.d.ts +2 -0
- package/build/react/index.d.ts.map +1 -0
- package/build/react/index.js +2 -0
- package/build/react/index.js.map +1 -0
- package/build/react/useEngineSnapshot.d.ts +2 -0
- package/build/react/useEngineSnapshot.d.ts.map +1 -0
- package/build/react/useEngineSnapshot.js +14 -0
- package/build/react/useEngineSnapshot.js.map +1 -0
- package/build/runtime/bootstrap.d.ts +24 -1
- package/build/runtime/bootstrap.d.ts.map +1 -1
- package/build/runtime/bootstrap.js +17 -0
- package/build/runtime/bootstrap.js.map +1 -1
- package/build/runtime/scanQrSeam.d.ts +7 -0
- package/build/runtime/scanQrSeam.d.ts.map +1 -0
- package/build/runtime/scanQrSeam.js +16 -0
- package/build/runtime/scanQrSeam.js.map +1 -0
- package/build/services/AppRegistry.d.ts +33 -57
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +193 -144
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/AudioCloudUplink.d.ts +12 -0
- package/build/services/AudioCloudUplink.d.ts.map +1 -1
- package/build/services/AudioCloudUplink.js +22 -1
- package/build/services/AudioCloudUplink.js.map +1 -1
- package/build/services/AudioPlaybackService.d.ts +41 -2
- package/build/services/AudioPlaybackService.d.ts.map +1 -1
- package/build/services/AudioPlaybackService.js +250 -33
- package/build/services/AudioPlaybackService.js.map +1 -1
- package/build/services/BlobStore.d.ts +2 -1
- package/build/services/BlobStore.d.ts.map +1 -1
- package/build/services/BlobStore.js +17 -9
- package/build/services/BlobStore.js.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.js +13 -1
- package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
- package/build/services/CloudClientService.d.ts +15 -0
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +93 -1
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DeviceEventRouter.js +5 -5
- package/build/services/DeviceEventRouter.js.map +1 -1
- package/build/services/ForegroundLocationPermission.d.ts +13 -0
- package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
- package/build/services/ForegroundLocationPermission.js +12 -0
- package/build/services/ForegroundLocationPermission.js.map +1 -0
- package/build/services/GlassesSettingsSync.d.ts.map +1 -1
- package/build/services/GlassesSettingsSync.js +9 -3
- package/build/services/GlassesSettingsSync.js.map +1 -1
- package/build/services/GlassesStatusProjection.d.ts +2 -1
- package/build/services/GlassesStatusProjection.d.ts.map +1 -1
- package/build/services/GlassesStatusProjection.js +15 -8
- package/build/services/GlassesStatusProjection.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts +29 -0
- package/build/services/HotspotOtaTransport.d.ts.map +1 -0
- package/build/services/HotspotOtaTransport.js +146 -0
- package/build/services/HotspotOtaTransport.js.map +1 -0
- package/build/services/HotspotShutdown.d.ts +17 -0
- package/build/services/HotspotShutdown.d.ts.map +1 -0
- package/build/services/HotspotShutdown.js +29 -0
- package/build/services/HotspotShutdown.js.map +1 -0
- package/build/services/LocalDisplayManager.d.ts +15 -0
- package/build/services/LocalDisplayManager.d.ts.map +1 -1
- package/build/services/LocalDisplayManager.js +106 -20
- package/build/services/LocalDisplayManager.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +74 -2
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +785 -291
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalMiniappStorage.d.ts +32 -0
- package/build/services/LocalMiniappStorage.d.ts.map +1 -0
- package/build/services/LocalMiniappStorage.js +66 -0
- package/build/services/LocalMiniappStorage.js.map +1 -0
- package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
- package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
- package/build/services/LocalMiniappUserIdentity.js +43 -0
- package/build/services/LocalMiniappUserIdentity.js.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js +18 -12
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/MicStateCoordinator.d.ts +42 -1
- package/build/services/MicStateCoordinator.d.ts.map +1 -1
- package/build/services/MicStateCoordinator.js +141 -3
- package/build/services/MicStateCoordinator.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +23 -3
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/MiniappLiveness.d.ts +12 -0
- package/build/services/MiniappLiveness.d.ts.map +1 -0
- package/build/services/MiniappLiveness.js +16 -0
- package/build/services/MiniappLiveness.js.map +1 -0
- package/build/services/NativeHttpResponse.d.ts +3 -0
- package/build/services/NativeHttpResponse.d.ts.map +1 -0
- package/build/services/NativeHttpResponse.js +6 -0
- package/build/services/NativeHttpResponse.js.map +1 -0
- package/build/services/OtaArtifactDownloader.d.ts +65 -0
- package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
- package/build/services/OtaArtifactDownloader.js +226 -0
- package/build/services/OtaArtifactDownloader.js.map +1 -0
- package/build/services/OtaAutoChain.d.ts +34 -0
- package/build/services/OtaAutoChain.d.ts.map +1 -0
- package/build/services/OtaAutoChain.js +83 -0
- package/build/services/OtaAutoChain.js.map +1 -0
- package/build/services/OtaErrorMapping.d.ts +18 -0
- package/build/services/OtaErrorMapping.d.ts.map +1 -0
- package/build/services/OtaErrorMapping.js +63 -0
- package/build/services/OtaErrorMapping.js.map +1 -0
- package/build/services/OtaInstallCoordinator.d.ts +94 -14
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +574 -130
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/OtaService.d.ts.map +1 -1
- package/build/services/OtaService.js +8 -1
- package/build/services/OtaService.js.map +1 -1
- package/build/services/OtaUpdateCheckService.d.ts +38 -3
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +142 -22
- package/build/services/OtaUpdateCheckService.js.map +1 -1
- package/build/services/PhoneCalendarHelpers.d.ts +32 -0
- package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
- package/build/services/PhoneCalendarHelpers.js +157 -0
- package/build/services/PhoneCalendarHelpers.js.map +1 -0
- package/build/services/PhoneCalendarService.d.ts +5 -0
- package/build/services/PhoneCalendarService.d.ts.map +1 -0
- package/build/services/PhoneCalendarService.js +45 -0
- package/build/services/PhoneCalendarService.js.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.js +194 -0
- package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +12 -10
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts +26 -2
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
- package/build/services/PhonePhotoCoordinator.js +79 -9
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts +8 -1
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
- package/build/services/PhoneStreamCoordinator.js +125 -13
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/PhoneVideoCoordinator.d.ts +2 -0
- package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
- package/build/services/PhoneVideoCoordinator.js +10 -0
- package/build/services/PhoneVideoCoordinator.js.map +1 -1
- package/build/services/SceneRenderer.d.ts.map +1 -1
- package/build/services/SceneRenderer.js +15 -0
- package/build/services/SceneRenderer.js.map +1 -1
- package/build/services/SentenceTtsPipeline.d.ts +31 -0
- package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
- package/build/services/SentenceTtsPipeline.js +67 -0
- package/build/services/SentenceTtsPipeline.js.map +1 -0
- package/build/services/SupportProfileSync.d.ts +22 -0
- package/build/services/SupportProfileSync.d.ts.map +1 -0
- package/build/services/SupportProfileSync.js +213 -0
- package/build/services/SupportProfileSync.js.map +1 -0
- package/build/services/TranscriptionRouting.d.ts +12 -0
- package/build/services/TranscriptionRouting.d.ts.map +1 -0
- package/build/services/TranscriptionRouting.js +24 -0
- package/build/services/TranscriptionRouting.js.map +1 -0
- package/build/services/TtsTextSanitizer.d.ts +5 -0
- package/build/services/TtsTextSanitizer.d.ts.map +1 -0
- package/build/services/TtsTextSanitizer.js +61 -0
- package/build/services/TtsTextSanitizer.js.map +1 -0
- package/build/services/WifiAdbRequest.d.ts +17 -0
- package/build/services/WifiAdbRequest.d.ts.map +1 -0
- package/build/services/WifiAdbRequest.js +35 -0
- package/build/services/WifiAdbRequest.js.map +1 -0
- package/build/services/asg/asgCameraApi.d.ts +43 -0
- package/build/services/asg/asgCameraApi.d.ts.map +1 -1
- package/build/services/asg/asgCameraApi.js +509 -26
- package/build/services/asg/asgCameraApi.js.map +1 -1
- package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
- package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportCoordinator.js +618 -0
- package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
- package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
- package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportLedger.js +78 -0
- package/build/services/asg/cameraRollExportLedger.js.map +1 -0
- package/build/services/asg/galleryNotices.d.ts +1 -1
- package/build/services/asg/galleryNotices.d.ts.map +1 -1
- package/build/services/asg/galleryNotices.js.map +1 -1
- package/build/services/asg/galleryPathMigration.d.ts +3 -0
- package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
- package/build/services/asg/galleryPathMigration.js +26 -0
- package/build/services/asg/galleryPathMigration.js.map +1 -0
- package/build/services/asg/gallerySettingsService.d.ts +1 -0
- package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
- package/build/services/asg/gallerySettingsService.js +2 -0
- package/build/services/asg/gallerySettingsService.js.map +1 -1
- package/build/services/asg/gallerySyncService.d.ts.map +1 -1
- package/build/services/asg/gallerySyncService.js +162 -56
- package/build/services/asg/gallerySyncService.js.map +1 -1
- package/build/services/asg/galleryTransferLedger.d.ts +58 -0
- package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
- package/build/services/asg/galleryTransferLedger.js +225 -0
- package/build/services/asg/galleryTransferLedger.js.map +1 -0
- package/build/services/asg/localNetworkTransport.d.ts +15 -0
- package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
- package/build/services/asg/localNetworkTransport.js +144 -0
- package/build/services/asg/localNetworkTransport.js.map +1 -0
- package/build/services/asg/localStorageService.d.ts +18 -0
- package/build/services/asg/localStorageService.d.ts.map +1 -1
- package/build/services/asg/localStorageService.js +168 -19
- package/build/services/asg/localStorageService.js.map +1 -1
- package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
- package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
- package/build/services/asg/mediaProcessingQueue.js +193 -62
- package/build/services/asg/mediaProcessingQueue.js.map +1 -1
- package/build/services/audioPlaybackAssets.d.ts +8 -0
- package/build/services/audioPlaybackAssets.d.ts.map +1 -0
- package/build/services/audioPlaybackAssets.js +7 -0
- package/build/services/audioPlaybackAssets.js.map +1 -0
- package/build/services/gallerySyncClock.js +1 -1
- package/build/services/gallerySyncClock.js.map +1 -1
- package/build/services/glassesClockSync.js +2 -2
- package/build/services/glassesClockSync.js.map +1 -1
- package/build/services/manifestActions.d.ts +7 -0
- package/build/services/manifestActions.d.ts.map +1 -0
- package/build/services/manifestActions.js +25 -0
- package/build/services/manifestActions.js.map +1 -0
- package/build/services/otaDisplayState.d.ts +22 -11
- package/build/services/otaDisplayState.d.ts.map +1 -1
- package/build/services/otaDisplayState.js +36 -14
- package/build/services/otaDisplayState.js.map +1 -1
- package/build/services/otaInstallPolicy.d.ts +15 -3
- package/build/services/otaInstallPolicy.d.ts.map +1 -1
- package/build/services/otaInstallPolicy.js +24 -3
- package/build/services/otaInstallPolicy.js.map +1 -1
- package/build/services/otaManifestUrl.d.ts +2 -0
- package/build/services/otaManifestUrl.d.ts.map +1 -0
- package/build/services/{asgOtaVersionUrl.js → otaManifestUrl.js} +15 -5
- package/build/services/otaManifestUrl.js.map +1 -0
- package/build/services/slimStreamStatus.d.ts +11 -0
- package/build/services/slimStreamStatus.d.ts.map +1 -1
- package/build/services/slimStreamStatus.js +14 -4
- package/build/services/slimStreamStatus.js.map +1 -1
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +11 -0
- package/build/stores/apps.js.map +1 -1
- package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
- package/build/stores/bluetoothSettingKeys.js +2 -0
- package/build/stores/bluetoothSettingKeys.js.map +1 -1
- package/build/stores/gallerySync.d.ts +2 -0
- package/build/stores/gallerySync.d.ts.map +1 -1
- package/build/stores/gallerySync.js +2 -0
- package/build/stores/gallerySync.js.map +1 -1
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js +3 -0
- package/build/stores/glasses.js.map +1 -1
- package/build/stores/settings.d.ts +17 -0
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +157 -17
- package/build/stores/settings.js.map +1 -1
- package/build/types/applet.d.ts +2 -0
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/build/types/asg.d.ts +7 -0
- package/build/types/asg.d.ts.map +1 -1
- package/build/types/asg.js.map +1 -1
- package/build/types/enums.d.ts +1 -0
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +1 -0
- package/build/types/enums.js.map +1 -1
- package/build/types/hardware.d.ts +1 -0
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +14 -0
- package/build/types/hardware.js.map +1 -1
- package/build/utils/configuredDevHost.d.ts +6 -0
- package/build/utils/configuredDevHost.d.ts.map +1 -0
- package/build/utils/configuredDevHost.js +19 -0
- package/build/utils/configuredDevHost.js.map +1 -0
- package/build/utils/devMiniappLaunch.d.ts +19 -8
- package/build/utils/devMiniappLaunch.d.ts.map +1 -1
- package/build/utils/devMiniappLaunch.js +144 -21
- package/build/utils/devMiniappLaunch.js.map +1 -1
- package/build/utils/diagnosticContext.d.ts.map +1 -1
- package/build/utils/diagnosticContext.js +15 -17
- package/build/utils/diagnosticContext.js.map +1 -1
- package/build/utils/hardware/hardware.d.ts.map +1 -1
- package/build/utils/hardware/hardware.js +7 -3
- package/build/utils/hardware/hardware.js.map +1 -1
- package/build/utils/miniappDiagnostics.d.ts +64 -0
- package/build/utils/miniappDiagnostics.d.ts.map +1 -0
- package/build/utils/miniappDiagnostics.js +173 -0
- package/build/utils/miniappDiagnostics.js.map +1 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
- package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
- package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
- package/build/utils/timers/timers.d.ts.map +1 -1
- package/build/utils/timers/timers.js +55 -18
- package/build/utils/timers/timers.js.map +1 -1
- package/package.json +25 -15
- package/src/assets/silence.wav +0 -0
- package/src/engine.ts +7 -2
- package/src/facades/dev.ts +17 -12
- package/src/facades/gallery.ts +1 -1
- package/src/facades/glasses.ts +17 -4
- package/src/facades/glassesSettings.ts +5 -0
- package/src/facades/miniapps.ts +7 -0
- package/src/facades/ota.ts +19 -4
- package/src/facades/pairing.ts +11 -7
- package/src/facades/permissions.ts +14 -0
- package/src/facades/phoneNotifications.ts +4 -13
- package/src/index.ts +26 -2
- package/src/internal.ts +3 -1
- package/src/react/MentraLiveOtaFlow.tsx +856 -0
- package/src/react/index.ts +7 -0
- package/src/react/useEngineSnapshot.ts +16 -0
- package/src/runtime/bootstrap.ts +33 -1
- package/src/runtime/scanQrSeam.ts +20 -0
- package/src/services/AppRegistry.ts +224 -149
- package/src/services/AudioCloudUplink.ts +23 -1
- package/src/services/AudioPlaybackService.ts +287 -38
- package/src/services/BlobStore.ts +22 -9
- package/src/services/CloudAudioSubscriptionSync.ts +13 -1
- package/src/services/CloudClientService.ts +96 -1
- package/src/services/DeviceEventRouter.ts +5 -5
- package/src/services/ForegroundLocationPermission.ts +24 -0
- package/src/services/GlassesSettingsSync.ts +9 -3
- package/src/services/GlassesStatusProjection.ts +16 -8
- package/src/services/HotspotOtaTransport.ts +184 -0
- package/src/services/HotspotShutdown.ts +41 -0
- package/src/services/LocalDisplayManager.ts +112 -21
- package/src/services/LocalMiniappRuntime.ts +967 -346
- package/src/services/LocalMiniappStorage.ts +82 -0
- package/src/services/LocalMiniappUserIdentity.ts +46 -0
- package/src/services/LocalSttFallbackCoordinator.ts +19 -12
- package/src/services/MicStateCoordinator.ts +169 -4
- package/src/services/MiniappLauncher.ts +30 -3
- package/src/services/MiniappLiveness.ts +24 -0
- package/src/services/NativeHttpResponse.ts +6 -0
- package/src/services/OtaArtifactDownloader.ts +312 -0
- package/src/services/OtaAutoChain.ts +106 -0
- package/src/services/OtaErrorMapping.ts +80 -0
- package/src/services/OtaInstallCoordinator.ts +645 -143
- package/src/services/OtaService.ts +11 -5
- package/src/services/OtaUpdateCheckService.ts +180 -20
- package/src/services/PhoneCalendarHelpers.ts +212 -0
- package/src/services/PhoneCalendarService.ts +65 -0
- package/src/services/PhoneCameraFovCoordinator.ts +210 -0
- package/src/services/PhoneNotificationsSync.ts +12 -10
- package/src/services/PhonePhotoCoordinator.ts +116 -18
- package/src/services/PhoneStreamCoordinator.ts +139 -25
- package/src/services/PhoneVideoCoordinator.ts +11 -0
- package/src/services/SceneRenderer.ts +16 -0
- package/src/services/SentenceTtsPipeline.ts +106 -0
- package/src/services/SupportProfileSync.ts +218 -0
- package/src/services/TranscriptionRouting.ts +37 -0
- package/src/services/TtsTextSanitizer.ts +66 -0
- package/src/services/WifiAdbRequest.ts +53 -0
- package/src/services/asg/asgCameraApi.ts +615 -33
- package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
- package/src/services/asg/cameraRollExportLedger.ts +122 -0
- package/src/services/asg/galleryNotices.ts +1 -0
- package/src/services/asg/galleryPathMigration.ts +22 -0
- package/src/services/asg/gallerySettingsService.ts +3 -0
- package/src/services/asg/gallerySyncService.ts +184 -73
- package/src/services/asg/galleryTransferLedger.ts +312 -0
- package/src/services/asg/localNetworkTransport.ts +169 -0
- package/src/services/asg/localStorageService.ts +179 -24
- package/src/services/asg/mediaProcessingQueue.ts +209 -62
- package/src/services/audioPlaybackAssets.ts +8 -0
- package/src/services/gallerySyncClock.ts +1 -1
- package/src/services/glassesClockSync.ts +2 -2
- package/src/services/manifestActions.ts +30 -0
- package/src/services/otaDisplayState.ts +57 -16
- package/src/services/otaInstallPolicy.ts +29 -3
- package/src/services/{asgOtaVersionUrl.ts → otaManifestUrl.ts} +16 -4
- package/src/services/slimStreamStatus.ts +16 -5
- package/src/stores/apps.ts +12 -0
- package/src/stores/bluetoothSettingKeys.ts +2 -0
- package/src/stores/gallerySync.ts +4 -0
- package/src/stores/glasses.ts +3 -0
- package/src/stores/settings.ts +179 -18
- package/src/types/applet.ts +2 -0
- package/src/types/asg.ts +7 -0
- package/src/types/enums.ts +2 -1
- package/src/types/hardware.ts +17 -0
- package/src/utils/configuredDevHost.ts +17 -0
- package/src/utils/devMiniappLaunch.ts +151 -23
- package/src/utils/diagnosticContext.ts +17 -17
- package/src/utils/hardware/hardware.ts +7 -9
- package/src/utils/miniappDiagnostics.ts +226 -0
- package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
- package/src/utils/timers/timers.ts +57 -21
- package/build/services/asgOtaVersionUrl.d.ts +0 -2
- package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
- package/build/services/asgOtaVersionUrl.js.map +0 -1
|
@@ -22,10 +22,13 @@ import { permissions, PermissionFeatures } from "../../facades/permissions";
|
|
|
22
22
|
import { asgCameraApi } from "./asgCameraApi";
|
|
23
23
|
import { gallerySettingsService } from "./gallerySettingsService";
|
|
24
24
|
import { gallerySyncNotifications } from "./gallerySyncNotifications";
|
|
25
|
+
import { localNetworkTransport } from "./localNetworkTransport";
|
|
25
26
|
import { localStorageService } from "./localStorageService";
|
|
26
27
|
import { mediaProcessingQueue } from "./mediaProcessingQueue";
|
|
27
28
|
import { validateCaptureMetadataForDownload } from "./galleryMediaValidation";
|
|
28
29
|
import { emitGalleryNotice } from "./galleryNotices";
|
|
30
|
+
import { galleryTransferLedger } from "./galleryTransferLedger";
|
|
31
|
+
import { cameraRollExportCoordinator } from "./cameraRollExportCoordinator";
|
|
29
32
|
// Timing constants
|
|
30
33
|
const TIMING = {
|
|
31
34
|
HOTSPOT_CONNECT_DELAY_MS: 3000, // Increased from 1000ms - hotspot needs time to broadcast and become discoverable
|
|
@@ -87,6 +90,7 @@ class GallerySyncService {
|
|
|
87
90
|
this.appStateSubscription = AppState.addEventListener("change", this.handleAppStateChange);
|
|
88
91
|
this.hotspotListenerRegistered = true;
|
|
89
92
|
this.isInitialized = true;
|
|
93
|
+
void cameraRollExportCoordinator.initialize();
|
|
90
94
|
// console.log("[GallerySyncService] Initialized")
|
|
91
95
|
// Check for resumable sync on startup
|
|
92
96
|
this.checkForResumableSync();
|
|
@@ -95,6 +99,7 @@ class GallerySyncService {
|
|
|
95
99
|
* Cleanup - remove event listeners
|
|
96
100
|
*/
|
|
97
101
|
cleanup() {
|
|
102
|
+
void localNetworkTransport.disconnect();
|
|
98
103
|
if (this.hotspotListenerRegistered) {
|
|
99
104
|
GlobalEventEmitter.removeListener("hotspot_status_change", this.handleHotspotStatusChange);
|
|
100
105
|
GlobalEventEmitter.removeListener("hotspot_error", this.handleHotspotError);
|
|
@@ -109,6 +114,7 @@ class GallerySyncService {
|
|
|
109
114
|
this.appStateSubscription.remove();
|
|
110
115
|
this.appStateSubscription = null;
|
|
111
116
|
}
|
|
117
|
+
cameraRollExportCoordinator.cleanup();
|
|
112
118
|
if (this.hotspotConnectionTimeout) {
|
|
113
119
|
BgTimer.clearTimeout(this.hotspotConnectionTimeout);
|
|
114
120
|
this.hotspotConnectionTimeout = null;
|
|
@@ -118,6 +124,10 @@ class GallerySyncService {
|
|
|
118
124
|
this.hotspotRequestTimeout = null;
|
|
119
125
|
}
|
|
120
126
|
this.syncStartPromise = null;
|
|
127
|
+
useGallerySyncStore.getState().setSyncStarting(false);
|
|
128
|
+
this.waitingForWifiRetry = false;
|
|
129
|
+
this.wifiSettingsOpenedAt = null;
|
|
130
|
+
this.startAborted = false;
|
|
121
131
|
this.isInitialized = false;
|
|
122
132
|
console.log("[GallerySyncService] Cleaned up");
|
|
123
133
|
}
|
|
@@ -153,6 +163,7 @@ class GallerySyncService {
|
|
|
153
163
|
this.hotspotRequestTimeout = null;
|
|
154
164
|
}
|
|
155
165
|
gallerySyncNotifications.showSyncError("Glasses disconnected");
|
|
166
|
+
void localNetworkTransport.disconnect();
|
|
156
167
|
};
|
|
157
168
|
/**
|
|
158
169
|
* Handle app state changes to auto-retry sync when user returns from settings
|
|
@@ -162,6 +173,8 @@ class GallerySyncService {
|
|
|
162
173
|
if (nextAppState !== "active") {
|
|
163
174
|
return;
|
|
164
175
|
}
|
|
176
|
+
// Camera-roll backfill is phone-local and must resume independently of glasses/WiFi.
|
|
177
|
+
void cameraRollExportCoordinator.resume("app foreground");
|
|
165
178
|
// Only auto-retry if we were waiting for WiFi
|
|
166
179
|
if (!this.waitingForWifiRetry) {
|
|
167
180
|
return;
|
|
@@ -174,41 +187,46 @@ class GallerySyncService {
|
|
|
174
187
|
if (!glassesConnected) {
|
|
175
188
|
console.log("[GallerySyncService] Glasses disconnected - not retrying sync");
|
|
176
189
|
this.waitingForWifiRetry = false;
|
|
190
|
+
this.wifiSettingsOpenedAt = null;
|
|
177
191
|
return;
|
|
178
192
|
}
|
|
193
|
+
// The user has returned from the WiFi settings prompt, so the previous
|
|
194
|
+
// "Sync failed" state is no longer actionable. Make the button available
|
|
195
|
+
// immediately while the native WiFi state catches up; a successful check
|
|
196
|
+
// below will start the sync automatically.
|
|
197
|
+
if (store.syncState === "error" && store.lastError?.startsWith("WiFi disabled")) {
|
|
198
|
+
store.setSyncState("idle");
|
|
199
|
+
}
|
|
179
200
|
// Check if WiFi is now enabled (Android only)
|
|
180
201
|
// Use retry logic because WiFi status takes time to propagate after user enables it
|
|
181
202
|
if (Platform.OS === "android") {
|
|
182
203
|
const MAX_RETRIES = 5;
|
|
183
|
-
const RETRY_DELAY_MS = 1000;
|
|
204
|
+
const RETRY_DELAY_MS = 1000;
|
|
184
205
|
console.log("[GallerySyncService] Waiting for WiFi to initialize (may take a moment after enabling)...");
|
|
185
206
|
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
186
207
|
try {
|
|
187
208
|
await new Promise((resolve) => BgTimer.setTimeout(() => resolve(), RETRY_DELAY_MS));
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
209
|
+
// NetInfo can remain stale after Android's WiFi settings close. Use
|
|
210
|
+
// the same native source as the normal sync preflight.
|
|
211
|
+
const wifiEnabled = await WifiManager.isEnabled();
|
|
212
|
+
console.log(`[GallerySyncService] WiFi check attempt ${attempt}/${MAX_RETRIES}: enabled=${wifiEnabled}`);
|
|
213
|
+
if (wifiEnabled) {
|
|
191
214
|
console.log("[GallerySyncService] ✅ WiFi is now enabled - auto-retrying sync");
|
|
192
215
|
this.waitingForWifiRetry = false;
|
|
193
216
|
this.wifiSettingsOpenedAt = null; // Clear cooldown timestamp
|
|
194
|
-
// Clear previous error state
|
|
195
|
-
store.setSyncState("idle");
|
|
196
217
|
// Auto-retry sync
|
|
197
218
|
await this.startSync();
|
|
198
219
|
return;
|
|
199
220
|
}
|
|
200
|
-
// If this was the last attempt, log and give up
|
|
201
|
-
if (attempt === MAX_RETRIES) {
|
|
202
|
-
console.log("[GallerySyncService] ❌ WiFi still disabled after all retries - user may need to tap sync manually");
|
|
203
|
-
this.waitingForWifiRetry = false;
|
|
204
|
-
this.wifiSettingsOpenedAt = null; // Clear cooldown timestamp
|
|
205
|
-
}
|
|
206
221
|
}
|
|
207
222
|
catch (error) {
|
|
208
223
|
console.warn(`[GallerySyncService] Failed to check WiFi status on attempt ${attempt}:`, error);
|
|
209
224
|
// Continue to next retry
|
|
210
225
|
}
|
|
211
226
|
}
|
|
227
|
+
console.log("[GallerySyncService] WiFi not detected after retries - leaving sync available for manual retry");
|
|
228
|
+
this.waitingForWifiRetry = false;
|
|
229
|
+
this.wifiSettingsOpenedAt = null;
|
|
212
230
|
}
|
|
213
231
|
};
|
|
214
232
|
/**
|
|
@@ -294,8 +312,10 @@ class GallerySyncService {
|
|
|
294
312
|
console.log("[GallerySyncService] ⚠️ Sync start already in progress, joining existing attempt");
|
|
295
313
|
return this.syncStartPromise;
|
|
296
314
|
}
|
|
315
|
+
useGallerySyncStore.getState().setSyncStarting(true);
|
|
297
316
|
this.syncStartPromise = this.runStartSync().finally(() => {
|
|
298
317
|
this.syncStartPromise = null;
|
|
318
|
+
useGallerySyncStore.getState().setSyncStarting(false);
|
|
299
319
|
});
|
|
300
320
|
return this.syncStartPromise;
|
|
301
321
|
}
|
|
@@ -401,8 +421,6 @@ class GallerySyncService {
|
|
|
401
421
|
connected: glassesConnected,
|
|
402
422
|
hotspotEnabled: glassesHotspot !== null,
|
|
403
423
|
});
|
|
404
|
-
// Reset processing queue only after pre-flight passes — avoids clobbering an active session
|
|
405
|
-
mediaProcessingQueue.reset();
|
|
406
424
|
// Request all permissions upfront so user isn't interrupted during WiFi/download
|
|
407
425
|
console.log("[GallerySyncService] 🔐 Step 1/6: Requesting permissions...");
|
|
408
426
|
// 1. Notification permission (for background sync progress)
|
|
@@ -434,6 +452,22 @@ class GallerySyncService {
|
|
|
434
452
|
console.log("[GallerySyncService] Pre-flight aborted after location permission");
|
|
435
453
|
return;
|
|
436
454
|
}
|
|
455
|
+
if (Platform.OS === "android") {
|
|
456
|
+
console.log("[GallerySyncService] 📡 Checking local WiFi permission...");
|
|
457
|
+
const hasLocalWifiPermission = await permissions.check(PermissionFeatures.LOCAL_WIFI);
|
|
458
|
+
if (!hasLocalWifiPermission) {
|
|
459
|
+
const granted = await permissions.request(PermissionFeatures.LOCAL_WIFI);
|
|
460
|
+
if (!granted) {
|
|
461
|
+
store.setSyncError("Local WiFi permission is required for gallery sync");
|
|
462
|
+
await gallerySyncNotifications.showSyncError("Allow WiFi access to connect to your glasses");
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (this.shouldAbortPreFlight()) {
|
|
467
|
+
console.log("[GallerySyncService] Pre-flight aborted after local WiFi permission");
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
437
471
|
// 3. Camera roll permission (if auto-save is enabled)
|
|
438
472
|
const shouldAutoSave = await gallerySettingsService.getAutoSaveToCameraRoll();
|
|
439
473
|
console.log(`[GallerySyncService] 📸 Auto-save to camera roll: ${shouldAutoSave}`);
|
|
@@ -444,9 +478,10 @@ class GallerySyncService {
|
|
|
444
478
|
console.log("[GallerySyncService] ⚠️ Camera roll permission not granted - requesting...");
|
|
445
479
|
const granted = await MediaLibraryPermissions.requestPermission();
|
|
446
480
|
if (!granted) {
|
|
447
|
-
console.warn("[GallerySyncService] ❌ Camera roll permission denied -
|
|
448
|
-
|
|
449
|
-
|
|
481
|
+
console.warn("[GallerySyncService] ❌ Camera roll permission denied - auto-save sync cannot continue");
|
|
482
|
+
store.setSyncError("Camera-roll permission required while automatic saving is enabled");
|
|
483
|
+
emitGalleryNotice({ code: "camera_roll_permission_required" });
|
|
484
|
+
return;
|
|
450
485
|
}
|
|
451
486
|
else {
|
|
452
487
|
console.log("[GallerySyncService] ✅ Camera roll permission granted");
|
|
@@ -635,12 +670,21 @@ class GallerySyncService {
|
|
|
635
670
|
console.log("[GallerySyncService] ℹ️ Glasses hotspot not currently enabled");
|
|
636
671
|
console.log("[GallerySyncService] ➡️ Will request hotspot activation");
|
|
637
672
|
}
|
|
673
|
+
// Every fallible pre-flight gate has passed. It is now safe to replace the previous
|
|
674
|
+
// in-memory queue; startFileDownload immediately recovers its durable ledger work.
|
|
675
|
+
mediaProcessingQueue.reset();
|
|
638
676
|
if (isAlreadyConnected && currentGlassesHotspot) {
|
|
639
|
-
console.log("[GallerySyncService] 🚀 Skipping hotspot request - already connected!");
|
|
640
677
|
const hotspotInfo = currentGlassesHotspot;
|
|
641
678
|
store.setHotspotInfo(hotspotInfo);
|
|
642
679
|
store.setSyncState("connecting_wifi");
|
|
643
|
-
|
|
680
|
+
if (localNetworkTransport.supportsScopedConnection() && !localNetworkTransport.isScopedConnectionActive()) {
|
|
681
|
+
console.log("[GallerySyncService] 📡 System SSID matches; establishing scoped glasses transport");
|
|
682
|
+
await this.connectToHotspotWifi(hotspotInfo);
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
console.log("[GallerySyncService] 🚀 Skipping hotspot request - already connected!");
|
|
686
|
+
await this.startFileDownload(hotspotInfo);
|
|
687
|
+
}
|
|
644
688
|
return;
|
|
645
689
|
}
|
|
646
690
|
// Request hotspot
|
|
@@ -773,7 +817,7 @@ class GallerySyncService {
|
|
|
773
817
|
preConnectSSID = await WifiManager.getCurrentWifiSSID();
|
|
774
818
|
console.log(`[GallerySyncService] 📡 Current WiFi SSID: "${preConnectSSID}"`);
|
|
775
819
|
// Check if already connected (shouldn't happen, but good to verify)
|
|
776
|
-
if (preConnectSSID === hotspotInfo.ssid) {
|
|
820
|
+
if (!localNetworkTransport.supportsScopedConnection() && preConnectSSID === hotspotInfo.ssid) {
|
|
777
821
|
console.log("[GallerySyncService] ✅ Already connected to target SSID! Proceeding to download.");
|
|
778
822
|
appStateSubscription.remove();
|
|
779
823
|
const totalWifiDuration = Date.now() - wifiConnectStartTime;
|
|
@@ -790,8 +834,7 @@ class GallerySyncService {
|
|
|
790
834
|
console.warn(`[GallerySyncService] ⚠️ Could not get current SSID: ${preError?.message}`);
|
|
791
835
|
console.warn("[GallerySyncService] ⚠️ Error code:", preError?.code);
|
|
792
836
|
}
|
|
793
|
-
|
|
794
|
-
console.log(`[GallerySyncService] 🔌 Calling WifiManager.connectToProtectedSSID...`);
|
|
837
|
+
console.log(`[GallerySyncService] 🔌 Connecting the glasses-local transport...`);
|
|
795
838
|
console.log(`[GallerySyncService] 🔌 Parameters:`);
|
|
796
839
|
console.log(`[GallerySyncService] - SSID: "${hotspotInfo.ssid}"`);
|
|
797
840
|
console.log(`[GallerySyncService] - Password: ${"*".repeat(hotspotInfo.password.length)}`);
|
|
@@ -800,9 +843,9 @@ class GallerySyncService {
|
|
|
800
843
|
const connectCallStartTime = Date.now();
|
|
801
844
|
appBackgrounded = false; // Reset flag for this attempt
|
|
802
845
|
appBackgroundTime = null;
|
|
803
|
-
await
|
|
846
|
+
await localNetworkTransport.connect(hotspotInfo.ssid, hotspotInfo.password);
|
|
804
847
|
const connectCallDuration = Date.now() - connectCallStartTime;
|
|
805
|
-
console.log(`[GallerySyncService] ✅
|
|
848
|
+
console.log(`[GallerySyncService] ✅ Glasses-local transport connected successfully`);
|
|
806
849
|
console.log(`[GallerySyncService] ⏱️ Library call duration: ${connectCallDuration}ms`);
|
|
807
850
|
console.log(`[GallerySyncService] 📱 App was backgrounded during call: ${appBackgrounded}`);
|
|
808
851
|
if (appBackgrounded && appBackgroundTime) {
|
|
@@ -860,7 +903,9 @@ class GallerySyncService {
|
|
|
860
903
|
console.log("[GallerySyncService] 👂 App state listener removed");
|
|
861
904
|
// Final verification: Check SSID one more time before starting download
|
|
862
905
|
try {
|
|
863
|
-
const finalSSID =
|
|
906
|
+
const finalSSID = localNetworkTransport.isScopedConnectionActive()
|
|
907
|
+
? hotspotInfo.ssid
|
|
908
|
+
: await WifiManager.getCurrentWifiSSID();
|
|
864
909
|
console.log(`[GallerySyncService] 📶 Final SSID check before download: "${finalSSID}"`);
|
|
865
910
|
if (Platform.OS === "android") {
|
|
866
911
|
// Some local builds can have stale generated typings for the Bluetooth SDK module.
|
|
@@ -891,7 +936,7 @@ class GallerySyncService {
|
|
|
891
936
|
const probeController = new AbortController();
|
|
892
937
|
const probeTimeout = BgTimer.setTimeout(() => probeController.abort(), 1000); // 1 second timeout per probe
|
|
893
938
|
const probeStartTime = Date.now();
|
|
894
|
-
const probeResponse = await fetch(`http://${hotspotInfo.ip}:8089/api/health`, {
|
|
939
|
+
const probeResponse = await localNetworkTransport.fetch(`http://${hotspotInfo.ip}:8089/api/health`, {
|
|
895
940
|
method: "GET",
|
|
896
941
|
signal: probeController.signal,
|
|
897
942
|
});
|
|
@@ -1064,13 +1109,40 @@ class GallerySyncService {
|
|
|
1064
1109
|
}
|
|
1065
1110
|
}
|
|
1066
1111
|
finally {
|
|
1112
|
+
// Release the scoped Android Network on every terminal path. This is idempotent with
|
|
1113
|
+
// closeHotspot(), and intentionally leaves Android 9/iOS legacy routing unchanged.
|
|
1114
|
+
await localNetworkTransport.disconnect();
|
|
1067
1115
|
// L2: Guarantee listener cleanup on all exit paths (cancel, success, error, exhaustion)
|
|
1068
1116
|
appStateSubscription.remove();
|
|
1069
1117
|
}
|
|
1070
1118
|
}
|
|
1071
1119
|
async fetchSyncManifest(clientId, lastSyncTime) {
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1120
|
+
const v3 = typeof asgCameraApi.getV3Manifest === "function" ? await asgCameraApi.getV3Manifest() : null;
|
|
1121
|
+
if (v3) {
|
|
1122
|
+
const downloadedFiles = await localStorageService.getDownloadedFiles();
|
|
1123
|
+
await localStorageService.reconcileRemoteCaptures(v3.captures.map((capture) => capture.capture_id), downloadedFiles);
|
|
1124
|
+
return {
|
|
1125
|
+
api_version: 3,
|
|
1126
|
+
client_id: clientId,
|
|
1127
|
+
// The ledger is a crash-recovery journal, not proof that app-private media survived an
|
|
1128
|
+
// Android restore or reinstall. Suppress a remote capture only when both records agree.
|
|
1129
|
+
captures: v3.captures.filter((capture) => !downloadedFiles[capture.capture_id] || !galleryTransferLedger.isLocallyCommitted(capture.capture_id)),
|
|
1130
|
+
changed_files: [],
|
|
1131
|
+
deleted_files: [],
|
|
1132
|
+
server_time: v3.server_time,
|
|
1133
|
+
total_changed: v3.captures.length,
|
|
1134
|
+
total_size: v3.captures.reduce((total, capture) => total + capture.total_size, 0),
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
// Old firmware remains on the exact v2 endpoint/schema. Avoid expensive inline thumbnails;
|
|
1138
|
+
// video thumbnails are fetched as small side downloads with their primary media.
|
|
1139
|
+
const syncResponse = await asgCameraApi.syncWithServer(clientId, lastSyncTime, false);
|
|
1140
|
+
const data = (syncResponse.data || syncResponse);
|
|
1141
|
+
if (data.captures) {
|
|
1142
|
+
data.captures = data.captures.filter((capture) => !galleryTransferLedger.isLocallyCommitted(capture.capture_id));
|
|
1143
|
+
}
|
|
1144
|
+
data.changed_files = (data.changed_files || []).filter((file) => !galleryTransferLedger.isFileLocallyCommitted(file.name));
|
|
1145
|
+
return data;
|
|
1074
1146
|
}
|
|
1075
1147
|
/**
|
|
1076
1148
|
* Resolve sync manifest: detect skew, optionally fix clock, retry full sync when needed.
|
|
@@ -1125,6 +1197,10 @@ class GallerySyncService {
|
|
|
1125
1197
|
// Set up the API client
|
|
1126
1198
|
asgCameraApi.setServer(hotspotInfo.ip, 8089);
|
|
1127
1199
|
console.log("[GallerySyncService] ✅ API client configured");
|
|
1200
|
+
const recovery = await mediaProcessingQueue.retryPending();
|
|
1201
|
+
if (recovery.retried > 0 || recovery.failed > 0) {
|
|
1202
|
+
console.log(`[GallerySyncService] ♻️ Recovery: ${recovery.retried} completed, ${recovery.failed} still pending`);
|
|
1203
|
+
}
|
|
1128
1204
|
// Get sync state and files to download
|
|
1129
1205
|
// IMPORTANT: This creates a SNAPSHOT of files at this moment based on last_sync_time.
|
|
1130
1206
|
// Any photos taken AFTER this call (during the sync) will NOT be included in this sync.
|
|
@@ -1159,16 +1235,21 @@ class GallerySyncService {
|
|
|
1159
1235
|
console.log(`[GallerySyncService] - Captures: ${syncData.captures?.length || 0}`);
|
|
1160
1236
|
if (isSyncManifestEmpty(syncData)) {
|
|
1161
1237
|
console.log("[GallerySyncService] ✅ No new files to sync - already up to date!");
|
|
1162
|
-
|
|
1238
|
+
if (galleryTransferLedger.hasPendingRecovery()) {
|
|
1239
|
+
store.setSyncError("Gallery export or acknowledgement needs retry");
|
|
1240
|
+
}
|
|
1241
|
+
else {
|
|
1242
|
+
store.setSyncComplete();
|
|
1243
|
+
}
|
|
1163
1244
|
await this.onSyncComplete(0, 0);
|
|
1164
1245
|
return;
|
|
1165
1246
|
}
|
|
1166
1247
|
// Detect API version and route to appropriate download path
|
|
1167
|
-
const useCaptures = syncData.api_version
|
|
1248
|
+
const useCaptures = (syncData.api_version || 0) >= 2 && syncData.captures && syncData.captures.length > 0;
|
|
1168
1249
|
if (useCaptures) {
|
|
1169
1250
|
// New capture-aware sync path
|
|
1170
1251
|
const captures = syncData.captures;
|
|
1171
|
-
console.log(`[GallerySyncService] 📊 Found ${captures.length} captures to download (api_version
|
|
1252
|
+
console.log(`[GallerySyncService] 📊 Found ${captures.length} captures to download (api_version=${syncData.api_version})`);
|
|
1172
1253
|
captures.slice(0, 5).forEach((c, idx) => {
|
|
1173
1254
|
console.log(`[GallerySyncService] ${idx + 1}. ${c.capture_id} (${c.type}, ${c.files.length} files, ${(c.total_size / 1024).toFixed(1)} KB)`);
|
|
1174
1255
|
});
|
|
@@ -1260,7 +1341,7 @@ class GallerySyncService {
|
|
|
1260
1341
|
const downloadResult = await asgCameraApi.batchSyncFiles(files, true, (current, total, fileName, fileProgress, downloadedFile) => {
|
|
1261
1342
|
// CRITICAL: This callback MUST NOT throw!
|
|
1262
1343
|
// RNFS progress callbacks run inside native bridge — throwing here causes
|
|
1263
|
-
// EXC_BAD_ACCESS. Cancellation is handled via AbortSignal →
|
|
1344
|
+
// EXC_BAD_ACCESS. Cancellation is handled via AbortSignal → the active transport.
|
|
1264
1345
|
// Check if cancelled — just return, abort signal will stop the download
|
|
1265
1346
|
if (this.abortController?.signal.aborted) {
|
|
1266
1347
|
return;
|
|
@@ -1345,6 +1426,7 @@ class GallerySyncService {
|
|
|
1345
1426
|
shouldAutoSave: !!shouldAutoSave,
|
|
1346
1427
|
thumbnailPath: downloadedFile.thumbnailPath,
|
|
1347
1428
|
deleteFromGlasses: [downloadedFile.name],
|
|
1429
|
+
protocolVersion: 1,
|
|
1348
1430
|
});
|
|
1349
1431
|
}
|
|
1350
1432
|
}
|
|
@@ -1375,18 +1457,6 @@ class GallerySyncService {
|
|
|
1375
1457
|
currentStore.onFileComplete(lastFileName);
|
|
1376
1458
|
}
|
|
1377
1459
|
}
|
|
1378
|
-
// Save downloaded files metadata (skip auxiliary files from gallery entries)
|
|
1379
|
-
for (const photoInfo of downloadResult.downloaded) {
|
|
1380
|
-
// Skip HDR brackets and IMU sidecars — they shouldn't appear as separate gallery items
|
|
1381
|
-
const isAuxiliary = photoInfo.name?.match(/_ev-?\d+\.(jpg|jpeg)$/i) ||
|
|
1382
|
-
photoInfo.name?.match(/\.imu\.json$/i) ||
|
|
1383
|
-
photoInfo.name?.match(/\/ev-?\d+\.jpe?g$/i) ||
|
|
1384
|
-
photoInfo.name?.match(/\/imu\.json$/i);
|
|
1385
|
-
if (isAuxiliary)
|
|
1386
|
-
continue;
|
|
1387
|
-
const downloadedFile = localStorageService.convertToDownloadedFile(photoInfo, photoInfo.filePath || "", photoInfo.thumbnailPath, defaultWearable);
|
|
1388
|
-
await localStorageService.saveDownloadedFile(downloadedFile);
|
|
1389
|
-
}
|
|
1390
1460
|
// Update queue index to final position
|
|
1391
1461
|
await localStorageService.updateSyncQueueIndex(files.length);
|
|
1392
1462
|
// Mark failed files in store
|
|
@@ -1398,6 +1468,16 @@ class GallerySyncService {
|
|
|
1398
1468
|
console.log("[GallerySyncService] ⏳ Waiting for processing queue to drain...");
|
|
1399
1469
|
await mediaProcessingQueue.waitUntilDrained();
|
|
1400
1470
|
console.log("[GallerySyncService] ✅ Processing queue drained");
|
|
1471
|
+
// Download success is not destination success. Export, validation, metadata, and
|
|
1472
|
+
// acknowledgement failures are reported asynchronously by the processing queue; fold them
|
|
1473
|
+
// back into the legacy result so its timestamp watermark cannot skip the source forever.
|
|
1474
|
+
const processingFailures = new Set(useGallerySyncStore.getState().failedFiles);
|
|
1475
|
+
for (const file of files) {
|
|
1476
|
+
if (processingFailures.has(file.name) && !downloadResult.failed.includes(file.name)) {
|
|
1477
|
+
downloadResult.failed.push(file.name);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
failedCount = downloadResult.failed.length;
|
|
1401
1481
|
// Update sync state — only advance watermark if files were downloaded.
|
|
1402
1482
|
// If any failed, set it before the oldest failure so they get retried.
|
|
1403
1483
|
let syncWatermark = serverTime;
|
|
@@ -1453,8 +1533,12 @@ class GallerySyncService {
|
|
|
1453
1533
|
console.log(`[GallerySyncService] - Total data (lifetime): ${((currentSyncState.total_size + downloadResult.total_size) /
|
|
1454
1534
|
1024 /
|
|
1455
1535
|
1024).toFixed(2)} MB`);
|
|
1456
|
-
|
|
1457
|
-
|
|
1536
|
+
if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {
|
|
1537
|
+
store.setSyncError(`${failedCount || "Some"} gallery items need retry`);
|
|
1538
|
+
}
|
|
1539
|
+
else {
|
|
1540
|
+
store.setSyncComplete();
|
|
1541
|
+
}
|
|
1458
1542
|
await this.onSyncComplete(downloadedCount, failedCount);
|
|
1459
1543
|
}
|
|
1460
1544
|
catch (error) {
|
|
@@ -1539,6 +1623,7 @@ class GallerySyncService {
|
|
|
1539
1623
|
bracketPaths: result.bracketPaths,
|
|
1540
1624
|
sidecarPath: result.sidecarPath,
|
|
1541
1625
|
thumbnailData: capture.thumbnail_data,
|
|
1626
|
+
thumbnailPath: result.thumbnailPath,
|
|
1542
1627
|
captureDir: result.captureDir,
|
|
1543
1628
|
timestamp: capture.timestamp,
|
|
1544
1629
|
totalSize: capture.total_size,
|
|
@@ -1547,6 +1632,7 @@ class GallerySyncService {
|
|
|
1547
1632
|
shouldProcess: !!shouldProcessImages,
|
|
1548
1633
|
shouldAutoSave: !!shouldAutoSave,
|
|
1549
1634
|
deleteFromGlasses: [capture.capture_id],
|
|
1635
|
+
protocolVersion: capture.files.some((file) => !!file.etag) ? 3 : 2,
|
|
1550
1636
|
});
|
|
1551
1637
|
}
|
|
1552
1638
|
catch (captureError) {
|
|
@@ -1631,7 +1717,12 @@ class GallerySyncService {
|
|
|
1631
1717
|
total_size: currentSyncState.total_size + totalSizeDownloaded,
|
|
1632
1718
|
});
|
|
1633
1719
|
}
|
|
1634
|
-
|
|
1720
|
+
if (failedCount > 0 || galleryTransferLedger.hasPendingRecovery()) {
|
|
1721
|
+
store.setSyncError(`${failedCount || "Some"} gallery items need retry`);
|
|
1722
|
+
}
|
|
1723
|
+
else {
|
|
1724
|
+
store.setSyncComplete();
|
|
1725
|
+
}
|
|
1635
1726
|
await this.onSyncComplete(downloadedCount, failedCount);
|
|
1636
1727
|
}
|
|
1637
1728
|
catch (error) {
|
|
@@ -1689,12 +1780,24 @@ class GallerySyncService {
|
|
|
1689
1780
|
// } catch (error) {
|
|
1690
1781
|
// console.error(`[GallerySyncService] Failed to get post-sync inventory:`, error)
|
|
1691
1782
|
// }
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1783
|
+
const hasPendingRecovery = galleryTransferLedger.hasPendingRecovery();
|
|
1784
|
+
if (!hasPendingRecovery && failedCount === 0) {
|
|
1785
|
+
console.log("[GallerySyncService] 🧹 Clearing completed sync queue...");
|
|
1786
|
+
await localStorageService.clearSyncQueue();
|
|
1787
|
+
}
|
|
1788
|
+
else {
|
|
1789
|
+
console.log("[GallerySyncService] ♻️ Keeping recovery state for unfinished export/ack work");
|
|
1790
|
+
}
|
|
1791
|
+
if (hasPendingRecovery || failedCount > 0) {
|
|
1792
|
+
console.log("[GallerySyncService] 📱 Showing retry-required notification...");
|
|
1793
|
+
await gallerySyncNotifications.showSyncError(failedCount > 0
|
|
1794
|
+
? `${failedCount} gallery item${failedCount === 1 ? "" : "s"} will be retried`
|
|
1795
|
+
: "Gallery export or acknowledgement will be retried");
|
|
1796
|
+
}
|
|
1797
|
+
else {
|
|
1798
|
+
console.log("[GallerySyncService] 📱 Showing completion notification...");
|
|
1799
|
+
await gallerySyncNotifications.showSyncComplete(downloadedCount, 0);
|
|
1800
|
+
}
|
|
1698
1801
|
// Close hotspot if we opened it
|
|
1699
1802
|
const store = useGallerySyncStore.getState();
|
|
1700
1803
|
if (store.syncServiceOpenedHotspot) {
|
|
@@ -1707,8 +1810,10 @@ class GallerySyncService {
|
|
|
1707
1810
|
// Clear glasses gallery count immediately after successful sync
|
|
1708
1811
|
// This ensures UI shows 0 items remaining right away
|
|
1709
1812
|
// The subsequent query will update this if new photos were taken during sync
|
|
1710
|
-
|
|
1711
|
-
|
|
1813
|
+
if (!hasPendingRecovery && failedCount === 0) {
|
|
1814
|
+
console.log("[GallerySyncService] 🔄 Clearing glasses gallery count (synced all items)");
|
|
1815
|
+
store.clearGlassesGalleryStatus();
|
|
1816
|
+
}
|
|
1712
1817
|
// Auto-reset to idle after 4 seconds to clear "Sync complete!" message,
|
|
1713
1818
|
// then query glasses for any new content taken during the sync.
|
|
1714
1819
|
// The query MUST happen after the reset — otherwise setGlassesGalleryStatus
|
|
@@ -1764,6 +1869,7 @@ class GallerySyncService {
|
|
|
1764
1869
|
const store = useGallerySyncStore.getState();
|
|
1765
1870
|
try {
|
|
1766
1871
|
console.log("[GallerySyncService] Closing hotspot...");
|
|
1872
|
+
await localNetworkTransport.disconnect();
|
|
1767
1873
|
await BluetoothSdk.setHotspotState(false);
|
|
1768
1874
|
store.setSyncServiceOpenedHotspot(false);
|
|
1769
1875
|
store.setHotspotInfo(null);
|
|
@@ -1824,7 +1930,7 @@ class GallerySyncService {
|
|
|
1824
1930
|
}
|
|
1825
1931
|
/** True while pre-flight startSync work is in flight (before sync state transitions). */
|
|
1826
1932
|
isSyncStarting() {
|
|
1827
|
-
return
|
|
1933
|
+
return useGallerySyncStore.getState().syncStarting;
|
|
1828
1934
|
}
|
|
1829
1935
|
/**
|
|
1830
1936
|
* Check if sync is currently in progress (hotspot/WiFi/download phases).
|