@mentra/engine 0.1.0-dev.0 → 0.1.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (441) hide show
  1. package/README.md +42 -1
  2. package/build/engine.d.ts +11 -3
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +7 -2
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts +3 -2
  7. package/build/facades/dev.d.ts.map +1 -1
  8. package/build/facades/dev.js +18 -12
  9. package/build/facades/dev.js.map +1 -1
  10. package/build/facades/gallery.js +1 -1
  11. package/build/facades/gallery.js.map +1 -1
  12. package/build/facades/glasses.d.ts +1 -0
  13. package/build/facades/glasses.d.ts.map +1 -1
  14. package/build/facades/glasses.js +19 -4
  15. package/build/facades/glasses.js.map +1 -1
  16. package/build/facades/glassesSettings.d.ts.map +1 -1
  17. package/build/facades/glassesSettings.js +1 -0
  18. package/build/facades/glassesSettings.js.map +1 -1
  19. package/build/facades/miniapps.d.ts +4 -0
  20. package/build/facades/miniapps.d.ts.map +1 -1
  21. package/build/facades/miniapps.js +5 -0
  22. package/build/facades/miniapps.js.map +1 -1
  23. package/build/facades/ota.d.ts +11 -2
  24. package/build/facades/ota.d.ts.map +1 -1
  25. package/build/facades/ota.js +19 -4
  26. package/build/facades/ota.js.map +1 -1
  27. package/build/facades/pairing.d.ts +4 -0
  28. package/build/facades/pairing.d.ts.map +1 -1
  29. package/build/facades/pairing.js +10 -8
  30. package/build/facades/pairing.js.map +1 -1
  31. package/build/facades/permissions.d.ts +10 -0
  32. package/build/facades/permissions.d.ts.map +1 -1
  33. package/build/facades/permissions.js +10 -0
  34. package/build/facades/permissions.js.map +1 -1
  35. package/build/facades/phoneNotifications.d.ts +0 -4
  36. package/build/facades/phoneNotifications.d.ts.map +1 -1
  37. package/build/facades/phoneNotifications.js +4 -14
  38. package/build/facades/phoneNotifications.js.map +1 -1
  39. package/build/index.d.ts +6 -3
  40. package/build/index.d.ts.map +1 -1
  41. package/build/index.js +4 -2
  42. package/build/index.js.map +1 -1
  43. package/build/internal.d.ts +3 -2
  44. package/build/internal.d.ts.map +1 -1
  45. package/build/internal.js +2 -1
  46. package/build/internal.js.map +1 -1
  47. package/build/react/MentraLiveOtaFlow.d.ts +38 -0
  48. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  49. package/build/react/MentraLiveOtaFlow.js +528 -0
  50. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  51. package/build/react/index.d.ts +2 -0
  52. package/build/react/index.d.ts.map +1 -0
  53. package/build/react/index.js +2 -0
  54. package/build/react/index.js.map +1 -0
  55. package/build/react/useEngineSnapshot.d.ts +2 -0
  56. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  57. package/build/react/useEngineSnapshot.js +14 -0
  58. package/build/react/useEngineSnapshot.js.map +1 -0
  59. package/build/runtime/bootstrap.d.ts +24 -1
  60. package/build/runtime/bootstrap.d.ts.map +1 -1
  61. package/build/runtime/bootstrap.js +17 -0
  62. package/build/runtime/bootstrap.js.map +1 -1
  63. package/build/runtime/scanQrSeam.d.ts +7 -0
  64. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  65. package/build/runtime/scanQrSeam.js +16 -0
  66. package/build/runtime/scanQrSeam.js.map +1 -0
  67. package/build/services/AppRegistry.d.ts +33 -57
  68. package/build/services/AppRegistry.d.ts.map +1 -1
  69. package/build/services/AppRegistry.js +193 -144
  70. package/build/services/AppRegistry.js.map +1 -1
  71. package/build/services/AudioCloudUplink.d.ts +12 -0
  72. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  73. package/build/services/AudioCloudUplink.js +22 -1
  74. package/build/services/AudioCloudUplink.js.map +1 -1
  75. package/build/services/AudioPlaybackService.d.ts +41 -2
  76. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  77. package/build/services/AudioPlaybackService.js +250 -33
  78. package/build/services/AudioPlaybackService.js.map +1 -1
  79. package/build/services/BlobStore.d.ts +2 -1
  80. package/build/services/BlobStore.d.ts.map +1 -1
  81. package/build/services/BlobStore.js +17 -9
  82. package/build/services/BlobStore.js.map +1 -1
  83. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  84. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  85. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  86. package/build/services/CloudClientService.d.ts +15 -0
  87. package/build/services/CloudClientService.d.ts.map +1 -1
  88. package/build/services/CloudClientService.js +93 -1
  89. package/build/services/CloudClientService.js.map +1 -1
  90. package/build/services/DeviceEventRouter.js +5 -5
  91. package/build/services/DeviceEventRouter.js.map +1 -1
  92. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  93. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  94. package/build/services/ForegroundLocationPermission.js +12 -0
  95. package/build/services/ForegroundLocationPermission.js.map +1 -0
  96. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  97. package/build/services/GlassesSettingsSync.js +9 -3
  98. package/build/services/GlassesSettingsSync.js.map +1 -1
  99. package/build/services/GlassesStatusProjection.d.ts +2 -1
  100. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  101. package/build/services/GlassesStatusProjection.js +15 -8
  102. package/build/services/GlassesStatusProjection.js.map +1 -1
  103. package/build/services/HotspotOtaTransport.d.ts +29 -0
  104. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  105. package/build/services/HotspotOtaTransport.js +146 -0
  106. package/build/services/HotspotOtaTransport.js.map +1 -0
  107. package/build/services/HotspotShutdown.d.ts +17 -0
  108. package/build/services/HotspotShutdown.d.ts.map +1 -0
  109. package/build/services/HotspotShutdown.js +29 -0
  110. package/build/services/HotspotShutdown.js.map +1 -0
  111. package/build/services/LocalDisplayManager.d.ts +15 -0
  112. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  113. package/build/services/LocalDisplayManager.js +106 -20
  114. package/build/services/LocalDisplayManager.js.map +1 -1
  115. package/build/services/LocalMiniappRuntime.d.ts +74 -2
  116. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  117. package/build/services/LocalMiniappRuntime.js +785 -291
  118. package/build/services/LocalMiniappRuntime.js.map +1 -1
  119. package/build/services/LocalMiniappStorage.d.ts +32 -0
  120. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  121. package/build/services/LocalMiniappStorage.js +66 -0
  122. package/build/services/LocalMiniappStorage.js.map +1 -0
  123. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  124. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  125. package/build/services/LocalMiniappUserIdentity.js +43 -0
  126. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  127. package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
  128. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  129. package/build/services/LocalSttFallbackCoordinator.js +18 -12
  130. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  131. package/build/services/MicStateCoordinator.d.ts +42 -1
  132. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  133. package/build/services/MicStateCoordinator.js +141 -3
  134. package/build/services/MicStateCoordinator.js.map +1 -1
  135. package/build/services/MiniappLauncher.d.ts.map +1 -1
  136. package/build/services/MiniappLauncher.js +23 -3
  137. package/build/services/MiniappLauncher.js.map +1 -1
  138. package/build/services/MiniappLiveness.d.ts +12 -0
  139. package/build/services/MiniappLiveness.d.ts.map +1 -0
  140. package/build/services/MiniappLiveness.js +16 -0
  141. package/build/services/MiniappLiveness.js.map +1 -0
  142. package/build/services/NativeHttpResponse.d.ts +3 -0
  143. package/build/services/NativeHttpResponse.d.ts.map +1 -0
  144. package/build/services/NativeHttpResponse.js +6 -0
  145. package/build/services/NativeHttpResponse.js.map +1 -0
  146. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  147. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  148. package/build/services/OtaArtifactDownloader.js +226 -0
  149. package/build/services/OtaArtifactDownloader.js.map +1 -0
  150. package/build/services/OtaAutoChain.d.ts +34 -0
  151. package/build/services/OtaAutoChain.d.ts.map +1 -0
  152. package/build/services/OtaAutoChain.js +83 -0
  153. package/build/services/OtaAutoChain.js.map +1 -0
  154. package/build/services/OtaErrorMapping.d.ts +18 -0
  155. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  156. package/build/services/OtaErrorMapping.js +63 -0
  157. package/build/services/OtaErrorMapping.js.map +1 -0
  158. package/build/services/OtaInstallCoordinator.d.ts +94 -14
  159. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  160. package/build/services/OtaInstallCoordinator.js +574 -130
  161. package/build/services/OtaInstallCoordinator.js.map +1 -1
  162. package/build/services/OtaService.d.ts.map +1 -1
  163. package/build/services/OtaService.js +8 -1
  164. package/build/services/OtaService.js.map +1 -1
  165. package/build/services/OtaUpdateCheckService.d.ts +38 -3
  166. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  167. package/build/services/OtaUpdateCheckService.js +142 -22
  168. package/build/services/OtaUpdateCheckService.js.map +1 -1
  169. package/build/services/PhoneCalendarHelpers.d.ts +32 -0
  170. package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
  171. package/build/services/PhoneCalendarHelpers.js +157 -0
  172. package/build/services/PhoneCalendarHelpers.js.map +1 -0
  173. package/build/services/PhoneCalendarService.d.ts +5 -0
  174. package/build/services/PhoneCalendarService.d.ts.map +1 -0
  175. package/build/services/PhoneCalendarService.js +45 -0
  176. package/build/services/PhoneCalendarService.js.map +1 -0
  177. package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
  178. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
  179. package/build/services/PhoneCameraFovCoordinator.js +194 -0
  180. package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
  181. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  182. package/build/services/PhoneNotificationsSync.js +12 -10
  183. package/build/services/PhoneNotificationsSync.js.map +1 -1
  184. package/build/services/PhonePhotoCoordinator.d.ts +26 -2
  185. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  186. package/build/services/PhonePhotoCoordinator.js +79 -9
  187. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  188. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  189. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  190. package/build/services/PhoneStreamCoordinator.js +125 -13
  191. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  192. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  193. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  194. package/build/services/PhoneVideoCoordinator.js +10 -0
  195. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  196. package/build/services/SceneRenderer.d.ts.map +1 -1
  197. package/build/services/SceneRenderer.js +15 -0
  198. package/build/services/SceneRenderer.js.map +1 -1
  199. package/build/services/SentenceTtsPipeline.d.ts +31 -0
  200. package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
  201. package/build/services/SentenceTtsPipeline.js +67 -0
  202. package/build/services/SentenceTtsPipeline.js.map +1 -0
  203. package/build/services/SupportProfileSync.d.ts +22 -0
  204. package/build/services/SupportProfileSync.d.ts.map +1 -0
  205. package/build/services/SupportProfileSync.js +213 -0
  206. package/build/services/SupportProfileSync.js.map +1 -0
  207. package/build/services/TranscriptionRouting.d.ts +12 -0
  208. package/build/services/TranscriptionRouting.d.ts.map +1 -0
  209. package/build/services/TranscriptionRouting.js +24 -0
  210. package/build/services/TranscriptionRouting.js.map +1 -0
  211. package/build/services/TtsTextSanitizer.d.ts +5 -0
  212. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  213. package/build/services/TtsTextSanitizer.js +61 -0
  214. package/build/services/TtsTextSanitizer.js.map +1 -0
  215. package/build/services/WifiAdbRequest.d.ts +17 -0
  216. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  217. package/build/services/WifiAdbRequest.js +35 -0
  218. package/build/services/WifiAdbRequest.js.map +1 -0
  219. package/build/services/asg/asgCameraApi.d.ts +43 -0
  220. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  221. package/build/services/asg/asgCameraApi.js +509 -26
  222. package/build/services/asg/asgCameraApi.js.map +1 -1
  223. package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
  224. package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
  225. package/build/services/asg/cameraRollExportCoordinator.js +618 -0
  226. package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
  227. package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
  228. package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
  229. package/build/services/asg/cameraRollExportLedger.js +78 -0
  230. package/build/services/asg/cameraRollExportLedger.js.map +1 -0
  231. package/build/services/asg/galleryNotices.d.ts +1 -1
  232. package/build/services/asg/galleryNotices.d.ts.map +1 -1
  233. package/build/services/asg/galleryNotices.js.map +1 -1
  234. package/build/services/asg/galleryPathMigration.d.ts +3 -0
  235. package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
  236. package/build/services/asg/galleryPathMigration.js +26 -0
  237. package/build/services/asg/galleryPathMigration.js.map +1 -0
  238. package/build/services/asg/gallerySettingsService.d.ts +1 -0
  239. package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
  240. package/build/services/asg/gallerySettingsService.js +2 -0
  241. package/build/services/asg/gallerySettingsService.js.map +1 -1
  242. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  243. package/build/services/asg/gallerySyncService.js +162 -56
  244. package/build/services/asg/gallerySyncService.js.map +1 -1
  245. package/build/services/asg/galleryTransferLedger.d.ts +58 -0
  246. package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
  247. package/build/services/asg/galleryTransferLedger.js +225 -0
  248. package/build/services/asg/galleryTransferLedger.js.map +1 -0
  249. package/build/services/asg/localNetworkTransport.d.ts +15 -0
  250. package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
  251. package/build/services/asg/localNetworkTransport.js +144 -0
  252. package/build/services/asg/localNetworkTransport.js.map +1 -0
  253. package/build/services/asg/localStorageService.d.ts +18 -0
  254. package/build/services/asg/localStorageService.d.ts.map +1 -1
  255. package/build/services/asg/localStorageService.js +168 -19
  256. package/build/services/asg/localStorageService.js.map +1 -1
  257. package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
  258. package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
  259. package/build/services/asg/mediaProcessingQueue.js +193 -62
  260. package/build/services/asg/mediaProcessingQueue.js.map +1 -1
  261. package/build/services/audioPlaybackAssets.d.ts +8 -0
  262. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  263. package/build/services/audioPlaybackAssets.js +7 -0
  264. package/build/services/audioPlaybackAssets.js.map +1 -0
  265. package/build/services/gallerySyncClock.js +1 -1
  266. package/build/services/gallerySyncClock.js.map +1 -1
  267. package/build/services/glassesClockSync.js +2 -2
  268. package/build/services/glassesClockSync.js.map +1 -1
  269. package/build/services/manifestActions.d.ts +7 -0
  270. package/build/services/manifestActions.d.ts.map +1 -0
  271. package/build/services/manifestActions.js +25 -0
  272. package/build/services/manifestActions.js.map +1 -0
  273. package/build/services/otaDisplayState.d.ts +22 -11
  274. package/build/services/otaDisplayState.d.ts.map +1 -1
  275. package/build/services/otaDisplayState.js +36 -14
  276. package/build/services/otaDisplayState.js.map +1 -1
  277. package/build/services/otaInstallPolicy.d.ts +15 -3
  278. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  279. package/build/services/otaInstallPolicy.js +24 -3
  280. package/build/services/otaInstallPolicy.js.map +1 -1
  281. package/build/services/otaManifestUrl.d.ts +2 -0
  282. package/build/services/otaManifestUrl.d.ts.map +1 -0
  283. package/build/services/{asgOtaVersionUrl.js → otaManifestUrl.js} +15 -5
  284. package/build/services/otaManifestUrl.js.map +1 -0
  285. package/build/services/slimStreamStatus.d.ts +11 -0
  286. package/build/services/slimStreamStatus.d.ts.map +1 -1
  287. package/build/services/slimStreamStatus.js +14 -4
  288. package/build/services/slimStreamStatus.js.map +1 -1
  289. package/build/stores/apps.d.ts.map +1 -1
  290. package/build/stores/apps.js +11 -0
  291. package/build/stores/apps.js.map +1 -1
  292. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  293. package/build/stores/bluetoothSettingKeys.js +2 -0
  294. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  295. package/build/stores/gallerySync.d.ts +2 -0
  296. package/build/stores/gallerySync.d.ts.map +1 -1
  297. package/build/stores/gallerySync.js +2 -0
  298. package/build/stores/gallerySync.js.map +1 -1
  299. package/build/stores/glasses.d.ts.map +1 -1
  300. package/build/stores/glasses.js +3 -0
  301. package/build/stores/glasses.js.map +1 -1
  302. package/build/stores/settings.d.ts +17 -0
  303. package/build/stores/settings.d.ts.map +1 -1
  304. package/build/stores/settings.js +157 -17
  305. package/build/stores/settings.js.map +1 -1
  306. package/build/types/applet.d.ts +2 -0
  307. package/build/types/applet.d.ts.map +1 -1
  308. package/build/types/applet.js.map +1 -1
  309. package/build/types/asg.d.ts +7 -0
  310. package/build/types/asg.d.ts.map +1 -1
  311. package/build/types/asg.js.map +1 -1
  312. package/build/types/enums.d.ts +1 -0
  313. package/build/types/enums.d.ts.map +1 -1
  314. package/build/types/enums.js +1 -0
  315. package/build/types/enums.js.map +1 -1
  316. package/build/types/hardware.d.ts +1 -0
  317. package/build/types/hardware.d.ts.map +1 -1
  318. package/build/types/hardware.js +14 -0
  319. package/build/types/hardware.js.map +1 -1
  320. package/build/utils/configuredDevHost.d.ts +6 -0
  321. package/build/utils/configuredDevHost.d.ts.map +1 -0
  322. package/build/utils/configuredDevHost.js +19 -0
  323. package/build/utils/configuredDevHost.js.map +1 -0
  324. package/build/utils/devMiniappLaunch.d.ts +19 -8
  325. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  326. package/build/utils/devMiniappLaunch.js +144 -21
  327. package/build/utils/devMiniappLaunch.js.map +1 -1
  328. package/build/utils/diagnosticContext.d.ts.map +1 -1
  329. package/build/utils/diagnosticContext.js +15 -17
  330. package/build/utils/diagnosticContext.js.map +1 -1
  331. package/build/utils/hardware/hardware.d.ts.map +1 -1
  332. package/build/utils/hardware/hardware.js +7 -3
  333. package/build/utils/hardware/hardware.js.map +1 -1
  334. package/build/utils/miniappDiagnostics.d.ts +64 -0
  335. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  336. package/build/utils/miniappDiagnostics.js +173 -0
  337. package/build/utils/miniappDiagnostics.js.map +1 -0
  338. package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
  339. package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
  340. package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
  341. package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
  342. package/build/utils/timers/timers.d.ts.map +1 -1
  343. package/build/utils/timers/timers.js +55 -18
  344. package/build/utils/timers/timers.js.map +1 -1
  345. package/package.json +25 -15
  346. package/src/assets/silence.wav +0 -0
  347. package/src/engine.ts +7 -2
  348. package/src/facades/dev.ts +17 -12
  349. package/src/facades/gallery.ts +1 -1
  350. package/src/facades/glasses.ts +17 -4
  351. package/src/facades/glassesSettings.ts +5 -0
  352. package/src/facades/miniapps.ts +7 -0
  353. package/src/facades/ota.ts +19 -4
  354. package/src/facades/pairing.ts +11 -7
  355. package/src/facades/permissions.ts +14 -0
  356. package/src/facades/phoneNotifications.ts +4 -13
  357. package/src/index.ts +26 -2
  358. package/src/internal.ts +3 -1
  359. package/src/react/MentraLiveOtaFlow.tsx +856 -0
  360. package/src/react/index.ts +7 -0
  361. package/src/react/useEngineSnapshot.ts +16 -0
  362. package/src/runtime/bootstrap.ts +33 -1
  363. package/src/runtime/scanQrSeam.ts +20 -0
  364. package/src/services/AppRegistry.ts +224 -149
  365. package/src/services/AudioCloudUplink.ts +23 -1
  366. package/src/services/AudioPlaybackService.ts +287 -38
  367. package/src/services/BlobStore.ts +22 -9
  368. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  369. package/src/services/CloudClientService.ts +96 -1
  370. package/src/services/DeviceEventRouter.ts +5 -5
  371. package/src/services/ForegroundLocationPermission.ts +24 -0
  372. package/src/services/GlassesSettingsSync.ts +9 -3
  373. package/src/services/GlassesStatusProjection.ts +16 -8
  374. package/src/services/HotspotOtaTransport.ts +184 -0
  375. package/src/services/HotspotShutdown.ts +41 -0
  376. package/src/services/LocalDisplayManager.ts +112 -21
  377. package/src/services/LocalMiniappRuntime.ts +967 -346
  378. package/src/services/LocalMiniappStorage.ts +82 -0
  379. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  380. package/src/services/LocalSttFallbackCoordinator.ts +19 -12
  381. package/src/services/MicStateCoordinator.ts +169 -4
  382. package/src/services/MiniappLauncher.ts +30 -3
  383. package/src/services/MiniappLiveness.ts +24 -0
  384. package/src/services/NativeHttpResponse.ts +6 -0
  385. package/src/services/OtaArtifactDownloader.ts +312 -0
  386. package/src/services/OtaAutoChain.ts +106 -0
  387. package/src/services/OtaErrorMapping.ts +80 -0
  388. package/src/services/OtaInstallCoordinator.ts +645 -143
  389. package/src/services/OtaService.ts +11 -5
  390. package/src/services/OtaUpdateCheckService.ts +180 -20
  391. package/src/services/PhoneCalendarHelpers.ts +212 -0
  392. package/src/services/PhoneCalendarService.ts +65 -0
  393. package/src/services/PhoneCameraFovCoordinator.ts +210 -0
  394. package/src/services/PhoneNotificationsSync.ts +12 -10
  395. package/src/services/PhonePhotoCoordinator.ts +116 -18
  396. package/src/services/PhoneStreamCoordinator.ts +139 -25
  397. package/src/services/PhoneVideoCoordinator.ts +11 -0
  398. package/src/services/SceneRenderer.ts +16 -0
  399. package/src/services/SentenceTtsPipeline.ts +106 -0
  400. package/src/services/SupportProfileSync.ts +218 -0
  401. package/src/services/TranscriptionRouting.ts +37 -0
  402. package/src/services/TtsTextSanitizer.ts +66 -0
  403. package/src/services/WifiAdbRequest.ts +53 -0
  404. package/src/services/asg/asgCameraApi.ts +615 -33
  405. package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
  406. package/src/services/asg/cameraRollExportLedger.ts +122 -0
  407. package/src/services/asg/galleryNotices.ts +1 -0
  408. package/src/services/asg/galleryPathMigration.ts +22 -0
  409. package/src/services/asg/gallerySettingsService.ts +3 -0
  410. package/src/services/asg/gallerySyncService.ts +184 -73
  411. package/src/services/asg/galleryTransferLedger.ts +312 -0
  412. package/src/services/asg/localNetworkTransport.ts +169 -0
  413. package/src/services/asg/localStorageService.ts +179 -24
  414. package/src/services/asg/mediaProcessingQueue.ts +209 -62
  415. package/src/services/audioPlaybackAssets.ts +8 -0
  416. package/src/services/gallerySyncClock.ts +1 -1
  417. package/src/services/glassesClockSync.ts +2 -2
  418. package/src/services/manifestActions.ts +30 -0
  419. package/src/services/otaDisplayState.ts +57 -16
  420. package/src/services/otaInstallPolicy.ts +29 -3
  421. package/src/services/{asgOtaVersionUrl.ts → otaManifestUrl.ts} +16 -4
  422. package/src/services/slimStreamStatus.ts +16 -5
  423. package/src/stores/apps.ts +12 -0
  424. package/src/stores/bluetoothSettingKeys.ts +2 -0
  425. package/src/stores/gallerySync.ts +4 -0
  426. package/src/stores/glasses.ts +3 -0
  427. package/src/stores/settings.ts +179 -18
  428. package/src/types/applet.ts +2 -0
  429. package/src/types/asg.ts +7 -0
  430. package/src/types/enums.ts +2 -1
  431. package/src/types/hardware.ts +17 -0
  432. package/src/utils/configuredDevHost.ts +17 -0
  433. package/src/utils/devMiniappLaunch.ts +151 -23
  434. package/src/utils/diagnosticContext.ts +17 -17
  435. package/src/utils/hardware/hardware.ts +7 -9
  436. package/src/utils/miniappDiagnostics.ts +226 -0
  437. package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
  438. package/src/utils/timers/timers.ts +57 -21
  439. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  440. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  441. package/build/services/asgOtaVersionUrl.js.map +0 -1
@@ -0,0 +1,312 @@
1
+ import * as RNFS from "@dr.pogodin/react-native-fs"
2
+ import type {OtaCheckCurrentGlassesResult, VersionJson} from "./OtaUpdateCheckService"
3
+
4
+ /**
5
+ * Phone-side artifact staging for hotspot-served OTA (OS-1676).
6
+ *
7
+ * When the glasses have no WiFi, the phone downloads the OTA artifacts itself (over
8
+ * whatever network it is on — the user's tap on "update" is the consent) and serves them
9
+ * to the glasses via the LocalOtaServer over the glasses' hotspot. This module owns:
10
+ *
11
+ * - planning which artifacts the pending update actually needs (from the raw manifest the
12
+ * update check fetched, so the glasses re-parse byte-identical version data),
13
+ * - downloading them with .part staging and sha256 verification, keyed on disk by hash so
14
+ * retries and the post-APK continuation reuse verified files,
15
+ * - rewriting the manifest's URL fields to point at the phone server, and
16
+ * - cleanup once the update completes or the manifest moves on.
17
+ */
18
+
19
+ export type OtaArtifactKind = "apk" | "mtk" | "bes"
20
+
21
+ export interface OtaArtifactPlanEntry {
22
+ kind: OtaArtifactKind
23
+ /** URL this artifact is fetched from, exactly as it appears in the raw manifest. */
24
+ url: string
25
+ /** Required content hash from the manifest. */
26
+ sha256: string
27
+ }
28
+
29
+ export interface PreparedOtaArtifact extends OtaArtifactPlanEntry {
30
+ filePath: string
31
+ }
32
+
33
+ export interface OtaArtifactDownloadProgress {
34
+ kind: OtaArtifactKind
35
+ /** 0-based index of the artifact being downloaded. */
36
+ index: number
37
+ totalCount: number
38
+ /** Percent of the current artifact, 0-100 (0 when the server sent no length). */
39
+ artifactPercent: number
40
+ bytesWritten: number
41
+ contentLength: number
42
+ }
43
+
44
+ export class OtaArtifactError extends Error {
45
+ constructor(
46
+ public readonly code: "artifact_download_failed" | "artifact_verify_failed" | "manifest_invalid",
47
+ message: string,
48
+ ) {
49
+ super(message)
50
+ this.name = "OtaArtifactError"
51
+ }
52
+ }
53
+
54
+ const ASG_PACKAGE = "com.mentra.asg_client"
55
+
56
+ export function otaArtifactsDirectory(): string {
57
+ return `${RNFS.DocumentDirectoryPath}/ota_artifacts`
58
+ }
59
+
60
+ /**
61
+ * Derive the artifact list the pending update needs from a completed check.
62
+ * Works off the raw manifest body (not the normalized check fields) so the URLs and
63
+ * hashes match exactly what the glasses will re-parse.
64
+ */
65
+ export function planArtifacts(result: OtaCheckCurrentGlassesResult): OtaArtifactPlanEntry[] {
66
+ if (!result.manifestBody) {
67
+ throw new OtaArtifactError("manifest_invalid", "Check result carries no manifest body")
68
+ }
69
+ let manifest: VersionJson
70
+ try {
71
+ manifest = JSON.parse(result.manifestBody)
72
+ } catch {
73
+ throw new OtaArtifactError("manifest_invalid", "Manifest body is not valid JSON")
74
+ }
75
+
76
+ const entries: OtaArtifactPlanEntry[] = []
77
+
78
+ if (result.updates.includes("apk")) {
79
+ const app = manifest.apps?.[ASG_PACKAGE] as unknown as Record<string, unknown> | undefined
80
+ const url = typeof app?.apkUrl === "string" ? app.apkUrl : null
81
+ if (!url) {
82
+ throw new OtaArtifactError("manifest_invalid", "Manifest has no apkUrl for the pending APK update")
83
+ }
84
+ entries.push({
85
+ kind: "apk",
86
+ url,
87
+ sha256: requireSha256(app, "APK"),
88
+ })
89
+ }
90
+
91
+ if (result.updates.includes("mtk") && result.mtkPatch) {
92
+ const raw = (manifest.mtk_patches ?? []).find(
93
+ (patch) => firmwareUrl(patch) === firmwareUrl(result.mtkPatch!),
94
+ ) as unknown as Record<string, unknown> | undefined
95
+ const url = firmwareUrl(raw) ?? firmwareUrl(result.mtkPatch)
96
+ if (!url) {
97
+ throw new OtaArtifactError("manifest_invalid", "Manifest has no URL for the pending MTK patch")
98
+ }
99
+ entries.push({
100
+ kind: "mtk",
101
+ url,
102
+ sha256: requireSha256(raw, "MTK"),
103
+ })
104
+ }
105
+
106
+ if (result.updates.includes("bes") && manifest.bes_firmware) {
107
+ const raw = manifest.bes_firmware as unknown as Record<string, unknown>
108
+ const url = firmwareUrl(raw)
109
+ if (!url) {
110
+ throw new OtaArtifactError("manifest_invalid", "Manifest has no URL for the pending BES firmware")
111
+ }
112
+ entries.push({
113
+ kind: "bes",
114
+ url,
115
+ sha256: requireSha256(raw, "BES"),
116
+ })
117
+ }
118
+
119
+ return entries
120
+ }
121
+
122
+ /**
123
+ * Download every planned artifact into the on-disk hash-keyed store, reusing files that
124
+ * already verify. Sequential on purpose: progress is legible and the hotspot window that
125
+ * follows is the slow part, not phone-side parallelism.
126
+ */
127
+ export async function prepareArtifacts(
128
+ plan: OtaArtifactPlanEntry[],
129
+ onProgress?: (progress: OtaArtifactDownloadProgress) => void,
130
+ nativeDownload?: (
131
+ entry: OtaArtifactPlanEntry,
132
+ destination: string,
133
+ onProgress?: (bytesWritten: number, contentLength: number) => void,
134
+ ) => Promise<{statusCode: number}>,
135
+ ): Promise<PreparedOtaArtifact[]> {
136
+ const directory = otaArtifactsDirectory()
137
+ await RNFS.mkdir(directory, {NSURLIsExcludedFromBackupKey: true})
138
+
139
+ const prepared: PreparedOtaArtifact[] = []
140
+ for (let index = 0; index < plan.length; index++) {
141
+ const entry = plan[index]
142
+
143
+ const cachedPath = `${directory}/${entry.sha256}`
144
+ if (await RNFS.exists(cachedPath)) {
145
+ const cachedHash = (await RNFS.hash(cachedPath, "sha256")).toLowerCase()
146
+ if (cachedHash === entry.sha256) {
147
+ prepared.push({...entry, filePath: cachedPath})
148
+ continue
149
+ }
150
+ await safeUnlink(cachedPath)
151
+ }
152
+
153
+ const partPath = `${directory}/download-${index}.part`
154
+ await safeUnlink(partPath)
155
+ try {
156
+ const reportProgress = (bytesWritten: number, contentLength: number) => {
157
+ onProgress?.({
158
+ kind: entry.kind,
159
+ index,
160
+ totalCount: plan.length,
161
+ artifactPercent: contentLength > 0 ? Math.round((bytesWritten / contentLength) * 100) : 0,
162
+ bytesWritten,
163
+ contentLength,
164
+ })
165
+ }
166
+ const downloadResult = nativeDownload
167
+ ? await nativeDownload(entry, partPath, reportProgress)
168
+ : await RNFS.downloadFile({
169
+ fromUrl: entry.url,
170
+ toFile: partPath,
171
+ connectionTimeout: 30_000,
172
+ readTimeout: 30_000,
173
+ progressDivider: 5,
174
+ progress: (res: RNFS.DownloadProgressCallbackResultT) => {
175
+ reportProgress(res.bytesWritten, res.contentLength)
176
+ },
177
+ }).promise
178
+ if (downloadResult.statusCode !== 200) {
179
+ throw new OtaArtifactError(
180
+ "artifact_download_failed",
181
+ `Download of ${entry.kind} artifact failed with HTTP ${downloadResult.statusCode}`,
182
+ )
183
+ }
184
+
185
+ const actualSha256 = (await RNFS.hash(partPath, "sha256")).toLowerCase()
186
+ if (actualSha256 !== entry.sha256) {
187
+ throw new OtaArtifactError(
188
+ "artifact_verify_failed",
189
+ `${entry.kind} artifact hash mismatch: expected ${entry.sha256}, got ${actualSha256}`,
190
+ )
191
+ }
192
+
193
+ const finalPath = `${directory}/${entry.sha256}`
194
+ await safeUnlink(finalPath)
195
+ await RNFS.moveFile(partPath, finalPath)
196
+ prepared.push({...entry, filePath: finalPath})
197
+ } catch (error) {
198
+ await safeUnlink(partPath)
199
+ if (error instanceof OtaArtifactError) {
200
+ throw error
201
+ }
202
+ throw new OtaArtifactError(
203
+ "artifact_download_failed",
204
+ `Download of ${entry.kind} artifact failed: ${error instanceof Error ? error.message : String(error)}`,
205
+ )
206
+ }
207
+ }
208
+ return prepared
209
+ }
210
+
211
+ /**
212
+ * Point the manifest's artifact URLs at the phone server, leaving every other field
213
+ * semantically identical to what the update check saw. Entries we host get
214
+ * `<baseUrl>/artifacts/<sha256>`; entries the update does not need keep their CDN URLs.
215
+ * Only URL fields change: target versions, sizes, and manifest hashes remain untouched.
216
+ */
217
+ export function rewriteManifestForLocalServer(
218
+ manifestBody: string,
219
+ artifacts: PreparedOtaArtifact[],
220
+ baseUrl: string,
221
+ ): string {
222
+ let manifest: VersionJson
223
+ try {
224
+ manifest = JSON.parse(manifestBody)
225
+ } catch {
226
+ throw new OtaArtifactError("manifest_invalid", "Manifest body is not valid JSON")
227
+ }
228
+ const byUrl = new Map(artifacts.map((artifact) => [artifact.url, artifact]))
229
+ const localUrl = (artifact: PreparedOtaArtifact) => `${baseUrl}/artifacts/${artifact.sha256}`
230
+
231
+ for (const app of Object.values(manifest.apps ?? {})) {
232
+ const record = app as unknown as Record<string, unknown>
233
+ const artifact = typeof record.apkUrl === "string" ? byUrl.get(record.apkUrl) : undefined
234
+ if (artifact) {
235
+ record.apkUrl = localUrl(artifact)
236
+ }
237
+ }
238
+
239
+ for (const patch of manifest.mtk_patches ?? []) {
240
+ rewriteFirmwareEntry(patch as unknown as Record<string, unknown>, byUrl, localUrl)
241
+ }
242
+ if (manifest.bes_firmware) {
243
+ rewriteFirmwareEntry(manifest.bes_firmware as unknown as Record<string, unknown>, byUrl, localUrl)
244
+ }
245
+
246
+ return JSON.stringify(manifest)
247
+ }
248
+
249
+ /** Delete every stored artifact whose hash is not in `keepSha256s` (plus stray .part files). */
250
+ export async function cleanupArtifacts(keepSha256s: string[] = []): Promise<void> {
251
+ const directory = otaArtifactsDirectory()
252
+ if (!(await RNFS.exists(directory))) {
253
+ return
254
+ }
255
+ const keep = new Set(keepSha256s.map((sha) => sha.toLowerCase()))
256
+ const items = await RNFS.readDir(directory)
257
+ for (const item of items) {
258
+ if (!item.isFile()) continue
259
+ if (keep.has(item.name.toLowerCase())) continue
260
+ await safeUnlink(item.path)
261
+ }
262
+ }
263
+
264
+ function rewriteFirmwareEntry(
265
+ entry: Record<string, unknown>,
266
+ byUrl: Map<string, PreparedOtaArtifact>,
267
+ localUrl: (artifact: PreparedOtaArtifact) => string,
268
+ ): void {
269
+ const url = firmwareUrl(entry)
270
+ const artifact = url ? byUrl.get(url) : undefined
271
+ if (!artifact) {
272
+ return
273
+ }
274
+ entry.url = localUrl(artifact)
275
+ // Overwrite the legacy key too when present, so no glasses build can prefer a stale
276
+ // CDN URL over the local one.
277
+ if (typeof entry.firmwareUrl === "string") {
278
+ entry.firmwareUrl = localUrl(artifact)
279
+ }
280
+ }
281
+
282
+ function firmwareUrl(entry: unknown): string | null {
283
+ if (!entry || typeof entry !== "object") {
284
+ return null
285
+ }
286
+ const record = entry as Record<string, unknown>
287
+ if (typeof record.url === "string" && record.url.length > 0) {
288
+ return record.url
289
+ }
290
+ if (typeof record.firmwareUrl === "string" && record.firmwareUrl.length > 0) {
291
+ return record.firmwareUrl
292
+ }
293
+ return null
294
+ }
295
+
296
+ function requireSha256(entry: Record<string, unknown> | undefined, label: string): string {
297
+ const sha256 = typeof entry?.sha256 === "string" ? entry.sha256.trim().toLowerCase() : ""
298
+ if (!/^[a-f0-9]{64}$/.test(sha256)) {
299
+ throw new OtaArtifactError("manifest_invalid", `${label} artifact has no valid manifest sha256`)
300
+ }
301
+ return sha256
302
+ }
303
+
304
+ async function safeUnlink(path: string): Promise<void> {
305
+ try {
306
+ if (await RNFS.exists(path)) {
307
+ await RNFS.unlink(path)
308
+ }
309
+ } catch {
310
+ // Best-effort: a leftover file only wastes space and is cleaned up next run.
311
+ }
312
+ }
@@ -0,0 +1,106 @@
1
+ import type {OtaCheckCurrentGlassesResult} from "./OtaUpdateCheckService"
2
+
3
+ export const MAX_OTA_AUTO_CHAIN_PASSES = 8
4
+ export const OTA_AUTO_CHAIN_RECONNECT_TIMEOUT_MS = 120_000
5
+
6
+ type OtaAutoChainSession = {
7
+ approvedDowngrade: boolean
8
+ passCount: number
9
+ reconnectDeadline: number | null
10
+ seenFingerprints: Set<string>
11
+ }
12
+
13
+ export type OtaAutoChainAdvanceResult =
14
+ | {advance: true; passCount: number}
15
+ | {advance: false; reason: "inactive" | "duplicate" | "max_passes" | "downgrade_not_approved"}
16
+
17
+ let session: OtaAutoChainSession | null = null
18
+
19
+ /**
20
+ * Identify the exact update offer that produced one OTA pass. Including the
21
+ * observed versions and manifest body lets a changed manifest advance while a
22
+ * stale post-install version_info response is rejected as a duplicate.
23
+ */
24
+ export function otaAutoChainFingerprint(result: OtaCheckCurrentGlassesResult): string {
25
+ return JSON.stringify({
26
+ manifestUrl: result.manifestUrl ?? "",
27
+ manifestBody: result.manifestBody ?? "",
28
+ buildNumber: result.buildNumber ?? "",
29
+ mtkFirmwareVersion: result.mtkFirmwareVersion ?? "",
30
+ besFirmwareVersion: result.besFirmwareVersion ?? "",
31
+ updates: result.updates,
32
+ targetBuildNumber: result.updateInfo?.versionCode ?? result.latestVersionInfo?.versionCode ?? 0,
33
+ targetBesVersion: result.besVersion ?? "",
34
+ mtkPatch: result.mtkPatch
35
+ ? {
36
+ startFirmware: result.mtkPatch.start_firmware,
37
+ endFirmware: result.mtkPatch.end_firmware,
38
+ url: result.mtkPatch.url,
39
+ }
40
+ : null,
41
+ })
42
+ }
43
+
44
+ /** Start a chain after the user explicitly approves its first update pass. */
45
+ export function beginOtaAutoChain(initialFingerprint: string, approvedDowngrade: boolean): void {
46
+ session = {
47
+ approvedDowngrade,
48
+ passCount: 1,
49
+ reconnectDeadline: null,
50
+ seenFingerprints: new Set([initialFingerprint]),
51
+ }
52
+ }
53
+
54
+ export function isOtaAutoChainActive(): boolean {
55
+ return session !== null
56
+ }
57
+
58
+ /** End the current chain. Safe to call when no chain is active. */
59
+ export function stopOtaAutoChain(): void {
60
+ session = null
61
+ }
62
+
63
+ /**
64
+ * Start (or continue) the bounded wait for glasses that are rebooting between
65
+ * passes. Re-renders must not extend the original deadline indefinitely.
66
+ */
67
+ export function otaAutoChainReconnectWaitRemaining(now = performance.now()): number | null {
68
+ if (!session) return null
69
+
70
+ session.reconnectDeadline ??= now + OTA_AUTO_CHAIN_RECONNECT_TIMEOUT_MS
71
+ return Math.max(0, session.reconnectDeadline - now)
72
+ }
73
+
74
+ /** A successful reconnect allows a future pass to establish a fresh wait. */
75
+ export function clearOtaAutoChainReconnectWait(): void {
76
+ if (session) session.reconnectDeadline = null
77
+ }
78
+
79
+ /**
80
+ * Admit the next pass of an active chain. Repeated offers, unexpectedly
81
+ * destructive downgrades, and runaway chains fail closed and end automation.
82
+ */
83
+ export function tryAdvanceOtaAutoChain(fingerprint: string, isDowngrade: boolean): OtaAutoChainAdvanceResult {
84
+ if (!session) {
85
+ return {advance: false, reason: "inactive"}
86
+ }
87
+
88
+ if (isDowngrade && !session.approvedDowngrade) {
89
+ stopOtaAutoChain()
90
+ return {advance: false, reason: "downgrade_not_approved"}
91
+ }
92
+
93
+ if (session.seenFingerprints.has(fingerprint)) {
94
+ stopOtaAutoChain()
95
+ return {advance: false, reason: "duplicate"}
96
+ }
97
+
98
+ if (session.passCount >= MAX_OTA_AUTO_CHAIN_PASSES) {
99
+ stopOtaAutoChain()
100
+ return {advance: false, reason: "max_passes"}
101
+ }
102
+
103
+ session.seenFingerprints.add(fingerprint)
104
+ session.passCount += 1
105
+ return {advance: true, passCount: session.passCount}
106
+ }
@@ -0,0 +1,80 @@
1
+ import type {OtaProgress, OtaStatus} from "../facades/ota"
2
+
3
+ export const BES_INSTALL_RESTART_MESSAGE =
4
+ "Restart your glasses to safely exit firmware update mode before trying again"
5
+
6
+ function isDownloadPhaseSnapshot(
7
+ otaStatus: OtaStatus | null | undefined,
8
+ otaProgress: OtaProgress | null | undefined,
9
+ ): boolean {
10
+ if (otaStatus?.phase === "download") {
11
+ return true
12
+ }
13
+ if (otaProgress?.stage === "download") {
14
+ return true
15
+ }
16
+ return false
17
+ }
18
+
19
+ /**
20
+ * Offer Change WiFi whenever the OTA flow failed while the glasses were in the
21
+ * download step (any download failure — network, SSL, size cap, verify, etc.).
22
+ *
23
+ * Also covers phone-side watchdog failures that fire while the store still shows
24
+ * an active download phase (stall / global timeout mid-download).
25
+ */
26
+ export function shouldShowChangeWifiForOtaDownloadFailure(
27
+ otaStatus: OtaStatus | null | undefined,
28
+ otaProgress: OtaProgress | null | undefined,
29
+ localErrorMessage: string,
30
+ ): boolean {
31
+ if (otaStatus?.status === "failed" && otaStatus.phase === "download") {
32
+ return true
33
+ }
34
+ if (otaProgress?.status === "FAILED" && otaProgress.stage === "download") {
35
+ return true
36
+ }
37
+ if (localErrorMessage && isDownloadPhaseSnapshot(otaStatus, otaProgress)) {
38
+ return true
39
+ }
40
+ return false
41
+ }
42
+
43
+ export function getOtaErrorMessage(error?: string): string {
44
+ switch (error) {
45
+ case "no_internet":
46
+ return "Glasses WiFi has no internet connection"
47
+ case "clock_skew":
48
+ return "Glasses clock is wrong — syncing time from your phone, then retrying update check"
49
+ case "ssl_error":
50
+ return "Secure connection failed — try a different WiFi network"
51
+ case "download_failed":
52
+ return "Download failed — check glasses WiFi connection"
53
+ case "firmware_too_large":
54
+ return "Firmware file is unexpectedly large — please contact support"
55
+ case "firmware_verify_failed":
56
+ return "Firmware verification failed — please try again or contact support"
57
+ case "apk_verify_failed":
58
+ return "Update verification failed — please try again or contact support"
59
+ case "install_failed":
60
+ return "Install failed — please try again"
61
+ default:
62
+ return error || "Update failed"
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Once a BES install has started, any failure conservatively requires a glasses restart. This
68
+ * avoids adding a BES-specific error code to the wire protocol and, more importantly, never offers
69
+ * an unsafe retry when a generic failure or silence may mean BES entered its raw OTA parser.
70
+ */
71
+ export function shouldRequireGlassesRebootForBesFailure(
72
+ otaStatus: OtaStatus | null | undefined,
73
+ _otaProgress: OtaProgress | null | undefined,
74
+ localErrorMessage: string,
75
+ ): boolean {
76
+ if (otaStatus?.stepType !== "bes" || otaStatus.phase !== "install") {
77
+ return false
78
+ }
79
+ return otaStatus.status === "failed" || Boolean(localErrorMessage)
80
+ }