@glassly/engine 0.1.0-dev.99 → 0.2.8-dev.445
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 +28 -0
- package/build/engine.d.ts +32 -10
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +24 -16
- package/build/engine.js.map +1 -1
- package/build/facades/dev.d.ts +9 -0
- package/build/facades/dev.d.ts.map +1 -1
- package/build/facades/dev.js +9 -0
- package/build/facades/dev.js.map +1 -1
- package/build/facades/display.d.ts +10 -3
- package/build/facades/display.d.ts.map +1 -1
- package/build/facades/display.js +22 -8
- package/build/facades/display.js.map +1 -1
- package/build/facades/displayMirror.d.ts +11 -0
- package/build/facades/displayMirror.d.ts.map +1 -1
- package/build/facades/displayMirror.js +22 -0
- package/build/facades/displayMirror.js.map +1 -1
- package/build/facades/glasses.d.ts +31 -1
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +51 -0
- package/build/facades/glasses.js.map +1 -1
- package/build/facades/memory.d.ts +0 -6
- package/build/facades/memory.d.ts.map +1 -1
- package/build/facades/memory.js +1 -9
- package/build/facades/memory.js.map +1 -1
- package/build/facades/miniapps.d.ts +3 -1
- package/build/facades/miniapps.d.ts.map +1 -1
- package/build/facades/miniapps.js +3 -1
- package/build/facades/miniapps.js.map +1 -1
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +5 -4
- package/build/facades/pairing.js.map +1 -1
- package/build/facades/permissions.d.ts +2 -0
- package/build/facades/permissions.d.ts.map +1 -1
- package/build/facades/permissions.js +48 -0
- package/build/facades/permissions.js.map +1 -1
- package/build/facades/phoneNotifications.d.ts +20 -9
- package/build/facades/phoneNotifications.d.ts.map +1 -1
- package/build/facades/phoneNotifications.js +33 -26
- package/build/facades/phoneNotifications.js.map +1 -1
- package/build/facades/settings.d.ts.map +1 -1
- package/build/facades/settings.js +1 -2
- package/build/facades/settings.js.map +1 -1
- package/build/generated/releaseMetadata.js +4 -4
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +6 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -4
- package/build/index.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.js +2 -2
- package/build/react/MentraLiveOtaFlow.js.map +1 -1
- package/build/react/useMentraLiveOta.d.ts.map +1 -1
- package/build/react/useMentraLiveOta.js +8 -7
- package/build/react/useMentraLiveOta.js.map +1 -1
- package/build/runtime/config.d.ts +1 -1
- package/build/runtime/config.d.ts.map +1 -1
- package/build/runtime/config.js.map +1 -1
- package/build/services/AppRegistry.d.ts +4 -1
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +21 -1
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/BlobStore.d.ts +2 -2
- package/build/services/BlobStore.js +3 -3
- package/build/services/BlobStore.js.map +1 -1
- package/build/services/CloudClientService.d.ts +7 -3
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +34 -9
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DevServerBridge.d.ts +1 -18
- package/build/services/DevServerBridge.d.ts.map +1 -1
- package/build/services/DevServerBridge.js +9 -8
- package/build/services/DevServerBridge.js.map +1 -1
- package/build/services/DeviceEventRouter.d.ts.map +1 -1
- package/build/services/DeviceEventRouter.js +58 -71
- package/build/services/DeviceEventRouter.js.map +1 -1
- package/build/services/DisplayDiagnostics.d.ts +5 -0
- package/build/services/DisplayDiagnostics.d.ts.map +1 -0
- package/build/services/DisplayDiagnostics.js +105 -0
- package/build/services/DisplayDiagnostics.js.map +1 -0
- package/build/services/DisplayProcessor.d.ts +6 -7
- package/build/services/DisplayProcessor.d.ts.map +1 -1
- package/build/services/DisplayProcessor.js +17 -45
- package/build/services/DisplayProcessor.js.map +1 -1
- package/build/services/GestureDotsService.d.ts +10 -4
- package/build/services/GestureDotsService.d.ts.map +1 -1
- package/build/services/GestureDotsService.js +70 -16
- package/build/services/GestureDotsService.js.map +1 -1
- package/build/services/GlassesKeyboardInput.d.ts +77 -0
- package/build/services/GlassesKeyboardInput.d.ts.map +1 -0
- package/build/services/GlassesKeyboardInput.js +261 -0
- package/build/services/GlassesKeyboardInput.js.map +1 -0
- package/build/services/GlassesSensorService.d.ts +47 -0
- package/build/services/GlassesSensorService.d.ts.map +1 -0
- package/build/services/GlassesSensorService.js +242 -0
- package/build/services/GlassesSensorService.js.map +1 -0
- package/build/services/GlassesTouchInput.d.ts +14 -0
- package/build/services/GlassesTouchInput.d.ts.map +1 -0
- package/build/services/GlassesTouchInput.js +107 -0
- package/build/services/GlassesTouchInput.js.map +1 -0
- package/build/services/HeadingService.d.ts +0 -6
- package/build/services/HeadingService.d.ts.map +1 -1
- package/build/services/HeadingService.js +0 -27
- package/build/services/HeadingService.js.map +1 -1
- package/build/services/HotspotShutdown.d.ts.map +1 -1
- package/build/services/HotspotShutdown.js +2 -1
- package/build/services/HotspotShutdown.js.map +1 -1
- package/build/services/JSCrashloopReportService.js +2 -2
- package/build/services/JSCrashloopReportService.js.map +1 -1
- package/build/services/JSRouter.d.ts +6 -4
- package/build/services/JSRouter.d.ts.map +1 -1
- package/build/services/JSRouter.js +15 -13
- package/build/services/JSRouter.js.map +1 -1
- package/build/services/LocalDisplayManager.d.ts +35 -7
- package/build/services/LocalDisplayManager.d.ts.map +1 -1
- package/build/services/LocalDisplayManager.js +105 -27
- package/build/services/LocalDisplayManager.js.map +1 -1
- package/build/services/LocalMiniappDataMigration.d.ts +1 -1
- package/build/services/LocalMiniappDataMigration.js +1 -1
- package/build/services/LocalMiniappDataMigration.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +64 -11
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +441 -35
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.d.ts +3 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js +27 -8
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/MemoryStore.d.ts +8 -33
- package/build/services/MemoryStore.d.ts.map +1 -1
- package/build/services/MemoryStore.js +30 -56
- package/build/services/MemoryStore.js.map +1 -1
- package/build/services/MiniappEngine.d.ts +3 -3
- package/build/services/MiniappEngine.js +7 -7
- package/build/services/MiniappEngine.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts +8 -0
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +19 -1
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/MirrorService.d.ts +24 -0
- package/build/services/MirrorService.d.ts.map +1 -0
- package/build/services/MirrorService.js +132 -0
- package/build/services/MirrorService.js.map +1 -0
- package/build/services/NativeNavigationService.d.ts +2 -3
- package/build/services/NativeNavigationService.d.ts.map +1 -1
- package/build/services/NativeNavigationService.js +24 -21
- package/build/services/NativeNavigationService.js.map +1 -1
- package/build/services/NavigationHandlers.d.ts.map +1 -1
- package/build/services/NavigationHandlers.js +10 -5
- package/build/services/NavigationHandlers.js.map +1 -1
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +24 -23
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/PairedGlassesLatch.d.ts +7 -0
- package/build/services/PairedGlassesLatch.d.ts.map +1 -0
- package/build/services/PairedGlassesLatch.js +38 -0
- package/build/services/PairedGlassesLatch.js.map +1 -0
- package/build/services/PhoneActivity.d.ts +23 -0
- package/build/services/PhoneActivity.d.ts.map +1 -0
- package/build/services/PhoneActivity.js +111 -0
- package/build/services/PhoneActivity.js.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
- package/build/services/PhoneCameraFovCoordinator.js +4 -3
- package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
- package/build/services/PhoneNotificationsSync.d.ts +40 -6
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +160 -84
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
- package/build/services/PhonePhotoCoordinator.js +6 -5
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
- package/build/services/PhoneStreamCoordinator.js +8 -7
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/STTModelManager.d.ts +3 -0
- package/build/services/STTModelManager.d.ts.map +1 -1
- package/build/services/STTModelManager.js +15 -1
- package/build/services/STTModelManager.js.map +1 -1
- package/build/services/SceneRenderer.d.ts +43 -2
- package/build/services/SceneRenderer.d.ts.map +1 -1
- package/build/services/SceneRenderer.js +123 -8
- package/build/services/SceneRenderer.js.map +1 -1
- package/build/services/StreamLifecycleController.d.ts.map +1 -1
- package/build/services/StreamLifecycleController.js +6 -14
- package/build/services/StreamLifecycleController.js.map +1 -1
- package/build/services/TTSModelManager.js +1 -1
- package/build/services/TTSModelManager.js.map +1 -1
- package/build/services/UIRouter.d.ts +2 -2
- package/build/services/UIRouter.js +5 -5
- package/build/services/UIRouter.js.map +1 -1
- package/build/services/asg/galleryPathMigration.js +1 -1
- package/build/services/asg/galleryPathMigration.js.map +1 -1
- package/build/services/asg/gallerySyncService.js +2 -2
- package/build/services/asg/gallerySyncService.js.map +1 -1
- package/build/services/asg/localStorageService.d.ts.map +1 -1
- package/build/services/asg/localStorageService.js +3 -3
- package/build/services/asg/localStorageService.js.map +1 -1
- package/build/services/debug/DashboardOpenTrace.d.ts +32 -0
- package/build/services/debug/DashboardOpenTrace.d.ts.map +1 -0
- package/build/services/debug/DashboardOpenTrace.js +128 -0
- package/build/services/debug/DashboardOpenTrace.js.map +1 -0
- package/build/services/debug/dashboardOpenTimeline.d.ts +77 -0
- package/build/services/debug/dashboardOpenTimeline.d.ts.map +1 -0
- package/build/services/debug/dashboardOpenTimeline.js +195 -0
- package/build/services/debug/dashboardOpenTimeline.js.map +1 -0
- package/build/services/effectiveCapabilities.d.ts.map +1 -1
- package/build/services/effectiveCapabilities.js +25 -13
- package/build/services/effectiveCapabilities.js.map +1 -1
- package/build/services/gestureClaims.d.ts +34 -15
- package/build/services/gestureClaims.d.ts.map +1 -1
- package/build/services/gestureClaims.js +42 -21
- package/build/services/gestureClaims.js.map +1 -1
- package/build/services/manifestFields.d.ts +9 -0
- package/build/services/manifestFields.d.ts.map +1 -0
- package/build/services/manifestFields.js +26 -0
- package/build/services/manifestFields.js.map +1 -0
- package/build/services/memoryStoreInstance.d.ts +0 -10
- package/build/services/memoryStoreInstance.d.ts.map +1 -1
- package/build/services/memoryStoreInstance.js +2 -31
- package/build/services/memoryStoreInstance.js.map +1 -1
- package/build/services/mirrorSnapshot.d.ts +16 -0
- package/build/services/mirrorSnapshot.d.ts.map +1 -0
- package/build/services/mirrorSnapshot.js +102 -0
- package/build/services/mirrorSnapshot.js.map +1 -0
- package/build/services/nativeNavigationGate.d.ts +8 -0
- package/build/services/nativeNavigationGate.d.ts.map +1 -0
- package/build/services/nativeNavigationGate.js +12 -0
- package/build/services/nativeNavigationGate.js.map +1 -0
- package/build/services/notificationAppCatalog.d.ts +7 -0
- package/build/services/notificationAppCatalog.d.ts.map +1 -0
- package/build/services/notificationAppCatalog.js +16 -0
- package/build/services/notificationAppCatalog.js.map +1 -0
- package/build/services/notifications/notificationPolicy.d.ts +55 -0
- package/build/services/notifications/notificationPolicy.d.ts.map +1 -0
- package/build/services/notifications/notificationPolicy.js +41 -0
- package/build/services/notifications/notificationPolicy.js.map +1 -0
- package/build/services/pages/OverlayPages.d.ts +26 -0
- package/build/services/pages/OverlayPages.d.ts.map +1 -0
- package/build/services/pages/OverlayPages.js +80 -0
- package/build/services/pages/OverlayPages.js.map +1 -0
- package/build/services/pages/PageHost.d.ts +32 -0
- package/build/services/pages/PageHost.d.ts.map +1 -0
- package/build/services/pages/PageHost.js +99 -0
- package/build/services/pages/PageHost.js.map +1 -0
- package/build/services/pages/overlayApps.d.ts +25 -0
- package/build/services/pages/overlayApps.d.ts.map +1 -0
- package/build/services/pages/overlayApps.js +66 -0
- package/build/services/pages/overlayApps.js.map +1 -0
- package/build/services/pages/pageEligibility.d.ts +9 -0
- package/build/services/pages/pageEligibility.d.ts.map +1 -0
- package/build/services/pages/pageEligibility.js +27 -0
- package/build/services/pages/pageEligibility.js.map +1 -0
- package/build/services/settingsBridge.d.ts +58 -0
- package/build/services/settingsBridge.d.ts.map +1 -0
- package/build/services/settingsBridge.js +90 -0
- package/build/services/settingsBridge.js.map +1 -0
- package/build/services/speakerProfileStoreInstance.js +1 -1
- package/build/services/speakerProfileStoreInstance.js.map +1 -1
- package/build/services/uiShim.d.ts +1 -1
- package/build/services/uiShim.js +4 -4
- package/build/services/uiShim.js.map +1 -1
- package/build/stores/appVisibility.d.ts +28 -0
- package/build/stores/appVisibility.d.ts.map +1 -1
- package/build/stores/appVisibility.js +34 -0
- package/build/stores/appVisibility.js.map +1 -1
- package/build/stores/apps.d.ts +13 -0
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +66 -12
- package/build/stores/apps.js.map +1 -1
- package/build/stores/bluetoothSettingKeys.js +1 -1
- package/build/stores/bluetoothSettingKeys.js.map +1 -1
- package/build/stores/display.d.ts +3 -3
- package/build/stores/display.d.ts.map +1 -1
- package/build/stores/display.js +16 -4
- package/build/stores/display.js.map +1 -1
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js +14 -1
- package/build/stores/glasses.js.map +1 -1
- package/build/stores/settings.d.ts +1 -0
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +170 -44
- package/build/stores/settings.js.map +1 -1
- package/build/types/applet.d.ts +14 -1
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
- package/build/types/capabilities/even-realities-g2.js +5 -0
- package/build/types/capabilities/even-realities-g2.js.map +1 -1
- package/build/types/capabilities/simulated-glasses.d.ts +1 -1
- package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
- package/build/types/capabilities/simulated-glasses.js +7 -4
- package/build/types/capabilities/simulated-glasses.js.map +1 -1
- package/build/types/hardware.d.ts +20 -1
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +2 -0
- package/build/types/hardware.js.map +1 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js +1 -0
- package/build/types/index.js.map +1 -1
- package/build/utils/debouncedPatch.d.ts +3 -1
- package/build/utils/debouncedPatch.d.ts.map +1 -1
- package/build/utils/debouncedPatch.js +6 -3
- package/build/utils/debouncedPatch.js.map +1 -1
- package/build/utils/devMiniappLaunch.d.ts.map +1 -1
- package/build/utils/devMiniappLaunch.js +4 -3
- package/build/utils/devMiniappLaunch.js.map +1 -1
- package/build/utils/display/measurer/TextMeasurer.d.ts +2 -159
- package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -1
- package/build/utils/display/measurer/TextMeasurer.js +2 -272
- package/build/utils/display/measurer/TextMeasurer.js.map +1 -1
- package/build/utils/display/measurer/script-detection.d.ts +1 -52
- package/build/utils/display/measurer/script-detection.d.ts.map +1 -1
- package/build/utils/display/measurer/script-detection.js +2 -183
- package/build/utils/display/measurer/script-detection.js.map +1 -1
- package/build/utils/display/pixelArt.d.ts +3 -0
- package/build/utils/display/pixelArt.d.ts.map +1 -0
- package/build/utils/display/pixelArt.js +3 -0
- package/build/utils/display/pixelArt.js.map +1 -0
- package/build/utils/display/profiles/g1.d.ts +1 -32
- package/build/utils/display/profiles/g1.d.ts.map +1 -1
- package/build/utils/display/profiles/g1.js +2 -212
- package/build/utils/display/profiles/g1.js.map +1 -1
- package/build/utils/display/profiles/g2.d.ts +1 -12
- package/build/utils/display/profiles/g2.d.ts.map +1 -1
- package/build/utils/display/profiles/g2.js +2 -33
- package/build/utils/display/profiles/g2.js.map +1 -1
- package/build/utils/display/profiles/nex.d.ts +1 -9
- package/build/utils/display/profiles/nex.d.ts.map +1 -1
- package/build/utils/display/profiles/nex.js +2 -149
- package/build/utils/display/profiles/nex.js.map +1 -1
- package/build/utils/display/profiles/types.d.ts +1 -102
- package/build/utils/display/profiles/types.d.ts.map +1 -1
- package/build/utils/display/profiles/types.js.map +1 -1
- package/build/utils/display/profiles/z100.d.ts +1 -32
- package/build/utils/display/profiles/z100.d.ts.map +1 -1
- package/build/utils/display/profiles/z100.js +2 -181
- package/build/utils/display/profiles/z100.js.map +1 -1
- package/build/utils/display/scene/degrade.d.ts.map +1 -1
- package/build/utils/display/scene/degrade.js +4 -1
- package/build/utils/display/scene/degrade.js.map +1 -1
- package/build/utils/display/scene/differ.d.ts +13 -1
- package/build/utils/display/scene/differ.d.ts.map +1 -1
- package/build/utils/display/scene/differ.js +22 -0
- package/build/utils/display/scene/differ.js.map +1 -1
- package/build/utils/display/scene/index.d.ts +1 -1
- package/build/utils/display/scene/index.d.ts.map +1 -1
- package/build/utils/display/scene/index.js.map +1 -1
- package/build/utils/display/scene/process.d.ts.map +1 -1
- package/build/utils/display/scene/process.js +183 -11
- package/build/utils/display/scene/process.js.map +1 -1
- package/build/utils/display/scene/store.d.ts +1 -1
- package/build/utils/display/scene/store.d.ts.map +1 -1
- package/build/utils/display/scene/store.js +0 -0
- package/build/utils/display/scene/store.js.map +1 -1
- package/build/utils/display/scene/svgPath.d.ts +9 -0
- package/build/utils/display/scene/svgPath.d.ts.map +1 -0
- package/build/utils/display/scene/svgPath.js +167 -0
- package/build/utils/display/scene/svgPath.js.map +1 -0
- package/build/utils/display/scene/types.d.ts +2 -142
- package/build/utils/display/scene/types.d.ts.map +1 -1
- package/build/utils/display/scene/types.js +0 -0
- package/build/utils/display/scene/types.js.map +1 -1
- package/build/utils/display/wrapper/TextWrapper.d.ts +1 -101
- package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -1
- package/build/utils/display/wrapper/TextWrapper.js +2 -470
- package/build/utils/display/wrapper/TextWrapper.js.map +1 -1
- package/build/utils/display/wrapper/types.d.ts +2 -74
- package/build/utils/display/wrapper/types.d.ts.map +1 -1
- package/build/utils/display/wrapper/types.js +2 -10
- package/build/utils/display/wrapper/types.js.map +1 -1
- package/build/utils/hardware/hardware.js +1 -1
- package/build/utils/hardware/hardware.js.map +1 -1
- package/build/utils/timers/timers.d.ts.map +1 -1
- package/build/utils/timers/timers.js +26 -4
- package/build/utils/timers/timers.js.map +1 -1
- package/package.json +8 -8
- package/src/engine.ts +24 -15
- package/src/facades/dev.ts +10 -0
- package/src/facades/display.ts +21 -8
- package/src/facades/displayMirror.ts +29 -0
- package/src/facades/glasses.ts +61 -1
- package/src/facades/memory.ts +1 -12
- package/src/facades/miniapps.ts +4 -1
- package/src/facades/pairing.ts +8 -6
- package/src/facades/permissions.ts +46 -0
- package/src/facades/phoneNotifications.ts +45 -26
- package/src/facades/settings.ts +1 -2
- package/src/generated/releaseMetadata.ts +4 -4
- package/src/index.ts +6 -9
- package/src/react/MentraLiveOtaFlow.tsx +2 -2
- package/src/react/useMentraLiveOta.ts +14 -8
- package/src/runtime/config.ts +1 -1
- package/src/services/AppRegistry.ts +43 -7
- package/src/services/BlobStore.ts +3 -3
- package/src/services/CloudClientService.ts +37 -10
- package/src/services/DevServerBridge.ts +12 -10
- package/src/services/DeviceEventRouter.ts +73 -74
- package/src/services/DisplayDiagnostics.ts +107 -0
- package/src/services/DisplayProcessor.ts +20 -55
- package/src/services/GestureDotsService.ts +77 -16
- package/src/services/GlassesKeyboardInput.ts +306 -0
- package/src/services/GlassesSensorService.ts +233 -0
- package/src/services/GlassesTouchInput.ts +128 -0
- package/src/services/HeadingService.ts +0 -24
- package/src/services/HotspotShutdown.ts +3 -1
- package/src/services/JSCrashloopReportService.ts +2 -2
- package/src/services/JSRouter.ts +29 -14
- package/src/services/LocalDisplayManager.ts +112 -26
- package/src/services/LocalMiniappDataMigration.ts +1 -1
- package/src/services/LocalMiniappRuntime.ts +500 -43
- package/src/services/LocalSttFallbackCoordinator.ts +28 -7
- package/src/services/MemoryStore.ts +32 -80
- package/src/services/MiniappEngine.ts +7 -7
- package/src/services/MiniappLauncher.ts +25 -1
- package/src/services/MirrorService.ts +139 -0
- package/src/services/NativeNavigationService.ts +29 -25
- package/src/services/NavigationHandlers.ts +10 -5
- package/src/services/OtaInstallCoordinator.ts +36 -34
- package/src/services/PairedGlassesLatch.ts +39 -0
- package/src/services/PhoneActivity.ts +116 -0
- package/src/services/PhoneCameraFovCoordinator.ts +6 -4
- package/src/services/PhoneNotificationsSync.ts +185 -103
- package/src/services/PhonePhotoCoordinator.ts +9 -10
- package/src/services/PhoneStreamCoordinator.ts +13 -11
- package/src/services/STTModelManager.ts +15 -1
- package/src/services/SceneRenderer.ts +148 -10
- package/src/services/StreamLifecycleController.ts +9 -7
- package/src/services/TTSModelManager.ts +1 -1
- package/src/services/UIRouter.ts +5 -5
- package/src/services/asg/galleryPathMigration.ts +1 -1
- package/src/services/asg/gallerySyncService.ts +2 -2
- package/src/services/asg/localStorageService.ts +3 -3
- package/src/services/debug/DashboardOpenTrace.ts +153 -0
- package/src/services/debug/dashboardOpenTimeline.ts +237 -0
- package/src/services/effectiveCapabilities.ts +32 -13
- package/src/services/gestureClaims.ts +72 -23
- package/src/services/manifestFields.ts +23 -0
- package/src/services/memoryStoreInstance.ts +2 -34
- package/src/services/mirrorSnapshot.ts +116 -0
- package/src/services/nativeNavigationGate.ts +14 -0
- package/src/services/notificationAppCatalog.ts +21 -0
- package/src/services/notifications/notificationPolicy.ts +87 -0
- package/src/services/pages/OverlayPages.ts +86 -0
- package/src/services/pages/PageHost.ts +116 -0
- package/src/services/pages/overlayApps.ts +72 -0
- package/src/services/pages/pageEligibility.ts +30 -0
- package/src/services/settingsBridge.ts +111 -0
- package/src/services/speakerProfileStoreInstance.ts +1 -1
- package/src/services/uiShim.ts +4 -4
- package/src/stores/appVisibility.ts +45 -0
- package/src/stores/apps.ts +110 -32
- package/src/stores/bluetoothSettingKeys.ts +1 -1
- package/src/stores/display.ts +18 -7
- package/src/stores/glasses.ts +15 -1
- package/src/stores/settings.ts +175 -51
- package/src/types/applet.ts +14 -1
- package/src/types/capabilities/even-realities-g2.ts +6 -0
- package/src/types/capabilities/simulated-glasses.ts +8 -4
- package/src/types/hardware.ts +34 -1
- package/src/types/index.ts +1 -0
- package/src/utils/debouncedPatch.ts +8 -4
- package/src/utils/devMiniappLaunch.ts +5 -3
- package/src/utils/display/measurer/TextMeasurer.ts +3 -346
- package/src/utils/display/measurer/script-detection.ts +10 -218
- package/src/utils/display/pixelArt.ts +3 -0
- package/src/utils/display/profiles/g1.ts +2 -236
- package/src/utils/display/profiles/g2.ts +2 -39
- package/src/utils/display/profiles/nex.ts +2 -166
- package/src/utils/display/profiles/types.ts +9 -132
- package/src/utils/display/profiles/z100.ts +2 -198
- package/src/utils/display/scene/degrade.ts +4 -1
- package/src/utils/display/scene/differ.ts +25 -1
- package/src/utils/display/scene/index.ts +5 -0
- package/src/utils/display/scene/process.ts +196 -13
- package/src/utils/display/scene/store.ts +0 -0
- package/src/utils/display/scene/svgPath.ts +163 -0
- package/src/utils/display/scene/types.ts +0 -0
- package/src/utils/display/wrapper/TextWrapper.ts +2 -546
- package/src/utils/display/wrapper/types.ts +3 -102
- package/src/utils/hardware/hardware.ts +1 -1
- package/src/utils/timers/timers.ts +32 -4
- package/build/services/CustomDashboardModel.d.ts +0 -48
- package/build/services/CustomDashboardModel.d.ts.map +0 -1
- package/build/services/CustomDashboardModel.js +0 -73
- package/build/services/CustomDashboardModel.js.map +0 -1
- package/build/services/CustomDashboardService.d.ts +0 -63
- package/build/services/CustomDashboardService.d.ts.map +0 -1
- package/build/services/CustomDashboardService.js +0 -576
- package/build/services/CustomDashboardService.js.map +0 -1
- package/build/services/DashboardCoordinator.d.ts +0 -26
- package/build/services/DashboardCoordinator.d.ts.map +0 -1
- package/build/services/DashboardCoordinator.js +0 -125
- package/build/services/DashboardCoordinator.js.map +0 -1
- package/build/services/iosNotificationAppCatalog.d.ts +0 -13
- package/build/services/iosNotificationAppCatalog.d.ts.map +0 -1
- package/build/services/iosNotificationAppCatalog.js +0 -28
- package/build/services/iosNotificationAppCatalog.js.map +0 -1
- package/src/services/CustomDashboardModel.ts +0 -83
- package/src/services/CustomDashboardService.ts +0 -598
- package/src/services/DashboardCoordinator.ts +0 -121
- package/src/services/iosNotificationAppCatalog.ts +0 -39
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PairedGlassesLatch.d.ts","sourceRoot":"","sources":["../../src/services/PairedGlassesLatch.ts"],"names":[],"mappings":"AAUA,OAAO,EAAmD,KAAK,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAEzG,2FAA2F;AAC3F,eAAO,MAAM,qBAAqB,GAAI,UAAU,gBAAgB,KAAG,OACY,CAAA;AAc/E,oGAAoG;AACpG,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAG7C"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PairedGlassesLatch — records that this phone has, at some point, paired
|
|
3
|
+
* real glasses. Projects the pairing identity (see PairingIdentity) into the
|
|
4
|
+
* one-way `has_paired_glasses` setting: set the first time the identity reads
|
|
5
|
+
* `paired` to a non-simulated model, never cleared. Forgetting the glasses or
|
|
6
|
+
* switching models leaves it on, so what it unlocks (the Store, see
|
|
7
|
+
* stores/appVisibility PAIRED_GLASSES_PACKAGES) stays unlocked.
|
|
8
|
+
*/
|
|
9
|
+
import { useSettingsStore, SETTINGS } from "../stores/settings";
|
|
10
|
+
import { DeviceTypes } from "../types";
|
|
11
|
+
import { projectPairingIdentity, subscribePairingIdentity } from "./PairingIdentity";
|
|
12
|
+
/** Paired to real glasses: the simulated device is its own identity and does not count. */
|
|
13
|
+
export const isPairedToRealGlasses = (identity) => identity.kind === "paired" && !identity.model.includes(DeviceTypes.SIMULATED);
|
|
14
|
+
let unsubscribe = null;
|
|
15
|
+
function latch(identity) {
|
|
16
|
+
if (identity.kind !== "paired" || !isPairedToRealGlasses(identity))
|
|
17
|
+
return;
|
|
18
|
+
const store = useSettingsStore.getState();
|
|
19
|
+
if (store.getSetting(SETTINGS.has_paired_glasses.key) === true)
|
|
20
|
+
return;
|
|
21
|
+
console.log(`PairedGlassesLatch: first real pairing ("${identity.model}") -> has_paired_glasses`);
|
|
22
|
+
void Promise.resolve(store.setSetting(SETTINGS.has_paired_glasses.key, true, false)).then((r) => {
|
|
23
|
+
if (r.is_error())
|
|
24
|
+
console.warn("PairedGlassesLatch: failed to persist has_paired_glasses:", r.error);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Start after the persisted settings are loaded so an already-paired phone latches immediately. */
|
|
28
|
+
export function startPairedGlassesLatch() {
|
|
29
|
+
if (unsubscribe)
|
|
30
|
+
return;
|
|
31
|
+
latch(projectPairingIdentity());
|
|
32
|
+
unsubscribe = subscribePairingIdentity(latch);
|
|
33
|
+
}
|
|
34
|
+
export function stopPairedGlassesLatch() {
|
|
35
|
+
unsubscribe?.();
|
|
36
|
+
unsubscribe = null;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=PairedGlassesLatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PairedGlassesLatch.js","sourceRoot":"","sources":["../../src/services/PairedGlassesLatch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAC,gBAAgB,EAAE,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAC,WAAW,EAAC,MAAM,UAAU,CAAA;AACpC,OAAO,EAAC,sBAAsB,EAAE,wBAAwB,EAAwB,MAAM,mBAAmB,CAAA;AAEzG,2FAA2F;AAC3F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,QAA0B,EAAW,EAAE,CAC3E,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;AAE/E,IAAI,WAAW,GAAwB,IAAI,CAAA;AAE3C,SAAS,KAAK,CAAC,QAA0B;IACvC,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC;QAAE,OAAM;IAC1E,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAA;IACzC,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,IAAI;QAAE,OAAM;IACtE,OAAO,CAAC,GAAG,CAAC,4CAA4C,QAAQ,CAAC,KAAK,0BAA0B,CAAC,CAAA;IACjG,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QAC9F,IAAI,CAAC,CAAC,QAAQ,EAAE;YAAE,OAAO,CAAC,IAAI,CAAC,2DAA2D,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;IACtG,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,uBAAuB;IACrC,IAAI,WAAW;QAAE,OAAM;IACvB,KAAK,CAAC,sBAAsB,EAAE,CAAC,CAAA;IAC/B,WAAW,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,WAAW,EAAE,EAAE,CAAA;IACf,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC","sourcesContent":["/**\n * PairedGlassesLatch — records that this phone has, at some point, paired\n * real glasses. Projects the pairing identity (see PairingIdentity) into the\n * one-way `has_paired_glasses` setting: set the first time the identity reads\n * `paired` to a non-simulated model, never cleared. Forgetting the glasses or\n * switching models leaves it on, so what it unlocks (the Store, see\n * stores/appVisibility PAIRED_GLASSES_PACKAGES) stays unlocked.\n */\nimport {useSettingsStore, SETTINGS} from \"../stores/settings\"\nimport {DeviceTypes} from \"../types\"\nimport {projectPairingIdentity, subscribePairingIdentity, type IdentitySnapshot} from \"./PairingIdentity\"\n\n/** Paired to real glasses: the simulated device is its own identity and does not count. */\nexport const isPairedToRealGlasses = (identity: IdentitySnapshot): boolean =>\n identity.kind === \"paired\" && !identity.model.includes(DeviceTypes.SIMULATED)\n\nlet unsubscribe: (() => void) | null = null\n\nfunction latch(identity: IdentitySnapshot): void {\n if (identity.kind !== \"paired\" || !isPairedToRealGlasses(identity)) return\n const store = useSettingsStore.getState()\n if (store.getSetting(SETTINGS.has_paired_glasses.key) === true) return\n console.log(`PairedGlassesLatch: first real pairing (\"${identity.model}\") -> has_paired_glasses`)\n void Promise.resolve(store.setSetting(SETTINGS.has_paired_glasses.key, true, false)).then((r) => {\n if (r.is_error()) console.warn(\"PairedGlassesLatch: failed to persist has_paired_glasses:\", r.error)\n })\n}\n\n/** Start after the persisted settings are loaded so an already-paired phone latches immediately. */\nexport function startPairedGlassesLatch(): void {\n if (unsubscribe) return\n latch(projectPairingIdentity())\n unsubscribe = subscribePairingIdentity(latch)\n}\n\nexport function stopPairedGlassesLatch(): void {\n unsubscribe?.()\n unsubscribe = null\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { PhoneLockState } from "@glassly/crust";
|
|
2
|
+
type Listener = (active: boolean) => void;
|
|
3
|
+
/**
|
|
4
|
+
* A foregrounded app is proof on its own. Without a passcode the platform lock
|
|
5
|
+
* signal is meaningless (iOS reports protected data as always available), so
|
|
6
|
+
* only the foreground gate applies there.
|
|
7
|
+
*/
|
|
8
|
+
export declare function computePhoneActive(lock: PhoneLockState, foregrounded: boolean): boolean;
|
|
9
|
+
export declare function isPhoneActive(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Whether the Glassly App itself is foregrounded, independent of the lock
|
|
12
|
+
* state that `isPhoneActive()` folds in. Background execution limits (timer
|
|
13
|
+
* coalescing, BLE pacing) follow this bit alone: a backgrounded app on an
|
|
14
|
+
* unlocked phone is still a backgrounded app.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isAppForegrounded(): boolean;
|
|
17
|
+
/** Fires on app foreground/background transitions only. See `isAppForegrounded`. */
|
|
18
|
+
export declare function onAppForegroundChange(listener: Listener): () => void;
|
|
19
|
+
export declare function onPhoneActivityChange(listener: Listener): () => void;
|
|
20
|
+
export declare function startPhoneActivityTracking(): void;
|
|
21
|
+
export declare function stopPhoneActivityTracking(): void;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=PhoneActivity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PhoneActivity.d.ts","sourceRoot":"","sources":["../../src/services/PhoneActivity.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,gBAAgB,CAAA;AAElD,KAAK,QAAQ,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;AAazC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAIvF;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI,CAKpE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI,CAKpE;AA2BD,wBAAgB,0BAA0B,IAAI,IAAI,CAUjD;AAED,wBAAgB,yBAAyB,IAAI,IAAI,CAShD"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phone activity — engine-owned, both platforms. Started by `engine.start()`.
|
|
3
|
+
*
|
|
4
|
+
* "Active" means the wearer can see the phone: the Glassly App is in the
|
|
5
|
+
* foreground, or the phone is unlocked. Crust reports lock state as
|
|
6
|
+
* `phone_lock_state` (iOS: protected-data availability; Android: screen on and
|
|
7
|
+
* keyguard hidden); React Native reports foregrounding. Consumers read
|
|
8
|
+
* `isPhoneActive()` at decision time — the dashboard reducer when a
|
|
9
|
+
* notification posts — and `onPhoneActivityChange` serves those that have to
|
|
10
|
+
* push the state somewhere, like the stock G2 firmware's notification ctrl.
|
|
11
|
+
*/
|
|
12
|
+
import { AppState } from "react-native";
|
|
13
|
+
import CrustModule from "@glassly/crust";
|
|
14
|
+
let started = false;
|
|
15
|
+
let lockStateSubscription = null;
|
|
16
|
+
let appStateSubscription = null;
|
|
17
|
+
const listeners = new Set();
|
|
18
|
+
const foregroundListeners = new Set();
|
|
19
|
+
// Until native answers, assume locked so a failed query never reads as active.
|
|
20
|
+
const ASSUMED_LOCKED = { unlocked: false, passcodeSet: true };
|
|
21
|
+
let phoneLock = ASSUMED_LOCKED;
|
|
22
|
+
let appForegrounded = false;
|
|
23
|
+
/**
|
|
24
|
+
* A foregrounded app is proof on its own. Without a passcode the platform lock
|
|
25
|
+
* signal is meaningless (iOS reports protected data as always available), so
|
|
26
|
+
* only the foreground gate applies there.
|
|
27
|
+
*/
|
|
28
|
+
export function computePhoneActive(lock, foregrounded) {
|
|
29
|
+
if (foregrounded)
|
|
30
|
+
return true;
|
|
31
|
+
if (!lock.passcodeSet)
|
|
32
|
+
return false;
|
|
33
|
+
return lock.unlocked;
|
|
34
|
+
}
|
|
35
|
+
export function isPhoneActive() {
|
|
36
|
+
return computePhoneActive(phoneLock, appForegrounded);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Whether the Glassly App itself is foregrounded, independent of the lock
|
|
40
|
+
* state that `isPhoneActive()` folds in. Background execution limits (timer
|
|
41
|
+
* coalescing, BLE pacing) follow this bit alone: a backgrounded app on an
|
|
42
|
+
* unlocked phone is still a backgrounded app.
|
|
43
|
+
*/
|
|
44
|
+
export function isAppForegrounded() {
|
|
45
|
+
return appForegrounded;
|
|
46
|
+
}
|
|
47
|
+
/** Fires on app foreground/background transitions only. See `isAppForegrounded`. */
|
|
48
|
+
export function onAppForegroundChange(listener) {
|
|
49
|
+
foregroundListeners.add(listener);
|
|
50
|
+
return () => {
|
|
51
|
+
foregroundListeners.delete(listener);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function onPhoneActivityChange(listener) {
|
|
55
|
+
listeners.add(listener);
|
|
56
|
+
return () => {
|
|
57
|
+
listeners.delete(listener);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function update(next) {
|
|
61
|
+
const before = isPhoneActive();
|
|
62
|
+
const foregroundBefore = appForegrounded;
|
|
63
|
+
if (next.lock)
|
|
64
|
+
phoneLock = next.lock;
|
|
65
|
+
if (next.foregrounded !== undefined)
|
|
66
|
+
appForegrounded = next.foregrounded;
|
|
67
|
+
if (appForegrounded !== foregroundBefore) {
|
|
68
|
+
for (const listener of Array.from(foregroundListeners))
|
|
69
|
+
listener(appForegrounded);
|
|
70
|
+
}
|
|
71
|
+
const after = isPhoneActive();
|
|
72
|
+
if (after === before)
|
|
73
|
+
return;
|
|
74
|
+
for (const listener of Array.from(listeners))
|
|
75
|
+
listener(after);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A suspended app misses lock events, so the state is re-read whenever the
|
|
79
|
+
* app changes foreground state, not only at start.
|
|
80
|
+
*/
|
|
81
|
+
function refreshLockState() {
|
|
82
|
+
void Promise.resolve(CrustModule.getPhoneLockState())
|
|
83
|
+
.then((state) => {
|
|
84
|
+
if (started)
|
|
85
|
+
update({ lock: state });
|
|
86
|
+
})
|
|
87
|
+
.catch((err) => console.warn(`PhoneActivity: getPhoneLockState failed: ${err?.message ?? err}`));
|
|
88
|
+
}
|
|
89
|
+
export function startPhoneActivityTracking() {
|
|
90
|
+
if (started)
|
|
91
|
+
return;
|
|
92
|
+
started = true;
|
|
93
|
+
appForegrounded = AppState.currentState === "active";
|
|
94
|
+
lockStateSubscription = CrustModule.addListener("phone_lock_state", (state) => update({ lock: state }));
|
|
95
|
+
appStateSubscription = AppState.addEventListener("change", (next) => {
|
|
96
|
+
update({ foregrounded: next === "active" });
|
|
97
|
+
refreshLockState();
|
|
98
|
+
});
|
|
99
|
+
refreshLockState();
|
|
100
|
+
}
|
|
101
|
+
export function stopPhoneActivityTracking() {
|
|
102
|
+
started = false;
|
|
103
|
+
lockStateSubscription?.remove();
|
|
104
|
+
lockStateSubscription = null;
|
|
105
|
+
appStateSubscription?.remove();
|
|
106
|
+
appStateSubscription = null;
|
|
107
|
+
phoneLock = ASSUMED_LOCKED;
|
|
108
|
+
appForegrounded = false;
|
|
109
|
+
foregroundListeners.clear();
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=PhoneActivity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PhoneActivity.js","sourceRoot":"","sources":["../../src/services/PhoneActivity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Phone activity — engine-owned, both platforms. Started by `engine.start()`.\n *\n * \"Active\" means the wearer can see the phone: the Glassly App is in the\n * foreground, or the phone is unlocked. Crust reports lock state as\n * `phone_lock_state` (iOS: protected-data availability; Android: screen on and\n * keyguard hidden); React Native reports foregrounding. Consumers read\n * `isPhoneActive()` at decision time — the dashboard reducer when a\n * notification posts — and `onPhoneActivityChange` serves those that have to\n * push the state somewhere, like the stock G2 firmware's notification ctrl.\n */\nimport {AppState} from \"react-native\"\nimport type {AppStateStatus} from \"react-native\"\nimport CrustModule from \"@glassly/crust\"\nimport type {PhoneLockState} from \"@glassly/crust\"\n\ntype Listener = (active: boolean) => void\n\nlet started = false\nlet lockStateSubscription: {remove(): void} | null = null\nlet appStateSubscription: {remove(): void} | null = null\nconst listeners = new Set<Listener>()\nconst foregroundListeners = new Set<Listener>()\n\n// Until native answers, assume locked so a failed query never reads as active.\nconst ASSUMED_LOCKED: PhoneLockState = {unlocked: false, passcodeSet: true}\nlet phoneLock: PhoneLockState = ASSUMED_LOCKED\nlet appForegrounded = false\n\n/**\n * A foregrounded app is proof on its own. Without a passcode the platform lock\n * signal is meaningless (iOS reports protected data as always available), so\n * only the foreground gate applies there.\n */\nexport function computePhoneActive(lock: PhoneLockState, foregrounded: boolean): boolean {\n if (foregrounded) return true\n if (!lock.passcodeSet) return false\n return lock.unlocked\n}\n\nexport function isPhoneActive(): boolean {\n return computePhoneActive(phoneLock, appForegrounded)\n}\n\n/**\n * Whether the Glassly App itself is foregrounded, independent of the lock\n * state that `isPhoneActive()` folds in. Background execution limits (timer\n * coalescing, BLE pacing) follow this bit alone: a backgrounded app on an\n * unlocked phone is still a backgrounded app.\n */\nexport function isAppForegrounded(): boolean {\n return appForegrounded\n}\n\n/** Fires on app foreground/background transitions only. See `isAppForegrounded`. */\nexport function onAppForegroundChange(listener: Listener): () => void {\n foregroundListeners.add(listener)\n return () => {\n foregroundListeners.delete(listener)\n }\n}\n\nexport function onPhoneActivityChange(listener: Listener): () => void {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n}\n\nfunction update(next: {lock?: PhoneLockState; foregrounded?: boolean}): void {\n const before = isPhoneActive()\n const foregroundBefore = appForegrounded\n if (next.lock) phoneLock = next.lock\n if (next.foregrounded !== undefined) appForegrounded = next.foregrounded\n if (appForegrounded !== foregroundBefore) {\n for (const listener of Array.from(foregroundListeners)) listener(appForegrounded)\n }\n const after = isPhoneActive()\n if (after === before) return\n for (const listener of Array.from(listeners)) listener(after)\n}\n\n/**\n * A suspended app misses lock events, so the state is re-read whenever the\n * app changes foreground state, not only at start.\n */\nfunction refreshLockState(): void {\n void Promise.resolve(CrustModule.getPhoneLockState())\n .then((state) => {\n if (started) update({lock: state})\n })\n .catch((err: unknown) => console.warn(`PhoneActivity: getPhoneLockState failed: ${(err as Error)?.message ?? err}`))\n}\n\nexport function startPhoneActivityTracking(): void {\n if (started) return\n started = true\n appForegrounded = AppState.currentState === \"active\"\n lockStateSubscription = CrustModule.addListener(\"phone_lock_state\", (state: PhoneLockState) => update({lock: state}))\n appStateSubscription = AppState.addEventListener(\"change\", (next: AppStateStatus) => {\n update({foregrounded: next === \"active\"})\n refreshLockState()\n })\n refreshLockState()\n}\n\nexport function stopPhoneActivityTracking(): void {\n started = false\n lockStateSubscription?.remove()\n lockStateSubscription = null\n appStateSubscription?.remove()\n appStateSubscription = null\n phoneLock = ASSUMED_LOCKED\n appForegrounded = false\n foregroundListeners.clear()\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhoneCameraFovCoordinator.d.ts","sourceRoot":"","sources":["../../src/services/PhoneCameraFovCoordinator.ts"],"names":[],"mappings":"AAAA,OAAqB,EAAC,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAC,MAAM,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"PhoneCameraFovCoordinator.d.ts","sourceRoot":"","sources":["../../src/services/PhoneCameraFovCoordinator.ts"],"names":[],"mappings":"AAAA,OAAqB,EAAC,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAC,MAAM,iCAAiC,CAAA;AAIzG,eAAO,MAAM,0BAA0B,SAAU,CAAA;AACjD,eAAO,MAAM,8BAA8B,SAAU,CAAA;AAyBrD;;;;GAIG;AACH,qBAAa,yBAAyB;IAQxB,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAPlD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAC7D,OAAO,CAAC,gBAAgB,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,UAAU,CAAQ;gBAEG,qBAAqB,SAAkC;IAEpF,mEAAmE;IACnE,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAchD,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAkCrF,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoDjD,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,YAAY;YAKN,iBAAiB;YAkBjB,cAAc;IAM5B,OAAO,CAAC,0BAA0B;IAKlC,OAAO,CAAC,OAAO;CAQhB;AAED,eAAO,MAAM,yBAAyB,2BAAkC,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BluetoothSdk from "@glassly/bluetooth-sdk/internal";
|
|
2
|
+
import { BgTimer } from "../utils/timers";
|
|
2
3
|
export const CAMERA_FOV_OVERRIDE_TTL_MS = 300_000;
|
|
3
4
|
export const CAMERA_FOV_OVERRIDE_REFRESH_MS = 120_000;
|
|
4
5
|
// Legacy ASG clients restart the camera HAL for an FOV update but cannot acknowledge
|
|
@@ -140,7 +141,7 @@ export class PhoneCameraFovCoordinator {
|
|
|
140
141
|
const leaseId = this.effectiveLeaseId;
|
|
141
142
|
if (!leaseId)
|
|
142
143
|
return;
|
|
143
|
-
this.refreshTimer = setTimeout(() => {
|
|
144
|
+
this.refreshTimer = BgTimer.setTimeout(() => {
|
|
144
145
|
void this.enqueue(async () => {
|
|
145
146
|
if (this.effectiveLeaseId !== leaseId)
|
|
146
147
|
return;
|
|
@@ -159,7 +160,7 @@ export class PhoneCameraFovCoordinator {
|
|
|
159
160
|
}
|
|
160
161
|
clearRefresh() {
|
|
161
162
|
if (this.refreshTimer)
|
|
162
|
-
clearTimeout(this.refreshTimer);
|
|
163
|
+
BgTimer.clearTimeout(this.refreshTimer);
|
|
163
164
|
this.refreshTimer = undefined;
|
|
164
165
|
}
|
|
165
166
|
async setLegacyOverride(packageName, request, leaseId, order) {
|
|
@@ -182,7 +183,7 @@ export class PhoneCameraFovCoordinator {
|
|
|
182
183
|
waitForLegacyCameraRestart() {
|
|
183
184
|
if (this.legacyRestartSettleMs <= 0)
|
|
184
185
|
return Promise.resolve();
|
|
185
|
-
return new Promise((resolve) => setTimeout(resolve, this.legacyRestartSettleMs));
|
|
186
|
+
return new Promise((resolve) => BgTimer.setTimeout(resolve, this.legacyRestartSettleMs));
|
|
186
187
|
}
|
|
187
188
|
enqueue(operation) {
|
|
188
189
|
const result = this.queue.then(operation, operation);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhoneCameraFovCoordinator.js","sourceRoot":"","sources":["../../src/services/PhoneCameraFovCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import BluetoothSdk, {type CameraFovRequest, type CameraFovResult} from \"@glassly/bluetooth-sdk/internal\"\n\nexport const CAMERA_FOV_OVERRIDE_TTL_MS = 300_000\nexport const CAMERA_FOV_OVERRIDE_REFRESH_MS = 120_000\n// Legacy ASG clients restart the camera HAL for an FOV update but cannot acknowledge\n// when it is usable again. The ASG cooldown is 5s; retain a small settling margin so\n// miniapps cannot submit a photo against the stale camera service.\nconst LEGACY_CAMERA_RESTART_SETTLE_MS = 7_000\n\ninterface OverrideEntry {\n leaseId: string\n fov: number\n roiPosition: \"center\" | \"bottom\" | \"top\"\n order: number\n}\n\nlet leaseCounter = 0\n\nfunction mintLeaseId(): string {\n leaseCounter = (leaseCounter + 1) & 0xffff\n return `fov-${leaseCounter.toString(16).padStart(4, \"0\")}`\n}\n\nfunction isLegacyFovCompatibilityError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error)\n return /timed out waiting for glasses response|not available|unknown method/i.test(message)\n}\n\n/**\n * Serializes miniapp-owned FOV/ROI overrides. The last live owner wins; releasing it applies the\n * previous owner or asks ASG to restore its persistent base. ASG refreshes are no-restart TTL\n * extensions for crash safety.\n */\nexport class PhoneCameraFovCoordinator {\n private readonly overrides = new Map<string, OverrideEntry>()\n private effectiveLeaseId: string | undefined\n private sequence = 0\n private queue: Promise<unknown> = Promise.resolve()\n private refreshTimer: ReturnType<typeof setTimeout> | undefined\n private legacyMode = false\n\n constructor(private readonly legacyRestartSettleMs = LEGACY_CAMERA_RESTART_SETTLE_MS) {}\n\n /** Report-safe FOV ownership snapshot for incident diagnostics. */\n getDiagnosticSnapshot(): Record<string, unknown> {\n return {\n owners: [...this.overrides.entries()]\n .sort(([, a], [, b]) => b.order - a.order)\n .map(([packageName, entry]) => ({\n packageName,\n effective: entry.leaseId === this.effectiveLeaseId,\n fov: entry.fov,\n roiPosition: entry.roiPosition,\n })),\n legacyMode: this.legacyMode,\n }\n }\n\n setOverride(packageName: string, request: CameraFovRequest): Promise<CameraFovResult> {\n return this.enqueue(async () => {\n const previous = this.overrides.get(packageName)\n const leaseId = previous?.leaseId ?? mintLeaseId()\n const order = ++this.sequence\n try {\n if (this.legacyMode) return this.setLegacyOverride(packageName, request, leaseId, order)\n const result = await BluetoothSdk.setCameraFovOverride({\n ...request,\n leaseId,\n ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,\n })\n this.overrides.set(packageName, {\n leaseId,\n fov: result.fov,\n roiPosition: result.roiPosition,\n order,\n })\n this.effectiveLeaseId = leaseId\n this.scheduleRefresh()\n return result\n } catch (error) {\n if (!isLegacyFovCompatibilityError(error)) throw error\n console.warn(\"[PhoneCameraFovCoordinator] override unavailable; using legacy FOV command\", error)\n const result = await this.setLegacyOverride(packageName, request, leaseId, order)\n // Only cache compatibility mode after the fallback itself succeeds. A\n // disconnect or missing native bridge must not permanently downgrade\n // future requests on a healthy/newer glasses connection.\n this.legacyMode = true\n return result\n }\n })\n }\n\n releaseForApp(packageName: string): Promise<void> {\n return this.enqueue(async () => {\n const removed = this.overrides.get(packageName)\n if (!removed) return\n if (removed.leaseId !== this.effectiveLeaseId) {\n this.overrides.delete(packageName)\n return\n }\n\n const next = [...this.overrides.entries()]\n .filter(([candidatePackage]) => candidatePackage !== packageName)\n .map(([, entry]) => entry)\n .sort((a, b) => b.order - a.order)[0]\n if (this.legacyMode) {\n if (next) {\n await this.applyLegacyFov({fov: next.fov, roiPosition: next.roiPosition})\n this.overrides.delete(packageName)\n this.effectiveLeaseId = next.leaseId\n } else {\n // Legacy commands are one-way and have no lease-release protocol.\n // Ask native to replay its unchanged persistent base setting, then\n // probe the modern override path again for the next ownership cycle.\n await BluetoothSdk.restoreLegacyCameraFov()\n await this.waitForLegacyCameraRestart()\n this.overrides.delete(packageName)\n this.clearRefresh()\n this.effectiveLeaseId = undefined\n this.legacyMode = false\n }\n return\n }\n if (next) {\n await BluetoothSdk.setCameraFovOverride({\n leaseId: next.leaseId,\n fov: next.fov,\n roiPosition: next.roiPosition,\n ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,\n })\n // Commit phone-side ownership only after ASG accepted the replacement. On failure the\n // closing app remains effective here, allowing unregister/reconnect cleanup to retry.\n this.overrides.delete(packageName)\n this.effectiveLeaseId = next.leaseId\n this.scheduleRefresh()\n } else {\n await BluetoothSdk.releaseCameraFovOverride(removed.leaseId)\n this.overrides.delete(packageName)\n this.clearRefresh()\n this.effectiveLeaseId = undefined\n }\n })\n }\n\n private scheduleRefresh(): void {\n if (this.legacyMode) return\n this.clearRefresh()\n const leaseId = this.effectiveLeaseId\n if (!leaseId) return\n this.refreshTimer = setTimeout(() => {\n void this.enqueue(async () => {\n if (this.effectiveLeaseId !== leaseId) return\n const entry = [...this.overrides.values()].find((candidate) => candidate.leaseId === leaseId)\n if (!entry) return\n await BluetoothSdk.setCameraFovOverride({\n leaseId,\n fov: entry.fov,\n roiPosition: entry.roiPosition,\n ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,\n })\n this.scheduleRefresh()\n }).catch((error) => console.warn(\"[PhoneCameraFovCoordinator] failed to refresh override\", error))\n }, CAMERA_FOV_OVERRIDE_REFRESH_MS)\n }\n\n private clearRefresh(): void {\n if (this.refreshTimer) clearTimeout(this.refreshTimer)\n this.refreshTimer = undefined\n }\n\n private async setLegacyOverride(\n packageName: string,\n request: CameraFovRequest,\n leaseId: string,\n order: number,\n ): Promise<CameraFovResult> {\n const result = await this.applyLegacyFov(request)\n this.overrides.set(packageName, {\n leaseId,\n fov: result.fov,\n roiPosition: result.roiPosition,\n order,\n })\n this.effectiveLeaseId = leaseId\n this.clearRefresh()\n return result\n }\n\n private async applyLegacyFov(request: CameraFovRequest): Promise<CameraFovResult> {\n const result = await BluetoothSdk.setLegacyCameraFov(request)\n await this.waitForLegacyCameraRestart()\n return result\n }\n\n private waitForLegacyCameraRestart(): Promise<void> {\n if (this.legacyRestartSettleMs <= 0) return Promise.resolve()\n return new Promise<void>((resolve) => setTimeout(resolve, this.legacyRestartSettleMs))\n }\n\n private enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.queue.then(operation, operation)\n this.queue = result.then(\n () => undefined,\n () => undefined,\n )\n return result\n }\n}\n\nexport const phoneCameraFovCoordinator = new PhoneCameraFovCoordinator()\n"]}
|
|
1
|
+
{"version":3,"file":"PhoneCameraFovCoordinator.js","sourceRoot":"","sources":["../../src/services/PhoneCameraFovCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import BluetoothSdk, {type CameraFovRequest, type CameraFovResult} from \"@glassly/bluetooth-sdk/internal\"\n\nimport {BgTimer} from \"../utils/timers\"\n\nexport const CAMERA_FOV_OVERRIDE_TTL_MS = 300_000\nexport const CAMERA_FOV_OVERRIDE_REFRESH_MS = 120_000\n// Legacy ASG clients restart the camera HAL for an FOV update but cannot acknowledge\n// when it is usable again. The ASG cooldown is 5s; retain a small settling margin so\n// miniapps cannot submit a photo against the stale camera service.\nconst LEGACY_CAMERA_RESTART_SETTLE_MS = 7_000\n\ninterface OverrideEntry {\n leaseId: string\n fov: number\n roiPosition: \"center\" | \"bottom\" | \"top\"\n order: number\n}\n\nlet leaseCounter = 0\n\nfunction mintLeaseId(): string {\n leaseCounter = (leaseCounter + 1) & 0xffff\n return `fov-${leaseCounter.toString(16).padStart(4, \"0\")}`\n}\n\nfunction isLegacyFovCompatibilityError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error)\n return /timed out waiting for glasses response|not available|unknown method/i.test(message)\n}\n\n/**\n * Serializes miniapp-owned FOV/ROI overrides. The last live owner wins; releasing it applies the\n * previous owner or asks ASG to restore its persistent base. ASG refreshes are no-restart TTL\n * extensions for crash safety.\n */\nexport class PhoneCameraFovCoordinator {\n private readonly overrides = new Map<string, OverrideEntry>()\n private effectiveLeaseId: string | undefined\n private sequence = 0\n private queue: Promise<unknown> = Promise.resolve()\n private refreshTimer: number | undefined\n private legacyMode = false\n\n constructor(private readonly legacyRestartSettleMs = LEGACY_CAMERA_RESTART_SETTLE_MS) {}\n\n /** Report-safe FOV ownership snapshot for incident diagnostics. */\n getDiagnosticSnapshot(): Record<string, unknown> {\n return {\n owners: [...this.overrides.entries()]\n .sort(([, a], [, b]) => b.order - a.order)\n .map(([packageName, entry]) => ({\n packageName,\n effective: entry.leaseId === this.effectiveLeaseId,\n fov: entry.fov,\n roiPosition: entry.roiPosition,\n })),\n legacyMode: this.legacyMode,\n }\n }\n\n setOverride(packageName: string, request: CameraFovRequest): Promise<CameraFovResult> {\n return this.enqueue(async () => {\n const previous = this.overrides.get(packageName)\n const leaseId = previous?.leaseId ?? mintLeaseId()\n const order = ++this.sequence\n try {\n if (this.legacyMode) return this.setLegacyOverride(packageName, request, leaseId, order)\n const result = await BluetoothSdk.setCameraFovOverride({\n ...request,\n leaseId,\n ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,\n })\n this.overrides.set(packageName, {\n leaseId,\n fov: result.fov,\n roiPosition: result.roiPosition,\n order,\n })\n this.effectiveLeaseId = leaseId\n this.scheduleRefresh()\n return result\n } catch (error) {\n if (!isLegacyFovCompatibilityError(error)) throw error\n console.warn(\"[PhoneCameraFovCoordinator] override unavailable; using legacy FOV command\", error)\n const result = await this.setLegacyOverride(packageName, request, leaseId, order)\n // Only cache compatibility mode after the fallback itself succeeds. A\n // disconnect or missing native bridge must not permanently downgrade\n // future requests on a healthy/newer glasses connection.\n this.legacyMode = true\n return result\n }\n })\n }\n\n releaseForApp(packageName: string): Promise<void> {\n return this.enqueue(async () => {\n const removed = this.overrides.get(packageName)\n if (!removed) return\n if (removed.leaseId !== this.effectiveLeaseId) {\n this.overrides.delete(packageName)\n return\n }\n\n const next = [...this.overrides.entries()]\n .filter(([candidatePackage]) => candidatePackage !== packageName)\n .map(([, entry]) => entry)\n .sort((a, b) => b.order - a.order)[0]\n if (this.legacyMode) {\n if (next) {\n await this.applyLegacyFov({fov: next.fov, roiPosition: next.roiPosition})\n this.overrides.delete(packageName)\n this.effectiveLeaseId = next.leaseId\n } else {\n // Legacy commands are one-way and have no lease-release protocol.\n // Ask native to replay its unchanged persistent base setting, then\n // probe the modern override path again for the next ownership cycle.\n await BluetoothSdk.restoreLegacyCameraFov()\n await this.waitForLegacyCameraRestart()\n this.overrides.delete(packageName)\n this.clearRefresh()\n this.effectiveLeaseId = undefined\n this.legacyMode = false\n }\n return\n }\n if (next) {\n await BluetoothSdk.setCameraFovOverride({\n leaseId: next.leaseId,\n fov: next.fov,\n roiPosition: next.roiPosition,\n ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,\n })\n // Commit phone-side ownership only after ASG accepted the replacement. On failure the\n // closing app remains effective here, allowing unregister/reconnect cleanup to retry.\n this.overrides.delete(packageName)\n this.effectiveLeaseId = next.leaseId\n this.scheduleRefresh()\n } else {\n await BluetoothSdk.releaseCameraFovOverride(removed.leaseId)\n this.overrides.delete(packageName)\n this.clearRefresh()\n this.effectiveLeaseId = undefined\n }\n })\n }\n\n private scheduleRefresh(): void {\n if (this.legacyMode) return\n this.clearRefresh()\n const leaseId = this.effectiveLeaseId\n if (!leaseId) return\n this.refreshTimer = BgTimer.setTimeout(() => {\n void this.enqueue(async () => {\n if (this.effectiveLeaseId !== leaseId) return\n const entry = [...this.overrides.values()].find((candidate) => candidate.leaseId === leaseId)\n if (!entry) return\n await BluetoothSdk.setCameraFovOverride({\n leaseId,\n fov: entry.fov,\n roiPosition: entry.roiPosition,\n ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,\n })\n this.scheduleRefresh()\n }).catch((error) => console.warn(\"[PhoneCameraFovCoordinator] failed to refresh override\", error))\n }, CAMERA_FOV_OVERRIDE_REFRESH_MS)\n }\n\n private clearRefresh(): void {\n if (this.refreshTimer) BgTimer.clearTimeout(this.refreshTimer)\n this.refreshTimer = undefined\n }\n\n private async setLegacyOverride(\n packageName: string,\n request: CameraFovRequest,\n leaseId: string,\n order: number,\n ): Promise<CameraFovResult> {\n const result = await this.applyLegacyFov(request)\n this.overrides.set(packageName, {\n leaseId,\n fov: result.fov,\n roiPosition: result.roiPosition,\n order,\n })\n this.effectiveLeaseId = leaseId\n this.clearRefresh()\n return result\n }\n\n private async applyLegacyFov(request: CameraFovRequest): Promise<CameraFovResult> {\n const result = await BluetoothSdk.setLegacyCameraFov(request)\n await this.waitForLegacyCameraRestart()\n return result\n }\n\n private waitForLegacyCameraRestart(): Promise<void> {\n if (this.legacyRestartSettleMs <= 0) return Promise.resolve()\n return new Promise<void>((resolve) => BgTimer.setTimeout(resolve, this.legacyRestartSettleMs))\n }\n\n private enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.queue.then(operation, operation)\n this.queue = result.then(\n () => undefined,\n () => undefined,\n )\n return result\n }\n}\n\nexport const phoneCameraFovCoordinator = new PhoneCameraFovCoordinator()\n"]}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PhoneNotificationEvent } from "@glassly/crust";
|
|
2
|
+
import type { GlassesNotificationConfig } from "@glassly/bluetooth-sdk";
|
|
3
|
+
import { type NotificationApp, type PresentationOwner } from "./notifications/notificationPolicy";
|
|
4
|
+
export type { PresentationOwner };
|
|
2
5
|
export interface SeenNotificationApp {
|
|
3
6
|
appId: string;
|
|
4
7
|
displayName: string;
|
|
@@ -6,11 +9,42 @@ export interface SeenNotificationApp {
|
|
|
6
9
|
}
|
|
7
10
|
export declare function getSeenNotificationApps(): SeenNotificationApp[];
|
|
8
11
|
/** Catalog ∪ seen apps, seen display names winning. Sorted by name. */
|
|
9
|
-
export declare function getKnownNotificationApps():
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
export declare function getKnownNotificationApps(): NotificationApp[];
|
|
13
|
+
/**
|
|
14
|
+
* Apps to show in a notification filter UI (package/bundle id, name, icon).
|
|
15
|
+
* Android: installed apps. iOS: seeded catalog ∪ glasses-reported apps
|
|
16
|
+
* (icons unavailable — iOS offers no cross-app icon lookup).
|
|
17
|
+
*/
|
|
18
|
+
export declare function installedNotificationApps(): Promise<Array<{
|
|
19
|
+
packageName: string;
|
|
20
|
+
appName: string;
|
|
21
|
+
icon: string | null;
|
|
22
|
+
}>>;
|
|
23
|
+
/** The connected (or remembered) model presents notifications in firmware. */
|
|
24
|
+
export declare function nativeNotificationsSupported(): boolean;
|
|
25
|
+
/** Popup durations the firmware accepts, or an empty list when it takes any. */
|
|
26
|
+
export declare function nativeNotificationPopupSeconds(): number[];
|
|
27
|
+
export declare function notificationsEnabled(): boolean;
|
|
28
|
+
export declare function desiredGlassesNotificationConfig(): GlassesNotificationConfig;
|
|
29
|
+
/**
|
|
30
|
+
* Who presents the next phone notification. `hostActive` is the host's own
|
|
31
|
+
* presentation surface (Notify in the Glassly App); the engine has no view of
|
|
32
|
+
* it.
|
|
33
|
+
*/
|
|
34
|
+
export declare function currentPresentationOwner(hostActive: boolean): PresentationOwner;
|
|
35
|
+
/**
|
|
36
|
+
* Whether the glasses may read the phone's notifications. iOS glasses read
|
|
37
|
+
* the stream themselves under the Bluetooth notification-sharing consent the
|
|
38
|
+
* driver reports as `ancsAuthorized`; Android glasses get content from the
|
|
39
|
+
* phone's listener, whose grant the permission flow owns.
|
|
40
|
+
*/
|
|
41
|
+
export declare function captureAuthorization(): "granted" | "denied" | "unknown" | "not_needed";
|
|
42
|
+
/**
|
|
43
|
+
* Hand one captured notification to glasses whose firmware presents it from
|
|
44
|
+
* uploaded content (Android). Glasses that read the phone's stream reject it;
|
|
45
|
+
* callers only reach here when the owner is `firmware`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function uploadPhoneNotification(event: PhoneNotificationEvent): Promise<void>;
|
|
14
48
|
export declare function startPhoneNotificationsSync(): void;
|
|
15
49
|
export declare function stopPhoneNotificationsSync(): void;
|
|
16
50
|
//# sourceMappingURL=PhoneNotificationsSync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhoneNotificationsSync.d.ts","sourceRoot":"","sources":["../../src/services/PhoneNotificationsSync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PhoneNotificationsSync.d.ts","sourceRoot":"","sources":["../../src/services/PhoneNotificationsSync.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,wBAAwB,CAAA;AAUrE,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,oCAAoC,CAAA;AAK3C,YAAY,EAAC,iBAAiB,EAAC,CAAA;AAE/B,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAID,wBAAgB,uBAAuB,IAAI,mBAAmB,EAAE,CAG/D;AAED,uEAAuE;AACvE,wBAAgB,wBAAwB,IAAI,eAAe,EAAE,CAS5D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAClD,KAAK,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAAC,CACnE,CAMA;AAED,8EAA8E;AAC9E,wBAAgB,4BAA4B,IAAI,OAAO,CAGtD;AAED,gFAAgF;AAChF,wBAAgB,8BAA8B,IAAI,MAAM,EAAE,CAGzD;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,wBAAgB,gCAAgC,IAAI,yBAAyB,CAa5E;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,OAAO,GAAG,iBAAiB,CAU/E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAMtF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAapF;AAuCD,wBAAgB,2BAA2B,IAAI,IAAI,CAgClD;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAGjD"}
|