@glassly/engine 0.1.0-dev.99 → 0.2.9-beta.448
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,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification policy, pure: what the glasses should do with phone
|
|
3
|
+
* notifications, from settings and the current state of the phone and the
|
|
4
|
+
* glasses. Two questions live here. `glassesNotificationConfig` is the
|
|
5
|
+
* behaviour pushed to firmware that presents notifications itself.
|
|
6
|
+
* `presentationOwner` names the one thing that may draw a notification for
|
|
7
|
+
* the wearer; every other consumer stays quiet. The adapters
|
|
8
|
+
* (PhoneNotificationsSync, the host) snapshot inputs and act on the answers.
|
|
9
|
+
*/
|
|
10
|
+
import type {GlassesNotificationConfig} from "@glassly/bluetooth-sdk"
|
|
11
|
+
|
|
12
|
+
export interface NotificationApp {
|
|
13
|
+
appId: string
|
|
14
|
+
displayName: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface NotificationConfigInput {
|
|
18
|
+
enabled: boolean
|
|
19
|
+
popups: boolean
|
|
20
|
+
popupSeconds: number
|
|
21
|
+
holdDuringApps: boolean
|
|
22
|
+
/** Hold popups while the wearer can see the phone. */
|
|
23
|
+
ignoreWhileActive: boolean
|
|
24
|
+
phoneActive: boolean
|
|
25
|
+
blockedApps: string[]
|
|
26
|
+
/** Catalog ∪ apps the glasses reported, for allowlist firmware. */
|
|
27
|
+
knownApps: NotificationApp[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Popups fold the ignore-while-active gate in: firmware that pops
|
|
32
|
+
* notifications up by itself has no other way to hold them while the wearer
|
|
33
|
+
* is on the phone. The engine's viewer applies the same gate from its env.
|
|
34
|
+
*/
|
|
35
|
+
export function effectivePopups(popups: boolean, ignoreWhileActive: boolean, phoneActive: boolean): boolean {
|
|
36
|
+
if (!popups) return false
|
|
37
|
+
if (!ignoreWhileActive) return true
|
|
38
|
+
return !phoneActive
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function glassesNotificationConfig(input: NotificationConfigInput): GlassesNotificationConfig {
|
|
42
|
+
const blocked = new Set(input.blockedApps)
|
|
43
|
+
const seconds = Number(input.popupSeconds)
|
|
44
|
+
// Known apps travel even while nothing is blocked so a first block enables
|
|
45
|
+
// the allowlist against the wearer's current list, not an empty one.
|
|
46
|
+
const allowedApps = input.knownApps
|
|
47
|
+
.filter((app) => app.appId && !blocked.has(app.appId))
|
|
48
|
+
.map((app) => ({id: app.appId, name: app.displayName || app.appId}))
|
|
49
|
+
return {
|
|
50
|
+
enabled: input.enabled,
|
|
51
|
+
popups: effectivePopups(input.popups, input.ignoreWhileActive, input.phoneActive),
|
|
52
|
+
popupSeconds: Number.isFinite(seconds) && seconds > 0 ? Math.round(seconds) : 0,
|
|
53
|
+
holdDuringApps: input.holdDuringApps,
|
|
54
|
+
blockedApps: [...blocked],
|
|
55
|
+
allowedApps,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Who draws a phone notification for the wearer.
|
|
61
|
+
* viewer — the notifications viewer on connected Glassly CFW glasses, while it runs
|
|
62
|
+
* firmware — the glasses' own notification centre (hasNativeNotifications)
|
|
63
|
+
* host — the host app's card and speech, while its presentation surface runs
|
|
64
|
+
* none — nobody: notifications are off, or nothing is there to show them
|
|
65
|
+
* Miniapp forwarding is not presentation and is never gated by this.
|
|
66
|
+
*/
|
|
67
|
+
export type PresentationOwner = "viewer" | "firmware" | "host" | "none"
|
|
68
|
+
|
|
69
|
+
export interface PresentationInput {
|
|
70
|
+
enabled: boolean
|
|
71
|
+
/** Pages may show on the connected glasses. */
|
|
72
|
+
pagesEligible: boolean
|
|
73
|
+
/** The viewer's app is running, so a page can actually show. */
|
|
74
|
+
viewerRunning: boolean
|
|
75
|
+
/** The connected model presents notifications in firmware. */
|
|
76
|
+
nativeNotifications: boolean
|
|
77
|
+
/** The Notifications miniapp is running, enabling the host fallback. */
|
|
78
|
+
hostActive: boolean
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function presentationOwner(input: PresentationInput): PresentationOwner {
|
|
82
|
+
if (!input.enabled) return "none"
|
|
83
|
+
if (input.pagesEligible && input.viewerRunning) return "viewer"
|
|
84
|
+
if (input.nativeNotifications) return "firmware"
|
|
85
|
+
if (input.hostActive) return "host"
|
|
86
|
+
return "none"
|
|
87
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The overlay apps' pages (ADR-0006): one Page per app that has taken the
|
|
3
|
+
* slot, the only Page implementation the page host shows. The engine keeps
|
|
4
|
+
* the slot and the eligibility watch; a page only relays: holding the slot
|
|
5
|
+
* is reported to its app as a view change, and the app's frames reach the
|
|
6
|
+
* slot through `renderOverlay` under its package name. Whichever app asked
|
|
7
|
+
* last holds the slot; the previous one hears it was replaced. The runtime
|
|
8
|
+
* supplies the sink that delivers to apps, so this module never imports it.
|
|
9
|
+
*/
|
|
10
|
+
import pageHost, {type Page, type PageHiddenReason} from "./PageHost"
|
|
11
|
+
import {isOverlayApp} from "./overlayApps"
|
|
12
|
+
import {pagesEligible} from "./pageEligibility"
|
|
13
|
+
|
|
14
|
+
export type DashboardViewChangeReason = "shown" | "hidden" | "replaced" | "ineligible"
|
|
15
|
+
|
|
16
|
+
export interface OverlayPagesSink {
|
|
17
|
+
/** Deliver a display_view event to the app. */
|
|
18
|
+
send(packageName: string, event: Record<string, unknown>): void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class OverlayPages {
|
|
22
|
+
private sink: OverlayPagesSink | null = null
|
|
23
|
+
private pages = new Map<string, Page>()
|
|
24
|
+
/** Set while an app's page is torn down with the app; it hears nothing then. */
|
|
25
|
+
private silent = new Set<string>()
|
|
26
|
+
|
|
27
|
+
setSink(sink: OverlayPagesSink | null): void {
|
|
28
|
+
this.sink = sink
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The app whose page holds the slot, or null. */
|
|
32
|
+
get showingPackage(): string | null {
|
|
33
|
+
const showing = pageHost.showing
|
|
34
|
+
if (!showing) return null
|
|
35
|
+
for (const [packageName, page] of this.pages) if (page === showing) return packageName
|
|
36
|
+
return null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Give the app the slot (a no-op when it already shows or pages are not eligible). */
|
|
40
|
+
show(packageName: string): boolean {
|
|
41
|
+
if (!isOverlayApp(packageName) || !pagesEligible()) return false
|
|
42
|
+
const page = this.pageFor(packageName)
|
|
43
|
+
pageHost.show(page)
|
|
44
|
+
return pageHost.showing === page
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Release the slot if the app holds it. */
|
|
48
|
+
hide(packageName: string): void {
|
|
49
|
+
const page = this.pages.get(packageName)
|
|
50
|
+
if (page) pageHost.hide(page)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The app stopped: release the slot without telling it, and forget its page. */
|
|
54
|
+
remove(packageName: string): void {
|
|
55
|
+
const page = this.pages.get(packageName)
|
|
56
|
+
if (!page) return
|
|
57
|
+
this.silent.add(packageName)
|
|
58
|
+
try {
|
|
59
|
+
pageHost.hide(page)
|
|
60
|
+
} finally {
|
|
61
|
+
this.silent.delete(packageName)
|
|
62
|
+
}
|
|
63
|
+
this.pages.delete(packageName)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private pageFor(packageName: string): Page {
|
|
67
|
+
let page = this.pages.get(packageName)
|
|
68
|
+
if (page) return page
|
|
69
|
+
page = {
|
|
70
|
+
id: packageName,
|
|
71
|
+
onShown: () => this.emit(packageName, {kind: "change", view: "dashboard", reason: "shown"}),
|
|
72
|
+
onHidden: (reason: PageHiddenReason) => this.emit(packageName, {kind: "change", view: "main", reason}),
|
|
73
|
+
}
|
|
74
|
+
this.pages.set(packageName, page)
|
|
75
|
+
return page
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private emit(packageName: string, event: Record<string, unknown>): void {
|
|
79
|
+
if (this.silent.has(packageName) || !isOverlayApp(packageName)) return
|
|
80
|
+
this.sink?.send(packageName, event)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const overlayPages = new OverlayPages()
|
|
85
|
+
export default overlayPages
|
|
86
|
+
export {OverlayPages}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The page host owns the overlay slot: the single native view above the main
|
|
3
|
+
* content. At most one page shows at a time; showing a page replaces whatever
|
|
4
|
+
* was showing, hiding releases the slot and the main content replays. Which
|
|
5
|
+
* app gets the wearer's gestures is the gesture claims' business, not the
|
|
6
|
+
* host's. Show and hide run through one queue so a page
|
|
7
|
+
* that hides itself from inside its own transition is hidden afterwards, never
|
|
8
|
+
* re-entered. Eligibility (Glassly CFW, dashboard enabled) is checked before a
|
|
9
|
+
* show and watched while a page is up.
|
|
10
|
+
*/
|
|
11
|
+
import {useGlassesStore} from "../../stores/glasses"
|
|
12
|
+
import {SETTINGS, useSettingsStore} from "../../stores/settings"
|
|
13
|
+
import localDisplayManager from "../LocalDisplayManager"
|
|
14
|
+
import {pagesEligible} from "./pageEligibility"
|
|
15
|
+
|
|
16
|
+
export type PageHiddenReason = "hidden" | "replaced" | "ineligible"
|
|
17
|
+
|
|
18
|
+
export interface Page {
|
|
19
|
+
/** Scene app id; the overlay owner while the page shows. */
|
|
20
|
+
readonly id: string
|
|
21
|
+
/** The page holds the slot: draw the first frame. */
|
|
22
|
+
onShown(): void
|
|
23
|
+
/** The slot was released, taken by another page, or lost with eligibility. */
|
|
24
|
+
onHidden(reason: PageHiddenReason): void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class PageHost {
|
|
28
|
+
private showingPage: Page | null = null
|
|
29
|
+
private ops: Array<() => void> = []
|
|
30
|
+
private draining = false
|
|
31
|
+
private listeners = new Set<(page: Page | null) => void>()
|
|
32
|
+
private unsubs: Array<() => void> = []
|
|
33
|
+
private started = false
|
|
34
|
+
|
|
35
|
+
start(): void {
|
|
36
|
+
if (this.started) return
|
|
37
|
+
this.started = true
|
|
38
|
+
const check = () => {
|
|
39
|
+
if (this.showingPage && !pagesEligible()) this.release("ineligible")
|
|
40
|
+
}
|
|
41
|
+
this.unsubs.push(
|
|
42
|
+
useGlassesStore.subscribe(
|
|
43
|
+
(state) => `${state.connection.state}:${state.deviceModel}:${state.firmwareVersion}`,
|
|
44
|
+
check,
|
|
45
|
+
),
|
|
46
|
+
useSettingsStore.subscribe((state) => state.getSetting(SETTINGS.custom_dashboard_enabled.key), check),
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
stop(): void {
|
|
51
|
+
for (const unsub of this.unsubs) unsub()
|
|
52
|
+
this.unsubs = []
|
|
53
|
+
this.release("hidden")
|
|
54
|
+
this.started = false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get showing(): Page | null {
|
|
58
|
+
return this.showingPage
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Give `page` the slot; no-op when it already shows or pages are not eligible. */
|
|
62
|
+
show(page: Page): void {
|
|
63
|
+
this.enqueue(() => {
|
|
64
|
+
if (this.showingPage === page || !pagesEligible()) return
|
|
65
|
+
const previous = this.showingPage
|
|
66
|
+
this.showingPage = page
|
|
67
|
+
localDisplayManager.setOverlayOwner(page.id)
|
|
68
|
+
previous?.onHidden("replaced")
|
|
69
|
+
page.onShown()
|
|
70
|
+
this.emit()
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Release the slot if `page` holds it. */
|
|
75
|
+
hide(page: Page): void {
|
|
76
|
+
this.enqueue(() => {
|
|
77
|
+
if (this.showingPage !== page) return
|
|
78
|
+
this.release("hidden")
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
onChange(listener: (page: Page | null) => void): () => void {
|
|
83
|
+
this.listeners.add(listener)
|
|
84
|
+
return () => {
|
|
85
|
+
this.listeners.delete(listener)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private release(reason: PageHiddenReason): void {
|
|
90
|
+
const page = this.showingPage
|
|
91
|
+
if (!page) return
|
|
92
|
+
this.showingPage = null
|
|
93
|
+
localDisplayManager.setOverlayOwner(null)
|
|
94
|
+
page.onHidden(reason)
|
|
95
|
+
this.emit()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private emit(): void {
|
|
99
|
+
for (const listener of Array.from(this.listeners)) listener(this.showingPage)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private enqueue(op: () => void): void {
|
|
103
|
+
this.ops.push(op)
|
|
104
|
+
if (this.draining) return
|
|
105
|
+
this.draining = true
|
|
106
|
+
try {
|
|
107
|
+
while (this.ops.length) (this.ops.shift() as () => void)()
|
|
108
|
+
} finally {
|
|
109
|
+
this.draining = false
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const pageHost = new PageHost()
|
|
115
|
+
export default pageHost
|
|
116
|
+
export {PageHost}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The overlay apps: the connected miniapps whose manifest type is
|
|
3
|
+
* "system_dashboard" (the dashboard, the notifications viewer). They alone
|
|
4
|
+
* may take the overlay slot through `session.display.showView("dashboard")`
|
|
5
|
+
* and have "dashboard" in their `display.views` capability while the
|
|
6
|
+
* glasses are eligible. The runtime adds an app when it connects and
|
|
7
|
+
* removes it when it stops; the engine never knows what any of them draws.
|
|
8
|
+
* Kept free of imports so the runtime and the notification policy can both
|
|
9
|
+
* read it without a cycle.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export type DisplayView = "main" | "dashboard"
|
|
13
|
+
|
|
14
|
+
const apps = new Set<string>()
|
|
15
|
+
/** Overlay apps listening to the phone's notifications: something on the glasses presents them. */
|
|
16
|
+
const viewers = new Set<string>()
|
|
17
|
+
const listeners = new Set<() => void>()
|
|
18
|
+
|
|
19
|
+
export function isOverlayApp(packageName: string): boolean {
|
|
20
|
+
return apps.has(packageName)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function overlayApps(): readonly string[] {
|
|
24
|
+
return [...apps]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function addOverlayApp(packageName: string): void {
|
|
28
|
+
if (apps.has(packageName)) return
|
|
29
|
+
apps.add(packageName)
|
|
30
|
+
emit()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function removeOverlayApp(packageName: string): void {
|
|
34
|
+
viewers.delete(packageName)
|
|
35
|
+
if (!apps.delete(packageName)) return
|
|
36
|
+
emit()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Record whether an overlay app subscribes to phone notifications (it is a viewer while it does). */
|
|
40
|
+
export function setOverlayViewer(packageName: string, listening: boolean): void {
|
|
41
|
+
const was = viewers.has(packageName)
|
|
42
|
+
if (listening && apps.has(packageName)) viewers.add(packageName)
|
|
43
|
+
else viewers.delete(packageName)
|
|
44
|
+
if (was !== viewers.has(packageName)) emit()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** An overlay app that presents phone notifications is running. */
|
|
48
|
+
export function overlayViewerRunning(): boolean {
|
|
49
|
+
return viewers.size > 0
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function onOverlayAppsChange(listener: () => void): () => void {
|
|
53
|
+
listeners.add(listener)
|
|
54
|
+
return () => {
|
|
55
|
+
listeners.delete(listener)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** The views `packageName` may draw: main for everyone, the dashboard for overlay apps on eligible glasses. */
|
|
60
|
+
export function displayViewsFor(packageName: string, eligible: boolean): DisplayView[] {
|
|
61
|
+
return apps.has(packageName) && eligible ? ["main", "dashboard"] : ["main"]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function emit(): void {
|
|
65
|
+
for (const listener of Array.from(listeners)) listener()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Tests only. */
|
|
69
|
+
export function _resetOverlayAppsForTest(): void {
|
|
70
|
+
apps.clear()
|
|
71
|
+
viewers.clear()
|
|
72
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the dashboard view may show right now: connected Glassly CFW
|
|
3
|
+
* glasses with the dashboard enabled. The page host reads it before showing
|
|
4
|
+
* a page and hides the showing page when it turns false; the miniapp runtime
|
|
5
|
+
* folds it into the designated app's `display.views` capability. Read at
|
|
6
|
+
* decision time, never cached.
|
|
7
|
+
*/
|
|
8
|
+
import {useGlassesStore} from "../../stores/glasses"
|
|
9
|
+
import {SETTINGS, useSettingsStore} from "../../stores/settings"
|
|
10
|
+
import {DeviceTypes} from "../../types/enums"
|
|
11
|
+
import {isGlassesConnected} from "../GlassesReadiness"
|
|
12
|
+
|
|
13
|
+
/** G2.swift appends this marker after the firmware advertises Glassly CFW capabilities. */
|
|
14
|
+
export function isCfwFirmwareVersion(firmwareVersion: string | null | undefined): boolean {
|
|
15
|
+
return firmwareVersion?.toLowerCase().includes("glassly cfw") === true
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Stock G2 and NIMO are intentionally excluded. */
|
|
19
|
+
export function isCustomDashboardEligible(info: {model?: string | null; firmwareVersion?: string | null}): boolean {
|
|
20
|
+
return info.model === DeviceTypes.G2 && isCfwFirmwareVersion(info.firmwareVersion)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function pagesEligible(): boolean {
|
|
24
|
+
if (useSettingsStore.getState().getSetting(SETTINGS.custom_dashboard_enabled.key) === false) return false
|
|
25
|
+
const state = useGlassesStore.getState()
|
|
26
|
+
return (
|
|
27
|
+
isGlassesConnected(state.connection) &&
|
|
28
|
+
isCustomDashboardEligible({model: state.deviceModel, firmwareVersion: state.firmwareVersion})
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The settings bridge's vocabulary (session.settings): which engine settings
|
|
3
|
+
* a system miniapp may read or write, the derived read-only keys the engine
|
|
4
|
+
* computes rather than stores, and the request validation. Pure, so the
|
|
5
|
+
* runtime's handlers stay thin and this can be tested without the native
|
|
6
|
+
* import surface the runtime pulls in.
|
|
7
|
+
*
|
|
8
|
+
* The dashboard miniapp is the consumer: it edits the same dashboard,
|
|
9
|
+
* notification and glasses-menu keys the phone's settings screens used to,
|
|
10
|
+
* through the store, so persistence, server sync and the Bluetooth sync of
|
|
11
|
+
* `menu_apps` behave as if a phone screen wrote them.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type SettingsBridgeAccess = "read" | "write"
|
|
15
|
+
|
|
16
|
+
/** Stored settings the bridge serves, by key, with what a system app may do to each. */
|
|
17
|
+
export const SETTINGS_BRIDGE_KEYS: Readonly<Record<string, SettingsBridgeAccess>> = {
|
|
18
|
+
// The dashboard's master switch is a phone-side debug knob.
|
|
19
|
+
custom_dashboard_enabled: "read",
|
|
20
|
+
custom_dashboard_clock_style: "write",
|
|
21
|
+
custom_dashboard_clock_show_date: "write",
|
|
22
|
+
custom_dashboard_battery_style: "write",
|
|
23
|
+
custom_dashboard_layout: "write",
|
|
24
|
+
custom_dashboard_calendar_event_count: "write",
|
|
25
|
+
custom_dashboard_calendar_days_ahead: "write",
|
|
26
|
+
contextual_dashboard: "write",
|
|
27
|
+
twelve_hour_time: "write",
|
|
28
|
+
menu_apps: "write",
|
|
29
|
+
notifications_enabled: "write",
|
|
30
|
+
notifications_popups: "write",
|
|
31
|
+
notifications_popup_seconds: "write",
|
|
32
|
+
notifications_hold_during_apps: "write",
|
|
33
|
+
notifications_ignore_while_active: "write",
|
|
34
|
+
notifications_blocklist: "write",
|
|
35
|
+
// Apps the glasses reported posting notifications; the engine records it.
|
|
36
|
+
notification_seen_apps: "read",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Read-only keys the engine computes: whether the wearer can see the phone,
|
|
41
|
+
* whether the foreground miniapp is drawing on the glasses, and the ring's
|
|
42
|
+
* battery. They change on their own clocks; the runtime pushes them like
|
|
43
|
+
* stored keys.
|
|
44
|
+
*/
|
|
45
|
+
export const DERIVED_SETTINGS_KEYS = ["phone_active", "foreground_app_on_screen", "ring_battery"] as const
|
|
46
|
+
export type DerivedSettingsKey = (typeof DERIVED_SETTINGS_KEYS)[number]
|
|
47
|
+
|
|
48
|
+
export function isDerivedSettingsKey(key: string): key is DerivedSettingsKey {
|
|
49
|
+
return (DERIVED_SETTINGS_KEYS as readonly string[]).includes(key)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** What a system app may do with `key`, or null when the bridge does not serve it. */
|
|
53
|
+
export function settingsBridgeAccess(key: string): SettingsBridgeAccess | null {
|
|
54
|
+
if (isDerivedSettingsKey(key)) return "read"
|
|
55
|
+
return SETTINGS_BRIDGE_KEYS[key] ?? null
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Every key the bridge serves, stored then derived. */
|
|
59
|
+
export function allSettingsBridgeKeys(): string[] {
|
|
60
|
+
return [...Object.keys(SETTINGS_BRIDGE_KEYS), ...DERIVED_SETTINGS_KEYS]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The keys a SETTINGS_GET asks for: everything when `requested` is absent,
|
|
65
|
+
* else the known ones among the requested strings (unknown keys are left
|
|
66
|
+
* out, never rejected).
|
|
67
|
+
*/
|
|
68
|
+
export function selectSettingsBridgeKeys(requested: unknown): string[] {
|
|
69
|
+
if (requested === undefined || requested === null) return allSettingsBridgeKeys()
|
|
70
|
+
if (!Array.isArray(requested)) return []
|
|
71
|
+
return requested.filter((key): key is string => typeof key === "string" && settingsBridgeAccess(key) !== null)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export type SettingsSetValidation =
|
|
75
|
+
| {ok: true; key: string; value: unknown}
|
|
76
|
+
| {ok: false; code: "INVALID_ARGUMENT" | "NOT_PERMITTED"; message: string}
|
|
77
|
+
|
|
78
|
+
/** A SETTINGS_SET payload: a writable key and a JSON value (undefined is not a value). */
|
|
79
|
+
export function validateSettingsSet(payload: Record<string, unknown>): SettingsSetValidation {
|
|
80
|
+
const key = payload.key
|
|
81
|
+
if (typeof key !== "string" || !key) {
|
|
82
|
+
return {ok: false, code: "INVALID_ARGUMENT", message: "settings.set requires a key"}
|
|
83
|
+
}
|
|
84
|
+
const access = settingsBridgeAccess(key)
|
|
85
|
+
if (access === null) return {ok: false, code: "INVALID_ARGUMENT", message: `Unknown setting "${key}"`}
|
|
86
|
+
if (access !== "write") return {ok: false, code: "NOT_PERMITTED", message: `Setting "${key}" is read-only`}
|
|
87
|
+
if (!("value" in payload) || payload.value === undefined) {
|
|
88
|
+
return {ok: false, code: "INVALID_ARGUMENT", message: "settings.set requires a value"}
|
|
89
|
+
}
|
|
90
|
+
return {ok: true, key, value: payload.value}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** The ring's battery as the dashboard shows it: the relayed ring first, else the controller. */
|
|
94
|
+
export interface RingBattery {
|
|
95
|
+
connected: boolean
|
|
96
|
+
/** -1 when unknown. */
|
|
97
|
+
level: number
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function ringBatteryFrom(glasses: {
|
|
101
|
+
ringConnected: boolean
|
|
102
|
+
ringBatteryLevel: number
|
|
103
|
+
controllerConnected: boolean
|
|
104
|
+
controllerBatteryLevel: number
|
|
105
|
+
}): RingBattery {
|
|
106
|
+
const relayed = glasses.ringConnected && glasses.ringBatteryLevel >= 0
|
|
107
|
+
return {
|
|
108
|
+
connected: relayed || glasses.controllerConnected,
|
|
109
|
+
level: relayed ? glasses.ringBatteryLevel : glasses.controllerBatteryLevel,
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -9,7 +9,7 @@ import {cloudClientService} from "./CloudClientService"
|
|
|
9
9
|
import {SpeakerProfileStore} from "./SpeakerProfileStore"
|
|
10
10
|
|
|
11
11
|
export const speakerProfileStore = new SpeakerProfileStore({
|
|
12
|
-
getUserId: () => cloudClientService.
|
|
12
|
+
getUserId: () => cloudClientService.resolveUserId(),
|
|
13
13
|
backend: {
|
|
14
14
|
get(key: string): unknown | null {
|
|
15
15
|
const result = mmkvStorage.load<unknown>(key)
|
package/src/services/uiShim.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* - Buffers `glassly.send(channel, payload)` calls until `glassly.ready()`
|
|
11
11
|
* fires + the host acks the channel is open. WebView-side BUFFERS (the
|
|
12
12
|
* WebView is the short-lived side and shouldn't drop user input).
|
|
13
|
-
* - Installs `window.
|
|
13
|
+
* - Installs `window.__host.recv(envelope)` for the host to push
|
|
14
14
|
* background → WebView messages via `webview.injectJavaScript(...)`.
|
|
15
15
|
* - Sends `__heartbeat__` every 5s; host considers the WebView gone
|
|
16
16
|
* after 15s of silence.
|
|
@@ -39,12 +39,12 @@ export interface UiShimOptions {
|
|
|
39
39
|
export function buildUiShim(options: UiShimOptions): string {
|
|
40
40
|
const packageNameJson = JSON.stringify(options.packageName)
|
|
41
41
|
// The IIFE assembles a typed `glassly` global plus an internal
|
|
42
|
-
// `
|
|
42
|
+
// `__host` for host inbound calls. Quoted strings are JSON-safe so
|
|
43
43
|
// direct injection inside another JS literal also works.
|
|
44
44
|
return `
|
|
45
45
|
(function () {
|
|
46
46
|
if (typeof window === 'undefined') return;
|
|
47
|
-
if (window.glassly && window.
|
|
47
|
+
if (window.glassly && window.__host) return;
|
|
48
48
|
var packageName = ${packageNameJson};
|
|
49
49
|
// Resolve window.ReactNativeWebView.postMessage LAZILY, not once at shim-eval.
|
|
50
50
|
// On Android the shim is injected as a WebViewCompat document-start script
|
|
@@ -369,7 +369,7 @@ export function buildUiShim(options: UiShimOptions): string {
|
|
|
369
369
|
/** @internal — packageName for diagnostic logs only. */
|
|
370
370
|
_packageName: packageName,
|
|
371
371
|
};
|
|
372
|
-
window.
|
|
372
|
+
window.__host = { recv: recv };
|
|
373
373
|
})();
|
|
374
374
|
`.trim()
|
|
375
375
|
}
|
|
@@ -1,3 +1,48 @@
|
|
|
1
1
|
/** Combine registry-enforced visibility with the user's home-screen choice. */
|
|
2
2
|
export const resolveHiddenStatus = (registryHidden: boolean, userHidden: boolean): boolean =>
|
|
3
3
|
registryHidden || userHidden
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Miniapps that start off the primary home screen. They stay listed under
|
|
7
|
+
* "view all apps", where "Add to Home" saves an explicit choice that wins
|
|
8
|
+
* over this default from then on.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_HIDDEN_PACKAGES: ReadonlySet<string> = new Set(["com.glassly.camera", "com.glassly.recorder"])
|
|
11
|
+
|
|
12
|
+
/** The home-screen visibility of an app the user has never hidden or added. */
|
|
13
|
+
export const defaultHiddenStatus = (packageName: string): boolean => DEFAULT_HIDDEN_PACKAGES.has(packageName)
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Miniapps that exist only for developers: the Miniapp Developer launcher and
|
|
17
|
+
* the bundled sample/test miniapps. They are projected into the app store
|
|
18
|
+
* only while the `dev_tools` setting is on; off, they are absent from every
|
|
19
|
+
* launcher surface (home, all apps, glasses menu, AI listing), not merely
|
|
20
|
+
* hidden from the primary home screen.
|
|
21
|
+
*/
|
|
22
|
+
export const DEV_TOOLS_PACKAGES: ReadonlySet<string> = new Set([
|
|
23
|
+
"com.glassly.miniappdev",
|
|
24
|
+
"com.glassly.example",
|
|
25
|
+
"com.glassly.tetris",
|
|
26
|
+
"com.glassly.compass",
|
|
27
|
+
"com.glassly.showcase",
|
|
28
|
+
])
|
|
29
|
+
|
|
30
|
+
/** True when the app is dev-only and developer tools are off. */
|
|
31
|
+
export const isGatedByDevTools = (packageName: string, devToolsEnabled: boolean): boolean =>
|
|
32
|
+
!devToolsEnabled && DEV_TOOLS_PACKAGES.has(packageName)
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Miniapps that unlock once a real pair of glasses has been paired on this
|
|
36
|
+
* phone (`has_paired_glasses`, latched by PairedGlassesLatch and never
|
|
37
|
+
* cleared, so forgetting the glasses keeps them). Developer tools open them
|
|
38
|
+
* early. Until either, they are absent from every launcher surface like the
|
|
39
|
+
* dev-only set above.
|
|
40
|
+
*/
|
|
41
|
+
export const PAIRED_GLASSES_PACKAGES: ReadonlySet<string> = new Set(["com.glassly.store"])
|
|
42
|
+
|
|
43
|
+
/** True when the app waits on a pairing that hasn't happened and dev tools are off. */
|
|
44
|
+
export const isGatedUntilPaired = (
|
|
45
|
+
packageName: string,
|
|
46
|
+
devToolsEnabled: boolean,
|
|
47
|
+
hasPairedGlasses: boolean,
|
|
48
|
+
): boolean => !devToolsEnabled && !hasPairedGlasses && PAIRED_GLASSES_PACKAGES.has(packageName)
|