@glassly/engine 0.1.0-dev.98 → 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.
Files changed (501) hide show
  1. package/README.md +28 -0
  2. package/build/engine.d.ts +32 -10
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +24 -16
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts +9 -0
  7. package/build/facades/dev.d.ts.map +1 -1
  8. package/build/facades/dev.js +9 -0
  9. package/build/facades/dev.js.map +1 -1
  10. package/build/facades/display.d.ts +10 -3
  11. package/build/facades/display.d.ts.map +1 -1
  12. package/build/facades/display.js +22 -8
  13. package/build/facades/display.js.map +1 -1
  14. package/build/facades/displayMirror.d.ts +11 -0
  15. package/build/facades/displayMirror.d.ts.map +1 -1
  16. package/build/facades/displayMirror.js +22 -0
  17. package/build/facades/displayMirror.js.map +1 -1
  18. package/build/facades/glasses.d.ts +31 -1
  19. package/build/facades/glasses.d.ts.map +1 -1
  20. package/build/facades/glasses.js +51 -0
  21. package/build/facades/glasses.js.map +1 -1
  22. package/build/facades/memory.d.ts +0 -6
  23. package/build/facades/memory.d.ts.map +1 -1
  24. package/build/facades/memory.js +1 -9
  25. package/build/facades/memory.js.map +1 -1
  26. package/build/facades/miniapps.d.ts +3 -1
  27. package/build/facades/miniapps.d.ts.map +1 -1
  28. package/build/facades/miniapps.js +3 -1
  29. package/build/facades/miniapps.js.map +1 -1
  30. package/build/facades/pairing.d.ts.map +1 -1
  31. package/build/facades/pairing.js +5 -4
  32. package/build/facades/pairing.js.map +1 -1
  33. package/build/facades/permissions.d.ts +2 -0
  34. package/build/facades/permissions.d.ts.map +1 -1
  35. package/build/facades/permissions.js +48 -0
  36. package/build/facades/permissions.js.map +1 -1
  37. package/build/facades/phoneNotifications.d.ts +20 -9
  38. package/build/facades/phoneNotifications.d.ts.map +1 -1
  39. package/build/facades/phoneNotifications.js +33 -26
  40. package/build/facades/phoneNotifications.js.map +1 -1
  41. package/build/facades/settings.d.ts.map +1 -1
  42. package/build/facades/settings.js +1 -2
  43. package/build/facades/settings.js.map +1 -1
  44. package/build/generated/releaseMetadata.js +4 -4
  45. package/build/generated/releaseMetadata.js.map +1 -1
  46. package/build/index.d.ts +6 -4
  47. package/build/index.d.ts.map +1 -1
  48. package/build/index.js +5 -4
  49. package/build/index.js.map +1 -1
  50. package/build/react/MentraLiveOtaFlow.js +2 -2
  51. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  52. package/build/react/useMentraLiveOta.d.ts.map +1 -1
  53. package/build/react/useMentraLiveOta.js +8 -7
  54. package/build/react/useMentraLiveOta.js.map +1 -1
  55. package/build/runtime/config.d.ts +1 -1
  56. package/build/runtime/config.d.ts.map +1 -1
  57. package/build/runtime/config.js.map +1 -1
  58. package/build/services/AppRegistry.d.ts +4 -1
  59. package/build/services/AppRegistry.d.ts.map +1 -1
  60. package/build/services/AppRegistry.js +21 -1
  61. package/build/services/AppRegistry.js.map +1 -1
  62. package/build/services/BlobStore.d.ts +2 -2
  63. package/build/services/BlobStore.js +3 -3
  64. package/build/services/BlobStore.js.map +1 -1
  65. package/build/services/CloudClientService.d.ts +7 -3
  66. package/build/services/CloudClientService.d.ts.map +1 -1
  67. package/build/services/CloudClientService.js +34 -9
  68. package/build/services/CloudClientService.js.map +1 -1
  69. package/build/services/DevServerBridge.d.ts +1 -18
  70. package/build/services/DevServerBridge.d.ts.map +1 -1
  71. package/build/services/DevServerBridge.js +9 -8
  72. package/build/services/DevServerBridge.js.map +1 -1
  73. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  74. package/build/services/DeviceEventRouter.js +58 -71
  75. package/build/services/DeviceEventRouter.js.map +1 -1
  76. package/build/services/DisplayDiagnostics.d.ts +5 -0
  77. package/build/services/DisplayDiagnostics.d.ts.map +1 -0
  78. package/build/services/DisplayDiagnostics.js +105 -0
  79. package/build/services/DisplayDiagnostics.js.map +1 -0
  80. package/build/services/DisplayProcessor.d.ts +6 -7
  81. package/build/services/DisplayProcessor.d.ts.map +1 -1
  82. package/build/services/DisplayProcessor.js +17 -45
  83. package/build/services/DisplayProcessor.js.map +1 -1
  84. package/build/services/GestureDotsService.d.ts +10 -4
  85. package/build/services/GestureDotsService.d.ts.map +1 -1
  86. package/build/services/GestureDotsService.js +70 -16
  87. package/build/services/GestureDotsService.js.map +1 -1
  88. package/build/services/GlassesKeyboardInput.d.ts +77 -0
  89. package/build/services/GlassesKeyboardInput.d.ts.map +1 -0
  90. package/build/services/GlassesKeyboardInput.js +261 -0
  91. package/build/services/GlassesKeyboardInput.js.map +1 -0
  92. package/build/services/GlassesSensorService.d.ts +47 -0
  93. package/build/services/GlassesSensorService.d.ts.map +1 -0
  94. package/build/services/GlassesSensorService.js +242 -0
  95. package/build/services/GlassesSensorService.js.map +1 -0
  96. package/build/services/GlassesTouchInput.d.ts +14 -0
  97. package/build/services/GlassesTouchInput.d.ts.map +1 -0
  98. package/build/services/GlassesTouchInput.js +107 -0
  99. package/build/services/GlassesTouchInput.js.map +1 -0
  100. package/build/services/HeadingService.d.ts +0 -6
  101. package/build/services/HeadingService.d.ts.map +1 -1
  102. package/build/services/HeadingService.js +0 -27
  103. package/build/services/HeadingService.js.map +1 -1
  104. package/build/services/HotspotShutdown.d.ts.map +1 -1
  105. package/build/services/HotspotShutdown.js +2 -1
  106. package/build/services/HotspotShutdown.js.map +1 -1
  107. package/build/services/JSCrashloopReportService.js +2 -2
  108. package/build/services/JSCrashloopReportService.js.map +1 -1
  109. package/build/services/JSRouter.d.ts +6 -4
  110. package/build/services/JSRouter.d.ts.map +1 -1
  111. package/build/services/JSRouter.js +15 -13
  112. package/build/services/JSRouter.js.map +1 -1
  113. package/build/services/LocalDisplayManager.d.ts +35 -7
  114. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  115. package/build/services/LocalDisplayManager.js +105 -27
  116. package/build/services/LocalDisplayManager.js.map +1 -1
  117. package/build/services/LocalMiniappDataMigration.d.ts +1 -1
  118. package/build/services/LocalMiniappDataMigration.js +1 -1
  119. package/build/services/LocalMiniappDataMigration.js.map +1 -1
  120. package/build/services/LocalMiniappRuntime.d.ts +64 -11
  121. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  122. package/build/services/LocalMiniappRuntime.js +441 -35
  123. package/build/services/LocalMiniappRuntime.js.map +1 -1
  124. package/build/services/LocalSttFallbackCoordinator.d.ts +3 -0
  125. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  126. package/build/services/LocalSttFallbackCoordinator.js +27 -8
  127. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  128. package/build/services/MemoryStore.d.ts +8 -33
  129. package/build/services/MemoryStore.d.ts.map +1 -1
  130. package/build/services/MemoryStore.js +30 -56
  131. package/build/services/MemoryStore.js.map +1 -1
  132. package/build/services/MiniappEngine.d.ts +3 -3
  133. package/build/services/MiniappEngine.js +7 -7
  134. package/build/services/MiniappEngine.js.map +1 -1
  135. package/build/services/MiniappLauncher.d.ts +8 -0
  136. package/build/services/MiniappLauncher.d.ts.map +1 -1
  137. package/build/services/MiniappLauncher.js +19 -1
  138. package/build/services/MiniappLauncher.js.map +1 -1
  139. package/build/services/MirrorService.d.ts +24 -0
  140. package/build/services/MirrorService.d.ts.map +1 -0
  141. package/build/services/MirrorService.js +132 -0
  142. package/build/services/MirrorService.js.map +1 -0
  143. package/build/services/NativeNavigationService.d.ts +2 -3
  144. package/build/services/NativeNavigationService.d.ts.map +1 -1
  145. package/build/services/NativeNavigationService.js +24 -21
  146. package/build/services/NativeNavigationService.js.map +1 -1
  147. package/build/services/NavigationHandlers.d.ts.map +1 -1
  148. package/build/services/NavigationHandlers.js +10 -5
  149. package/build/services/NavigationHandlers.js.map +1 -1
  150. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  151. package/build/services/OtaInstallCoordinator.js +24 -23
  152. package/build/services/OtaInstallCoordinator.js.map +1 -1
  153. package/build/services/PairedGlassesLatch.d.ts +7 -0
  154. package/build/services/PairedGlassesLatch.d.ts.map +1 -0
  155. package/build/services/PairedGlassesLatch.js +38 -0
  156. package/build/services/PairedGlassesLatch.js.map +1 -0
  157. package/build/services/PhoneActivity.d.ts +23 -0
  158. package/build/services/PhoneActivity.d.ts.map +1 -0
  159. package/build/services/PhoneActivity.js +111 -0
  160. package/build/services/PhoneActivity.js.map +1 -0
  161. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  162. package/build/services/PhoneCameraFovCoordinator.js +4 -3
  163. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  164. package/build/services/PhoneNotificationsSync.d.ts +40 -6
  165. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  166. package/build/services/PhoneNotificationsSync.js +160 -84
  167. package/build/services/PhoneNotificationsSync.js.map +1 -1
  168. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  169. package/build/services/PhonePhotoCoordinator.js +6 -5
  170. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  171. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  172. package/build/services/PhoneStreamCoordinator.js +8 -7
  173. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  174. package/build/services/STTModelManager.d.ts +3 -0
  175. package/build/services/STTModelManager.d.ts.map +1 -1
  176. package/build/services/STTModelManager.js +15 -1
  177. package/build/services/STTModelManager.js.map +1 -1
  178. package/build/services/SceneRenderer.d.ts +43 -2
  179. package/build/services/SceneRenderer.d.ts.map +1 -1
  180. package/build/services/SceneRenderer.js +123 -8
  181. package/build/services/SceneRenderer.js.map +1 -1
  182. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  183. package/build/services/StreamLifecycleController.js +6 -14
  184. package/build/services/StreamLifecycleController.js.map +1 -1
  185. package/build/services/TTSModelManager.js +1 -1
  186. package/build/services/TTSModelManager.js.map +1 -1
  187. package/build/services/UIRouter.d.ts +2 -2
  188. package/build/services/UIRouter.js +5 -5
  189. package/build/services/UIRouter.js.map +1 -1
  190. package/build/services/asg/galleryPathMigration.js +1 -1
  191. package/build/services/asg/galleryPathMigration.js.map +1 -1
  192. package/build/services/asg/gallerySyncService.js +2 -2
  193. package/build/services/asg/gallerySyncService.js.map +1 -1
  194. package/build/services/asg/localStorageService.d.ts.map +1 -1
  195. package/build/services/asg/localStorageService.js +3 -3
  196. package/build/services/asg/localStorageService.js.map +1 -1
  197. package/build/services/debug/DashboardOpenTrace.d.ts +32 -0
  198. package/build/services/debug/DashboardOpenTrace.d.ts.map +1 -0
  199. package/build/services/debug/DashboardOpenTrace.js +128 -0
  200. package/build/services/debug/DashboardOpenTrace.js.map +1 -0
  201. package/build/services/debug/dashboardOpenTimeline.d.ts +77 -0
  202. package/build/services/debug/dashboardOpenTimeline.d.ts.map +1 -0
  203. package/build/services/debug/dashboardOpenTimeline.js +195 -0
  204. package/build/services/debug/dashboardOpenTimeline.js.map +1 -0
  205. package/build/services/effectiveCapabilities.d.ts.map +1 -1
  206. package/build/services/effectiveCapabilities.js +25 -13
  207. package/build/services/effectiveCapabilities.js.map +1 -1
  208. package/build/services/gestureClaims.d.ts +34 -15
  209. package/build/services/gestureClaims.d.ts.map +1 -1
  210. package/build/services/gestureClaims.js +42 -21
  211. package/build/services/gestureClaims.js.map +1 -1
  212. package/build/services/manifestFields.d.ts +9 -0
  213. package/build/services/manifestFields.d.ts.map +1 -0
  214. package/build/services/manifestFields.js +26 -0
  215. package/build/services/manifestFields.js.map +1 -0
  216. package/build/services/memoryStoreInstance.d.ts +0 -10
  217. package/build/services/memoryStoreInstance.d.ts.map +1 -1
  218. package/build/services/memoryStoreInstance.js +2 -31
  219. package/build/services/memoryStoreInstance.js.map +1 -1
  220. package/build/services/mirrorSnapshot.d.ts +16 -0
  221. package/build/services/mirrorSnapshot.d.ts.map +1 -0
  222. package/build/services/mirrorSnapshot.js +102 -0
  223. package/build/services/mirrorSnapshot.js.map +1 -0
  224. package/build/services/nativeNavigationGate.d.ts +8 -0
  225. package/build/services/nativeNavigationGate.d.ts.map +1 -0
  226. package/build/services/nativeNavigationGate.js +12 -0
  227. package/build/services/nativeNavigationGate.js.map +1 -0
  228. package/build/services/notificationAppCatalog.d.ts +7 -0
  229. package/build/services/notificationAppCatalog.d.ts.map +1 -0
  230. package/build/services/notificationAppCatalog.js +16 -0
  231. package/build/services/notificationAppCatalog.js.map +1 -0
  232. package/build/services/notifications/notificationPolicy.d.ts +55 -0
  233. package/build/services/notifications/notificationPolicy.d.ts.map +1 -0
  234. package/build/services/notifications/notificationPolicy.js +41 -0
  235. package/build/services/notifications/notificationPolicy.js.map +1 -0
  236. package/build/services/pages/OverlayPages.d.ts +26 -0
  237. package/build/services/pages/OverlayPages.d.ts.map +1 -0
  238. package/build/services/pages/OverlayPages.js +80 -0
  239. package/build/services/pages/OverlayPages.js.map +1 -0
  240. package/build/services/pages/PageHost.d.ts +32 -0
  241. package/build/services/pages/PageHost.d.ts.map +1 -0
  242. package/build/services/pages/PageHost.js +99 -0
  243. package/build/services/pages/PageHost.js.map +1 -0
  244. package/build/services/pages/overlayApps.d.ts +25 -0
  245. package/build/services/pages/overlayApps.d.ts.map +1 -0
  246. package/build/services/pages/overlayApps.js +66 -0
  247. package/build/services/pages/overlayApps.js.map +1 -0
  248. package/build/services/pages/pageEligibility.d.ts +9 -0
  249. package/build/services/pages/pageEligibility.d.ts.map +1 -0
  250. package/build/services/pages/pageEligibility.js +27 -0
  251. package/build/services/pages/pageEligibility.js.map +1 -0
  252. package/build/services/settingsBridge.d.ts +58 -0
  253. package/build/services/settingsBridge.d.ts.map +1 -0
  254. package/build/services/settingsBridge.js +90 -0
  255. package/build/services/settingsBridge.js.map +1 -0
  256. package/build/services/speakerProfileStoreInstance.js +1 -1
  257. package/build/services/speakerProfileStoreInstance.js.map +1 -1
  258. package/build/services/uiShim.d.ts +1 -1
  259. package/build/services/uiShim.js +4 -4
  260. package/build/services/uiShim.js.map +1 -1
  261. package/build/stores/appVisibility.d.ts +28 -0
  262. package/build/stores/appVisibility.d.ts.map +1 -1
  263. package/build/stores/appVisibility.js +34 -0
  264. package/build/stores/appVisibility.js.map +1 -1
  265. package/build/stores/apps.d.ts +13 -0
  266. package/build/stores/apps.d.ts.map +1 -1
  267. package/build/stores/apps.js +66 -12
  268. package/build/stores/apps.js.map +1 -1
  269. package/build/stores/bluetoothSettingKeys.js +1 -1
  270. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  271. package/build/stores/display.d.ts +3 -3
  272. package/build/stores/display.d.ts.map +1 -1
  273. package/build/stores/display.js +16 -4
  274. package/build/stores/display.js.map +1 -1
  275. package/build/stores/glasses.d.ts.map +1 -1
  276. package/build/stores/glasses.js +14 -1
  277. package/build/stores/glasses.js.map +1 -1
  278. package/build/stores/settings.d.ts +1 -0
  279. package/build/stores/settings.d.ts.map +1 -1
  280. package/build/stores/settings.js +170 -44
  281. package/build/stores/settings.js.map +1 -1
  282. package/build/types/applet.d.ts +14 -1
  283. package/build/types/applet.d.ts.map +1 -1
  284. package/build/types/applet.js.map +1 -1
  285. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
  286. package/build/types/capabilities/even-realities-g2.js +5 -0
  287. package/build/types/capabilities/even-realities-g2.js.map +1 -1
  288. package/build/types/capabilities/simulated-glasses.d.ts +1 -1
  289. package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
  290. package/build/types/capabilities/simulated-glasses.js +7 -4
  291. package/build/types/capabilities/simulated-glasses.js.map +1 -1
  292. package/build/types/hardware.d.ts +20 -1
  293. package/build/types/hardware.d.ts.map +1 -1
  294. package/build/types/hardware.js +2 -0
  295. package/build/types/hardware.js.map +1 -1
  296. package/build/types/index.d.ts +1 -0
  297. package/build/types/index.d.ts.map +1 -1
  298. package/build/types/index.js +1 -0
  299. package/build/types/index.js.map +1 -1
  300. package/build/utils/debouncedPatch.d.ts +3 -1
  301. package/build/utils/debouncedPatch.d.ts.map +1 -1
  302. package/build/utils/debouncedPatch.js +6 -3
  303. package/build/utils/debouncedPatch.js.map +1 -1
  304. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  305. package/build/utils/devMiniappLaunch.js +4 -3
  306. package/build/utils/devMiniappLaunch.js.map +1 -1
  307. package/build/utils/display/measurer/TextMeasurer.d.ts +2 -159
  308. package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -1
  309. package/build/utils/display/measurer/TextMeasurer.js +2 -272
  310. package/build/utils/display/measurer/TextMeasurer.js.map +1 -1
  311. package/build/utils/display/measurer/script-detection.d.ts +1 -52
  312. package/build/utils/display/measurer/script-detection.d.ts.map +1 -1
  313. package/build/utils/display/measurer/script-detection.js +2 -183
  314. package/build/utils/display/measurer/script-detection.js.map +1 -1
  315. package/build/utils/display/pixelArt.d.ts +3 -0
  316. package/build/utils/display/pixelArt.d.ts.map +1 -0
  317. package/build/utils/display/pixelArt.js +3 -0
  318. package/build/utils/display/pixelArt.js.map +1 -0
  319. package/build/utils/display/profiles/g1.d.ts +1 -32
  320. package/build/utils/display/profiles/g1.d.ts.map +1 -1
  321. package/build/utils/display/profiles/g1.js +2 -212
  322. package/build/utils/display/profiles/g1.js.map +1 -1
  323. package/build/utils/display/profiles/g2.d.ts +1 -12
  324. package/build/utils/display/profiles/g2.d.ts.map +1 -1
  325. package/build/utils/display/profiles/g2.js +2 -33
  326. package/build/utils/display/profiles/g2.js.map +1 -1
  327. package/build/utils/display/profiles/nex.d.ts +1 -9
  328. package/build/utils/display/profiles/nex.d.ts.map +1 -1
  329. package/build/utils/display/profiles/nex.js +2 -149
  330. package/build/utils/display/profiles/nex.js.map +1 -1
  331. package/build/utils/display/profiles/types.d.ts +1 -102
  332. package/build/utils/display/profiles/types.d.ts.map +1 -1
  333. package/build/utils/display/profiles/types.js.map +1 -1
  334. package/build/utils/display/profiles/z100.d.ts +1 -32
  335. package/build/utils/display/profiles/z100.d.ts.map +1 -1
  336. package/build/utils/display/profiles/z100.js +2 -181
  337. package/build/utils/display/profiles/z100.js.map +1 -1
  338. package/build/utils/display/scene/degrade.d.ts.map +1 -1
  339. package/build/utils/display/scene/degrade.js +4 -1
  340. package/build/utils/display/scene/degrade.js.map +1 -1
  341. package/build/utils/display/scene/differ.d.ts +13 -1
  342. package/build/utils/display/scene/differ.d.ts.map +1 -1
  343. package/build/utils/display/scene/differ.js +22 -0
  344. package/build/utils/display/scene/differ.js.map +1 -1
  345. package/build/utils/display/scene/index.d.ts +1 -1
  346. package/build/utils/display/scene/index.d.ts.map +1 -1
  347. package/build/utils/display/scene/index.js.map +1 -1
  348. package/build/utils/display/scene/process.d.ts.map +1 -1
  349. package/build/utils/display/scene/process.js +183 -11
  350. package/build/utils/display/scene/process.js.map +1 -1
  351. package/build/utils/display/scene/store.d.ts +1 -1
  352. package/build/utils/display/scene/store.d.ts.map +1 -1
  353. package/build/utils/display/scene/store.js +0 -0
  354. package/build/utils/display/scene/store.js.map +1 -1
  355. package/build/utils/display/scene/svgPath.d.ts +9 -0
  356. package/build/utils/display/scene/svgPath.d.ts.map +1 -0
  357. package/build/utils/display/scene/svgPath.js +167 -0
  358. package/build/utils/display/scene/svgPath.js.map +1 -0
  359. package/build/utils/display/scene/types.d.ts +2 -142
  360. package/build/utils/display/scene/types.d.ts.map +1 -1
  361. package/build/utils/display/scene/types.js +0 -0
  362. package/build/utils/display/scene/types.js.map +1 -1
  363. package/build/utils/display/wrapper/TextWrapper.d.ts +1 -101
  364. package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -1
  365. package/build/utils/display/wrapper/TextWrapper.js +2 -470
  366. package/build/utils/display/wrapper/TextWrapper.js.map +1 -1
  367. package/build/utils/display/wrapper/types.d.ts +2 -74
  368. package/build/utils/display/wrapper/types.d.ts.map +1 -1
  369. package/build/utils/display/wrapper/types.js +2 -10
  370. package/build/utils/display/wrapper/types.js.map +1 -1
  371. package/build/utils/hardware/hardware.js +1 -1
  372. package/build/utils/hardware/hardware.js.map +1 -1
  373. package/build/utils/timers/timers.d.ts.map +1 -1
  374. package/build/utils/timers/timers.js +26 -4
  375. package/build/utils/timers/timers.js.map +1 -1
  376. package/package.json +8 -8
  377. package/src/engine.ts +24 -15
  378. package/src/facades/dev.ts +10 -0
  379. package/src/facades/display.ts +21 -8
  380. package/src/facades/displayMirror.ts +29 -0
  381. package/src/facades/glasses.ts +61 -1
  382. package/src/facades/memory.ts +1 -12
  383. package/src/facades/miniapps.ts +4 -1
  384. package/src/facades/pairing.ts +8 -6
  385. package/src/facades/permissions.ts +46 -0
  386. package/src/facades/phoneNotifications.ts +45 -26
  387. package/src/facades/settings.ts +1 -2
  388. package/src/generated/releaseMetadata.ts +4 -4
  389. package/src/index.ts +6 -9
  390. package/src/react/MentraLiveOtaFlow.tsx +2 -2
  391. package/src/react/useMentraLiveOta.ts +14 -8
  392. package/src/runtime/config.ts +1 -1
  393. package/src/services/AppRegistry.ts +43 -7
  394. package/src/services/BlobStore.ts +3 -3
  395. package/src/services/CloudClientService.ts +37 -10
  396. package/src/services/DevServerBridge.ts +12 -10
  397. package/src/services/DeviceEventRouter.ts +73 -74
  398. package/src/services/DisplayDiagnostics.ts +107 -0
  399. package/src/services/DisplayProcessor.ts +20 -55
  400. package/src/services/GestureDotsService.ts +77 -16
  401. package/src/services/GlassesKeyboardInput.ts +306 -0
  402. package/src/services/GlassesSensorService.ts +233 -0
  403. package/src/services/GlassesTouchInput.ts +128 -0
  404. package/src/services/HeadingService.ts +0 -24
  405. package/src/services/HotspotShutdown.ts +3 -1
  406. package/src/services/JSCrashloopReportService.ts +2 -2
  407. package/src/services/JSRouter.ts +29 -14
  408. package/src/services/LocalDisplayManager.ts +112 -26
  409. package/src/services/LocalMiniappDataMigration.ts +1 -1
  410. package/src/services/LocalMiniappRuntime.ts +500 -43
  411. package/src/services/LocalSttFallbackCoordinator.ts +28 -7
  412. package/src/services/MemoryStore.ts +32 -80
  413. package/src/services/MiniappEngine.ts +7 -7
  414. package/src/services/MiniappLauncher.ts +25 -1
  415. package/src/services/MirrorService.ts +139 -0
  416. package/src/services/NativeNavigationService.ts +29 -25
  417. package/src/services/NavigationHandlers.ts +10 -5
  418. package/src/services/OtaInstallCoordinator.ts +36 -34
  419. package/src/services/PairedGlassesLatch.ts +39 -0
  420. package/src/services/PhoneActivity.ts +116 -0
  421. package/src/services/PhoneCameraFovCoordinator.ts +6 -4
  422. package/src/services/PhoneNotificationsSync.ts +185 -103
  423. package/src/services/PhonePhotoCoordinator.ts +9 -10
  424. package/src/services/PhoneStreamCoordinator.ts +13 -11
  425. package/src/services/STTModelManager.ts +15 -1
  426. package/src/services/SceneRenderer.ts +148 -10
  427. package/src/services/StreamLifecycleController.ts +9 -7
  428. package/src/services/TTSModelManager.ts +1 -1
  429. package/src/services/UIRouter.ts +5 -5
  430. package/src/services/asg/galleryPathMigration.ts +1 -1
  431. package/src/services/asg/gallerySyncService.ts +2 -2
  432. package/src/services/asg/localStorageService.ts +3 -3
  433. package/src/services/debug/DashboardOpenTrace.ts +153 -0
  434. package/src/services/debug/dashboardOpenTimeline.ts +237 -0
  435. package/src/services/effectiveCapabilities.ts +32 -13
  436. package/src/services/gestureClaims.ts +72 -23
  437. package/src/services/manifestFields.ts +23 -0
  438. package/src/services/memoryStoreInstance.ts +2 -34
  439. package/src/services/mirrorSnapshot.ts +116 -0
  440. package/src/services/nativeNavigationGate.ts +14 -0
  441. package/src/services/notificationAppCatalog.ts +21 -0
  442. package/src/services/notifications/notificationPolicy.ts +87 -0
  443. package/src/services/pages/OverlayPages.ts +86 -0
  444. package/src/services/pages/PageHost.ts +116 -0
  445. package/src/services/pages/overlayApps.ts +72 -0
  446. package/src/services/pages/pageEligibility.ts +30 -0
  447. package/src/services/settingsBridge.ts +111 -0
  448. package/src/services/speakerProfileStoreInstance.ts +1 -1
  449. package/src/services/uiShim.ts +4 -4
  450. package/src/stores/appVisibility.ts +45 -0
  451. package/src/stores/apps.ts +110 -32
  452. package/src/stores/bluetoothSettingKeys.ts +1 -1
  453. package/src/stores/display.ts +18 -7
  454. package/src/stores/glasses.ts +15 -1
  455. package/src/stores/settings.ts +175 -51
  456. package/src/types/applet.ts +14 -1
  457. package/src/types/capabilities/even-realities-g2.ts +6 -0
  458. package/src/types/capabilities/simulated-glasses.ts +8 -4
  459. package/src/types/hardware.ts +34 -1
  460. package/src/types/index.ts +1 -0
  461. package/src/utils/debouncedPatch.ts +8 -4
  462. package/src/utils/devMiniappLaunch.ts +5 -3
  463. package/src/utils/display/measurer/TextMeasurer.ts +3 -346
  464. package/src/utils/display/measurer/script-detection.ts +10 -218
  465. package/src/utils/display/pixelArt.ts +3 -0
  466. package/src/utils/display/profiles/g1.ts +2 -236
  467. package/src/utils/display/profiles/g2.ts +2 -39
  468. package/src/utils/display/profiles/nex.ts +2 -166
  469. package/src/utils/display/profiles/types.ts +9 -132
  470. package/src/utils/display/profiles/z100.ts +2 -198
  471. package/src/utils/display/scene/degrade.ts +4 -1
  472. package/src/utils/display/scene/differ.ts +25 -1
  473. package/src/utils/display/scene/index.ts +5 -0
  474. package/src/utils/display/scene/process.ts +196 -13
  475. package/src/utils/display/scene/store.ts +0 -0
  476. package/src/utils/display/scene/svgPath.ts +163 -0
  477. package/src/utils/display/scene/types.ts +0 -0
  478. package/src/utils/display/wrapper/TextWrapper.ts +2 -546
  479. package/src/utils/display/wrapper/types.ts +3 -102
  480. package/src/utils/hardware/hardware.ts +1 -1
  481. package/src/utils/timers/timers.ts +32 -4
  482. package/build/services/CustomDashboardModel.d.ts +0 -48
  483. package/build/services/CustomDashboardModel.d.ts.map +0 -1
  484. package/build/services/CustomDashboardModel.js +0 -73
  485. package/build/services/CustomDashboardModel.js.map +0 -1
  486. package/build/services/CustomDashboardService.d.ts +0 -63
  487. package/build/services/CustomDashboardService.d.ts.map +0 -1
  488. package/build/services/CustomDashboardService.js +0 -576
  489. package/build/services/CustomDashboardService.js.map +0 -1
  490. package/build/services/DashboardCoordinator.d.ts +0 -26
  491. package/build/services/DashboardCoordinator.d.ts.map +0 -1
  492. package/build/services/DashboardCoordinator.js +0 -125
  493. package/build/services/DashboardCoordinator.js.map +0 -1
  494. package/build/services/iosNotificationAppCatalog.d.ts +0 -13
  495. package/build/services/iosNotificationAppCatalog.d.ts.map +0 -1
  496. package/build/services/iosNotificationAppCatalog.js +0 -28
  497. package/build/services/iosNotificationAppCatalog.js.map +0 -1
  498. package/src/services/CustomDashboardModel.ts +0 -83
  499. package/src/services/CustomDashboardService.ts +0 -598
  500. package/src/services/DashboardCoordinator.ts +0 -121
  501. package/src/services/iosNotificationAppCatalog.ts +0 -39
@@ -18,6 +18,7 @@ import {SETTINGS, useSettingsStore} from "../stores/settings"
18
18
  import {useGlassesStore} from "../stores/glasses"
19
19
  import {DeviceTypes} from "../types"
20
20
  import {getEffectiveCapabilities} from "./effectiveCapabilities"
21
+ import {BgTimer} from "../utils/timers"
21
22
  import {
22
23
  degradeScene,
23
24
  diffScene,
@@ -37,16 +38,51 @@ const LOG_TAG = "SCENE_RENDERER"
37
38
  export type LegacyLayout = {layoutType: string; [key: string]: unknown}
38
39
 
39
40
  export type SceneEmitResult =
40
- /** A SceneFrame went to native. */
41
- | {kind: "scene"; degraded: boolean; dropped: string[]}
41
+ /**
42
+ * A SceneFrame was committed. `sent` is false when the frame stayed
43
+ * phone-side (dashboard covering main). `settleMs` is how long the device
44
+ * keeps animating after it has the frame: the longest transition among the
45
+ * elements this frame changed, 0 on devices that jump.
46
+ */
47
+ | {kind: "scene"; degraded: boolean; dropped: string[]; seq: number; sent: boolean; settleMs: number}
42
48
  /** Degrade path: caller routes this legacy layout through the existing pipeline (null layout ⇒ clear). */
43
49
  | {kind: "legacy"; layout: LegacyLayout | null; degraded: boolean; dropped: string[]}
44
50
  /** No display capabilities on the connected device. */
45
51
  | {kind: "no-display"}
46
52
 
53
+ /** How a frame ended up, as reported by native (or inferred from a later frame's report). */
54
+ export interface ScenePresentation {
55
+ /** The device had the frame's content (this frame or a later one that folded it in). */
56
+ presented: boolean
57
+ /** A later frame's report settled this one. */
58
+ superseded: boolean
59
+ reason?: string
60
+ }
61
+
62
+ /** Longest geometry tween (255 frames at ~30 fps); rotation uses a separate millisecond clock. */
63
+ const MAX_SETTLE_MS = 255 * 33
64
+
65
+ /** Longest transition among the elements that actually change on the device this frame. */
66
+ function settleTimeOf(elements: FrameElement[]): number {
67
+ let ms = 0
68
+ for (const el of elements) {
69
+ if (el.change !== "updated" && el.change !== "moved") continue
70
+ const t = el.transition?.durationMs ?? 0
71
+ // Rotation has its own millisecond clock, beyond the geometry frame limit.
72
+ const duration = Math.min(t, el.rotation !== undefined ? 65535 : MAX_SETTLE_MS)
73
+ if (duration > ms) ms = duration
74
+ }
75
+ return ms
76
+ }
77
+
47
78
  class SceneRenderer {
48
79
  private static instance: SceneRenderer | null = null
49
80
  private store = new SceneStore()
81
+ private seqCounter = 0
82
+ private pending = new Map<number, {appId: string; resolve: (p: ScenePresentation) => void}>()
83
+ private presentedSub: {remove: () => void} | null = null
84
+ private settledSub: {remove: () => void} | null = null
85
+ private settledListeners = new Set<(seq: number) => void>()
50
86
 
51
87
  public static getInstance(): SceneRenderer {
52
88
  if (!SceneRenderer.instance) {
@@ -79,7 +115,11 @@ class SceneRenderer {
79
115
  maxImageElements: display.maxImageElements ?? 0,
80
116
  maxImagePx: display.maxImagePx,
81
117
  shapes: display.shapes ?? [],
118
+ animation: display.animation ?? false,
119
+ rotation: display.rotation ?? false,
120
+ depth: display.depth ?? false,
82
121
  intensityLevels: display.intensityLevels ?? 2,
122
+
83
123
  partialUpdate: display.partialUpdate ?? false,
84
124
  }
85
125
  }
@@ -225,12 +265,20 @@ class SceneRenderer {
225
265
  appId,
226
266
  view,
227
267
  sceneEpoch: this.store.currentEpoch(appId, view),
268
+ seq: ++this.seqCounter,
228
269
  elements: diffed,
229
270
  removed,
230
271
  canvas,
231
272
  }
232
- this.sendFrame(frame)
233
- return {kind: "scene", degraded: processed.degraded, dropped: processed.dropped}
273
+ const sent = this.sendFrame(frame)
274
+ return {
275
+ kind: "scene",
276
+ degraded: processed.degraded,
277
+ dropped: processed.dropped,
278
+ seq: frame.seq,
279
+ sent,
280
+ settleMs: caps.animation ? settleTimeOf(diffed) : 0,
281
+ }
234
282
  }
235
283
 
236
284
  /**
@@ -239,15 +287,90 @@ class SceneRenderer {
239
287
  * Returns false when nothing is retained.
240
288
  */
241
289
  public replayApp(appId: string, view: "main" | "dashboard"): boolean {
242
- const frame = this.store.buildReplayFrame(appId, view)
290
+ const frame = this.store.buildReplayFrame(appId, view, ++this.seqCounter)
243
291
  if (!frame) return false
244
292
  this.sendFrame(frame)
245
293
  return true
246
294
  }
247
295
 
248
- /** Forget an app's retained scenes (app stop). */
296
+ /** Forget an app's retained scenes (app stop). Frames still in flight will never show. */
249
297
  public clearApp(appId: string): void {
250
298
  this.store.clear(appId)
299
+ this.settlePending((p) => p.appId === appId, {presented: false, superseded: true, reason: "cleared"})
300
+ }
301
+
302
+ // ===========================================================================
303
+ // Presentation — native reports when the device has a frame
304
+ // ===========================================================================
305
+
306
+ /**
307
+ * Resolves once native reports frame `seq` on the device, or a later frame
308
+ * that folded it in. Never rejects; `timeoutMs` bounds a frame the device
309
+ * never acknowledges (link stalls, page rebuilding).
310
+ */
311
+ public whenPresented(seq: number, timeoutMs: number, appId: string): Promise<ScenePresentation> {
312
+ this.ensurePresentedListener()
313
+ return new Promise((resolve) => {
314
+ const timer = BgTimer.setTimeout(() => {
315
+ if (this.pending.delete(seq)) resolve({presented: false, superseded: false, reason: "no presentation report"})
316
+ }, timeoutMs)
317
+ this.pending.set(seq, {
318
+ appId,
319
+ resolve: (p) => {
320
+ BgTimer.clearTimeout(timer)
321
+ resolve(p)
322
+ },
323
+ })
324
+ })
325
+ }
326
+
327
+ private ensurePresentedListener(): void {
328
+ if (this.presentedSub) return
329
+ this.presentedSub = BluetoothSdk.addListener("scene_frame_presented", (event) => {
330
+ this.onFramePresented(event.seq, event.appId, event.presented, event.reason)
331
+ })
332
+ }
333
+
334
+ /**
335
+ * Fires with the host frame number once the glasses report that every
336
+ * animation the frame started has ended (Glassly CFW revision 27+). The
337
+ * device echoes the low 16 bits of the seq; the full number is recovered
338
+ * against the latest frame sent.
339
+ */
340
+ public onSettled(listener: (seq: number) => void): {remove: () => void} {
341
+ this.settledListeners.add(listener)
342
+ if (!this.settledSub) {
343
+ this.settledSub = BluetoothSdk.addListener("scene_settled", (event) => {
344
+ const seq = this.seqCounter - ((this.seqCounter - event.tag) & 0xffff)
345
+ if (seq <= 0) return
346
+ for (const settled of [...this.settledListeners]) settled(seq)
347
+ })
348
+ }
349
+ return {remove: () => this.settledListeners.delete(listener)}
350
+ }
351
+
352
+ /** A report for `seq` settles it and every earlier frame (folded in by the native pacer). */
353
+ private onFramePresented(seq: number, appId: string, presented: boolean, reason?: string): void {
354
+ this.settlePending(
355
+ (p, s) => s <= seq,
356
+ (p, s) =>
357
+ s === seq
358
+ ? {presented, superseded: false, reason}
359
+ : p.appId === appId
360
+ ? {presented, superseded: true, reason}
361
+ : {presented: false, superseded: true, reason: `superseded by ${appId}`},
362
+ )
363
+ }
364
+
365
+ private settlePending(
366
+ match: (p: {appId: string}, seq: number) => boolean,
367
+ outcome: ScenePresentation | ((p: {appId: string}, seq: number) => ScenePresentation),
368
+ ): void {
369
+ for (const [seq, p] of [...this.pending]) {
370
+ if (!match(p, seq)) continue
371
+ this.pending.delete(seq)
372
+ p.resolve(typeof outcome === "function" ? outcome(p, seq) : outcome)
373
+ }
251
374
  }
252
375
 
253
376
  /**
@@ -270,13 +393,16 @@ class SceneRenderer {
270
393
  */
271
394
  public markViewStale(view: "main" | "dashboard"): void {
272
395
  this.store.markViewStale(view)
396
+ // Whatever was in flight for the view got wiped with it.
397
+ this.settlePending(() => true, {presented: false, superseded: true, reason: "cleared"})
273
398
  }
274
399
 
275
- private sendFrame(frame: SceneFrame): void {
400
+ /** Returns false when the frame stayed phone-side (no presentation report will follow). */
401
+ private sendFrame(frame: SceneFrame): boolean {
276
402
  // Single native view: only the visible surface's frames go out. Suppressed
277
- // main frames stay committed; setDashboardActive(false) replays them.
278
- const dashboardActive = useDisplayStore.getState().dashboardActive
279
- if (dashboardActive !== (frame.view === "dashboard")) return
403
+ // main frames stay committed; setOverlayOwner(null) replays them.
404
+ const overlayHeld = useDisplayStore.getState().overlayOwner !== null
405
+ if (overlayHeld !== (frame.view === "dashboard")) return false
280
406
  try {
281
407
  // Frames carry the canvas they were laid out against; only a frame from
282
408
  // a path that predates the tag falls back to the current capabilities.
@@ -296,13 +422,18 @@ class SceneRenderer {
296
422
  view: frame.view,
297
423
  layout: {
298
424
  layoutType: "scene",
425
+ appId: frame.appId,
426
+ view: frame.view,
427
+ sceneEpoch: frame.sceneEpoch,
299
428
  width: frame.canvas?.width,
300
429
  height: frame.canvas?.height,
301
430
  elements: frame.elements,
302
431
  },
303
432
  })
433
+ return true
304
434
  } catch (err) {
305
435
  console.error(`${LOG_TAG}: native scene send failed:`, err)
436
+ return false
306
437
  }
307
438
  }
308
439
 
@@ -312,6 +443,13 @@ class SceneRenderer {
312
443
 
313
444
  public _resetForTest(): void {
314
445
  this.store.clearAll()
446
+ this.settlePending(() => true, {presented: false, superseded: false, reason: "reset"})
447
+ this.presentedSub?.remove()
448
+ this.presentedSub = null
449
+ this.settledSub?.remove()
450
+ this.settledSub = null
451
+ this.settledListeners.clear()
452
+ this.seqCounter = 0
315
453
  }
316
454
 
317
455
  public _lastFrameForTest(appId: string, view: string): FrameElement[] {
@@ -1,3 +1,5 @@
1
+ import {BgTimer} from "../utils/timers"
2
+
1
3
  /**
2
4
  * Drives RTMP stream liveliness checks via a keep-alive heartbeat:
3
5
  * `setActive(true)` starts the timer; each tick sends a keep-alive with a
@@ -35,7 +37,7 @@ export interface StreamLifecycleOptions {
35
37
 
36
38
  interface PendingAckInfo {
37
39
  sentAt: number
38
- timeout: ReturnType<typeof setTimeout>
40
+ timeout: number
39
41
  }
40
42
 
41
43
  /**
@@ -45,7 +47,7 @@ interface PendingAckInfo {
45
47
  * caller is expected to tear the stream down.
46
48
  */
47
49
  export class StreamLifecycleController {
48
- private keepAliveTimer?: ReturnType<typeof setInterval>
50
+ private keepAliveTimer?: number
49
51
  private pendingAcks: Map<string, PendingAckInfo> = new Map()
50
52
  private missedAcks = 0
51
53
  private lastActivityMs: number
@@ -103,7 +105,7 @@ export class StreamLifecycleController {
103
105
  return
104
106
  }
105
107
 
106
- clearTimeout(ackInfo.timeout)
108
+ BgTimer.clearTimeout(ackInfo.timeout)
107
109
  this.pendingAcks.delete(ackId)
108
110
  this.recordActivity()
109
111
 
@@ -125,7 +127,7 @@ export class StreamLifecycleController {
125
127
 
126
128
  private startTimer(): void {
127
129
  if (this.keepAliveTimer) return
128
- this.keepAliveTimer = setInterval(() => {
130
+ this.keepAliveTimer = BgTimer.setInterval(() => {
129
131
  void this.tick()
130
132
  }, this.keepAliveIntervalMs)
131
133
  this.logger.debug({streamId: this.streamId}, "Keep-alive timer started")
@@ -133,7 +135,7 @@ export class StreamLifecycleController {
133
135
 
134
136
  private stopTimer(): void {
135
137
  if (this.keepAliveTimer) {
136
- clearInterval(this.keepAliveTimer)
138
+ BgTimer.clearInterval(this.keepAliveTimer)
137
139
  this.keepAliveTimer = undefined
138
140
  this.logger.debug({streamId: this.streamId}, "Keep-alive timer stopped")
139
141
  }
@@ -150,7 +152,7 @@ export class StreamLifecycleController {
150
152
  const ackId = this.createAckId()
151
153
  const sentAt = this.now()
152
154
 
153
- const timeout = setTimeout(() => {
155
+ const timeout = BgTimer.setTimeout(() => {
154
156
  this.onAckTimeout(ackId, sentAt)
155
157
  }, this.ackTimeoutMs)
156
158
 
@@ -196,7 +198,7 @@ export class StreamLifecycleController {
196
198
 
197
199
  private clearPendingAcks(): void {
198
200
  for (const {timeout} of this.pendingAcks.values()) {
199
- clearTimeout(timeout)
201
+ BgTimer.clearTimeout(timeout)
200
202
  }
201
203
  this.pendingAcks.clear()
202
204
  }
@@ -421,7 +421,7 @@ class TTSModelManager {
421
421
 
422
422
  const outputDir = RNFS.CachesDirectoryPath || RNFS.TemporaryDirectoryPath
423
423
  const safeId = `${Date.now()}_${Math.random().toString(36).slice(2)}`
424
- const outputPath = `${outputDir}/glassly_tts_${safeId}.wav`
424
+ const outputPath = `${outputDir}/tts_${safeId}.wav`
425
425
  const ok = await BluetoothSdk.generateTtsAudio(
426
426
  text,
427
427
  this.getModelPath(),
@@ -16,7 +16,7 @@
16
16
  * │ │
17
17
  * ▼ ▼
18
18
  * ──── UIRouter.routeFromWebView ──── UIRouter.routeFromBackground
19
- * ──► Crust.jsDispatchToJs ──► webView.injectJavaScript("window.__glassly.recv(...)")
19
+ * ──► Crust.jsDispatchToJs ──► webView.injectJavaScript("window.__host.recv(...)")
20
20
  * {kind:"bridge", raw: JSON({
21
21
  * payload:{
22
22
  * type:"EVENT", streamType:"_ui",
@@ -71,7 +71,7 @@ export class UIRouter {
71
71
  /**
72
72
  * Called when a UI WebView mounts. `injectFn` wraps
73
73
  * `webView.injectJavaScript` — the router calls it with prebuilt
74
- * `window.__glassly.recv(...)` strings to deliver background-side
74
+ * `window.__host.recv(...)` strings to deliver background-side
75
75
  * frames into the WebView's glassly global.
76
76
  *
77
77
  * The router also pushes a UI_OPEN envelope to the background side
@@ -194,7 +194,7 @@ export class UIRouter {
194
194
  const literal = JSON.stringify(cancel)
195
195
  const escaped = JSON.stringify(literal)
196
196
  binding.inject(
197
- `if (window.__glassly && window.__glassly.recv) window.__glassly.recv(JSON.parse(${escaped})); true;`,
197
+ `if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`,
198
198
  )
199
199
  return
200
200
  }
@@ -208,7 +208,7 @@ export class UIRouter {
208
208
  const literal = JSON.stringify(outbound)
209
209
  const escaped = JSON.stringify(literal)
210
210
  binding.inject(
211
- `if (window.__glassly && window.__glassly.recv) window.__glassly.recv(JSON.parse(${escaped})); true;`,
211
+ `if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`,
212
212
  )
213
213
  }
214
214
 
@@ -223,7 +223,7 @@ export class UIRouter {
223
223
  const literal = JSON.stringify(frame)
224
224
  const escaped = JSON.stringify(literal)
225
225
  binding.inject(
226
- `if (window.__glassly && window.__glassly.recv) window.__glassly.recv(JSON.parse(${escaped})); true;`,
226
+ `if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`,
227
227
  )
228
228
  }
229
229
 
@@ -15,7 +15,7 @@ export function toPortableGalleryPath(path: string, documentDirectoryPath: strin
15
15
 
16
16
  if (!candidate || candidate.includes("\0")) return null
17
17
  const segments = candidate.split("/")
18
- if (segments[0] !== "GlasslyPhotos" || segments.some((segment) => !segment || segment === "." || segment === "..")) {
18
+ if (segments[0] !== "Photos" || segments.some((segment) => !segment || segment === "." || segment === "..")) {
19
19
  return null
20
20
  }
21
21
  return segments.join("/")
@@ -404,7 +404,7 @@ class GallerySyncService {
404
404
  return await Promise.race([
405
405
  CrustModule.isLocationServicesEnabled(),
406
406
  new Promise<boolean>((_, reject) =>
407
- setTimeout(
407
+ BgTimer.setTimeout(
408
408
  () => reject(new Error("Location services check timed out")),
409
409
  TIMING.LOCATION_SERVICES_CHECK_TIMEOUT_MS,
410
410
  ),
@@ -434,7 +434,7 @@ class GallerySyncService {
434
434
  if (state !== "unknown") {
435
435
  return state === "on"
436
436
  }
437
- await new Promise((resolve) => setTimeout(resolve, 50))
437
+ await new Promise<void>((resolve) => BgTimer.setTimeout(resolve, 50))
438
438
  }
439
439
  console.warn("[GallerySyncService] Bluetooth state still unknown after 500ms - assuming enabled")
440
440
  return true
@@ -51,8 +51,8 @@ export class LocalStorageService {
51
51
  private readonly CLIENT_ID_KEY = "asg_client_id"
52
52
  private readonly SYNC_QUEUE_KEY = "asg_sync_queue"
53
53
  private readonly QUARANTINED_FILES_KEY = "asg_quarantined_downloaded_files_v1"
54
- private readonly ASG_PHOTOS_DIR = `${RNFS.DocumentDirectoryPath}/GlasslyPhotos`
55
- private readonly ASG_THUMBNAILS_DIR = `${RNFS.DocumentDirectoryPath}/GlasslyPhotos/thumbnails`
54
+ private readonly ASG_PHOTOS_DIR = `${RNFS.DocumentDirectoryPath}/Photos`
55
+ private readonly ASG_THUMBNAILS_DIR = `${RNFS.DocumentDirectoryPath}/Photos/thumbnails`
56
56
 
57
57
  private constructor() {
58
58
  this.initializeDirectories()
@@ -248,7 +248,7 @@ export class LocalStorageService {
248
248
  let didMigrate = false
249
249
 
250
250
  // Normalize every record before saving. This fixes the old read-absolute/write-one-relative
251
- // bug and migrates stale iOS container UUID paths via their Documents/GlasslyPhotos suffix.
251
+ // bug and migrates stale iOS container UUID paths via their Documents/Photos suffix.
252
252
  for (const [name, file] of Object.entries(files as Record<string, DownloadedFile>)) {
253
253
  const relativePath = this.toPortableRelativePath(file.filePath)
254
254
  const relativeThumbnailPath = file.thumbnailPath
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Dashboard open timing (Debug Settings): stamps a dashboard open from the
3
+ * gesture reaching the phone to the glasses presenting the first overlay
4
+ * frame, logs it, and hands it to the host, which posts it as a phone
5
+ * notification. Only a gesture with the setting on starts a trace; every
6
+ * other entry is a no-op while none runs.
7
+ */
8
+ import BluetoothSdk from "@glassly/bluetooth-sdk/internal"
9
+
10
+ import {useDisplayStore} from "../../stores/display"
11
+ import {useGlassesStore} from "../../stores/glasses"
12
+ import {SETTINGS, useSettingsStore} from "../../stores/settings"
13
+ import {BgTimer} from "../../utils/timers"
14
+ import {isGlassesConnected} from "../GlassesReadiness"
15
+ import {onOverlayAppsChange, overlayApps} from "../pages/overlayApps"
16
+ import {
17
+ DashboardOpenTimeline,
18
+ formatDashboardOpenTrace,
19
+ type DashboardOpenTrace,
20
+ type DashboardOpenTrigger,
21
+ } from "./dashboardOpenTimeline"
22
+
23
+ const LOG_TAG = "DashboardOpenTrace"
24
+
25
+ export interface DashboardOpenReport {
26
+ title: string
27
+ body: string
28
+ trace: DashboardOpenTrace
29
+ }
30
+
31
+ class DashboardOpenTracer {
32
+ private readonly timeline = new DashboardOpenTimeline({
33
+ now: () => Date.now(),
34
+ setTimeout: (callback, ms) => BgTimer.setTimeout(callback, ms),
35
+ clearTimeout: (handle) => BgTimer.clearTimeout(handle),
36
+ onFinished: (trace) => this.report(trace),
37
+ })
38
+ private listeners = new Set<(report: DashboardOpenReport) => void>()
39
+ private lastOpenAt: number | null = null
40
+ private overlayConnectedAt = new Map<string, number>()
41
+ private glassesConnectedAt: number | null = null
42
+ private frameSubs: Array<{remove: () => void}> = []
43
+ private unsubs: Array<() => void> = []
44
+
45
+ /** Track the context an open is judged against. Idempotent; returns the stop. */
46
+ start(): () => void {
47
+ if (this.unsubs.length === 0) {
48
+ this.syncOverlayApps()
49
+ this.syncGlasses(isGlassesConnected(useGlassesStore.getState().connection))
50
+ this.unsubs.push(
51
+ onOverlayAppsChange(() => this.syncOverlayApps()),
52
+ useGlassesStore.subscribe(
53
+ (state) => isGlassesConnected(state.connection),
54
+ (connected) => this.syncGlasses(connected),
55
+ ),
56
+ )
57
+ }
58
+ return () => this.stop()
59
+ }
60
+
61
+ stop(): void {
62
+ for (const unsub of this.unsubs) unsub()
63
+ this.unsubs = []
64
+ this.timeline.cancel()
65
+ this.unwatchFrames()
66
+ }
67
+
68
+ onReport(listener: (report: DashboardOpenReport) => void): () => void {
69
+ this.listeners.add(listener)
70
+ return () => {
71
+ this.listeners.delete(listener)
72
+ }
73
+ }
74
+
75
+ /** An opening gesture reached the phone; `nativeAt` is native's receipt time when the event has one. */
76
+ trigger(trigger: DashboardOpenTrigger, nativeAt?: number): void {
77
+ if (useSettingsStore.getState().getSetting(SETTINGS.debug_dashboard_open_timing.key) !== true) return
78
+ // With a page up the gesture moves within the dashboard or closes it.
79
+ if (useDisplayStore.getState().overlayOwner !== null) return
80
+ const now = Date.now()
81
+ this.timeline.trigger(
82
+ trigger,
83
+ {
84
+ sinceLastOpenMs: this.lastOpenAt === null ? null : now - this.lastOpenAt,
85
+ glassesUpMs: this.glassesConnectedAt === null ? null : now - this.glassesConnectedAt,
86
+ },
87
+ nativeAt,
88
+ )
89
+ }
90
+
91
+ showViewRequested(packageName: string): void {
92
+ this.timeline.showViewRequested(this.overlayConnectedAt.get(packageName) ?? null)
93
+ }
94
+
95
+ slotGranted(): void {
96
+ this.lastOpenAt = Date.now()
97
+ this.timeline.slotGranted()
98
+ }
99
+
100
+ frameSent(seq: number): void {
101
+ if (!this.timeline.tracing || this.timeline.frameSeq !== null) return
102
+ this.timeline.frameSent(seq)
103
+ if (this.timeline.frameSeq !== null) this.watchFrames()
104
+ }
105
+
106
+ // Raw device events rather than SceneRenderer.whenPresented: that keeps one
107
+ // waiter per seq, and the display manager's awaited render already holds it.
108
+ private watchFrames(): void {
109
+ if (this.frameSubs.length > 0) return
110
+ this.frameSubs.push(
111
+ BluetoothSdk.addListener("scene_frame_presented", (event) => {
112
+ this.timeline.framePresented(event.seq, event.presented, event.reason)
113
+ }),
114
+ BluetoothSdk.addListener("scene_settled", (event) => {
115
+ const frameSeq = this.timeline.frameSeq
116
+ if (frameSeq === null) return
117
+ // The device echoes the low 16 bits of the frame number.
118
+ const ahead = (event.tag - frameSeq) & 0xffff
119
+ if (ahead < 0x8000) this.timeline.frameSettled(frameSeq + ahead)
120
+ }),
121
+ )
122
+ }
123
+
124
+ private unwatchFrames(): void {
125
+ for (const sub of this.frameSubs) sub.remove()
126
+ this.frameSubs = []
127
+ }
128
+
129
+ private report(trace: DashboardOpenTrace): void {
130
+ this.unwatchFrames()
131
+ const {title, body} = formatDashboardOpenTrace(trace)
132
+ console.log(`${LOG_TAG}: ${title} | ${body.split("\n").join(" | ")}`)
133
+ for (const listener of Array.from(this.listeners)) listener({title, body, trace})
134
+ }
135
+
136
+ private syncOverlayApps(): void {
137
+ const running = new Set(overlayApps())
138
+ for (const packageName of this.overlayConnectedAt.keys()) {
139
+ if (!running.has(packageName)) this.overlayConnectedAt.delete(packageName)
140
+ }
141
+ for (const packageName of running) {
142
+ if (!this.overlayConnectedAt.has(packageName)) this.overlayConnectedAt.set(packageName, Date.now())
143
+ }
144
+ }
145
+
146
+ private syncGlasses(connected: boolean): void {
147
+ if (!connected) this.glassesConnectedAt = null
148
+ else if (this.glassesConnectedAt === null) this.glassesConnectedAt = Date.now()
149
+ }
150
+ }
151
+
152
+ const dashboardOpenTrace = new DashboardOpenTracer()
153
+ export default dashboardOpenTrace