@mentra/engine 0.1.0-dev.0 → 3.1.0-dev.4

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 (503) hide show
  1. package/README.md +55 -18
  2. package/build/bluetooth-sdk/debug.d.ts +2 -0
  3. package/build/bluetooth-sdk/debug.d.ts.map +1 -0
  4. package/build/bluetooth-sdk/debug.js +2 -0
  5. package/build/bluetooth-sdk/debug.js.map +1 -0
  6. package/build/bluetooth-sdk/index.d.ts +3 -0
  7. package/build/bluetooth-sdk/index.d.ts.map +1 -0
  8. package/build/bluetooth-sdk/index.js +3 -0
  9. package/build/bluetooth-sdk/index.js.map +1 -0
  10. package/build/bluetooth-sdk/photo-receiver.d.ts +3 -0
  11. package/build/bluetooth-sdk/photo-receiver.d.ts.map +1 -0
  12. package/build/bluetooth-sdk/photo-receiver.js +3 -0
  13. package/build/bluetooth-sdk/photo-receiver.js.map +1 -0
  14. package/build/bluetooth-sdk/react.d.ts +2 -0
  15. package/build/bluetooth-sdk/react.d.ts.map +1 -0
  16. package/build/bluetooth-sdk/react.js +2 -0
  17. package/build/bluetooth-sdk/react.js.map +1 -0
  18. package/build/bluetooth-sdk/types.d.ts +2 -0
  19. package/build/bluetooth-sdk/types.d.ts.map +1 -0
  20. package/build/bluetooth-sdk/types.js +2 -0
  21. package/build/bluetooth-sdk/types.js.map +1 -0
  22. package/build/engine.d.ts +24 -16
  23. package/build/engine.d.ts.map +1 -1
  24. package/build/engine.js +9 -4
  25. package/build/engine.js.map +1 -1
  26. package/build/facades/dev.d.ts +3 -2
  27. package/build/facades/dev.d.ts.map +1 -1
  28. package/build/facades/dev.js +18 -12
  29. package/build/facades/dev.js.map +1 -1
  30. package/build/facades/display.d.ts +1 -1
  31. package/build/facades/display.d.ts.map +1 -1
  32. package/build/facades/display.js +1 -1
  33. package/build/facades/display.js.map +1 -1
  34. package/build/facades/gallery.js +1 -1
  35. package/build/facades/gallery.js.map +1 -1
  36. package/build/facades/glasses.d.ts +4 -13
  37. package/build/facades/glasses.d.ts.map +1 -1
  38. package/build/facades/glasses.js +21 -6
  39. package/build/facades/glasses.js.map +1 -1
  40. package/build/facades/glassesSettings.d.ts.map +1 -1
  41. package/build/facades/glassesSettings.js +1 -0
  42. package/build/facades/glassesSettings.js.map +1 -1
  43. package/build/facades/miniapps.d.ts +4 -0
  44. package/build/facades/miniapps.d.ts.map +1 -1
  45. package/build/facades/miniapps.js +5 -0
  46. package/build/facades/miniapps.js.map +1 -1
  47. package/build/facades/ota.d.ts +14 -16
  48. package/build/facades/ota.d.ts.map +1 -1
  49. package/build/facades/ota.js +22 -7
  50. package/build/facades/ota.js.map +1 -1
  51. package/build/facades/pairing.d.ts +8 -5
  52. package/build/facades/pairing.d.ts.map +1 -1
  53. package/build/facades/pairing.js +12 -10
  54. package/build/facades/pairing.js.map +1 -1
  55. package/build/facades/permissions.d.ts +10 -0
  56. package/build/facades/permissions.d.ts.map +1 -1
  57. package/build/facades/permissions.js +10 -0
  58. package/build/facades/permissions.js.map +1 -1
  59. package/build/facades/phoneNotifications.d.ts +0 -4
  60. package/build/facades/phoneNotifications.d.ts.map +1 -1
  61. package/build/facades/phoneNotifications.js +4 -14
  62. package/build/facades/phoneNotifications.js.map +1 -1
  63. package/build/facades/speech.d.ts +7 -6
  64. package/build/facades/speech.d.ts.map +1 -1
  65. package/build/facades/speech.js +1 -1
  66. package/build/facades/speech.js.map +1 -1
  67. package/build/generated/releaseMetadata.d.ts +12 -0
  68. package/build/generated/releaseMetadata.d.ts.map +1 -0
  69. package/build/generated/releaseMetadata.js +10 -0
  70. package/build/generated/releaseMetadata.js.map +1 -0
  71. package/build/index.d.ts +10 -8
  72. package/build/index.d.ts.map +1 -1
  73. package/build/index.js +6 -5
  74. package/build/index.js.map +1 -1
  75. package/build/react/MentraLiveOtaFlow.d.ts +38 -0
  76. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  77. package/build/react/MentraLiveOtaFlow.js +528 -0
  78. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  79. package/build/react/index.d.ts +2 -0
  80. package/build/react/index.d.ts.map +1 -0
  81. package/build/react/index.js +2 -0
  82. package/build/react/index.js.map +1 -0
  83. package/build/react/useEngineSnapshot.d.ts +2 -0
  84. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  85. package/build/react/useEngineSnapshot.js +14 -0
  86. package/build/react/useEngineSnapshot.js.map +1 -0
  87. package/build/runtime/bootstrap.d.ts +24 -1
  88. package/build/runtime/bootstrap.d.ts.map +1 -1
  89. package/build/runtime/bootstrap.js +17 -0
  90. package/build/runtime/bootstrap.js.map +1 -1
  91. package/build/runtime/scanQrSeam.d.ts +7 -0
  92. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  93. package/build/runtime/scanQrSeam.js +16 -0
  94. package/build/runtime/scanQrSeam.js.map +1 -0
  95. package/build/services/AppRegistry.d.ts +41 -57
  96. package/build/services/AppRegistry.d.ts.map +1 -1
  97. package/build/services/AppRegistry.js +208 -144
  98. package/build/services/AppRegistry.js.map +1 -1
  99. package/build/services/AudioCloudUplink.d.ts +12 -0
  100. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  101. package/build/services/AudioCloudUplink.js +22 -1
  102. package/build/services/AudioCloudUplink.js.map +1 -1
  103. package/build/services/AudioPlaybackService.d.ts +41 -2
  104. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  105. package/build/services/AudioPlaybackService.js +250 -33
  106. package/build/services/AudioPlaybackService.js.map +1 -1
  107. package/build/services/BlobStore.d.ts +2 -1
  108. package/build/services/BlobStore.d.ts.map +1 -1
  109. package/build/services/BlobStore.js +17 -9
  110. package/build/services/BlobStore.js.map +1 -1
  111. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  112. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  113. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  114. package/build/services/CloudClientService.d.ts +15 -0
  115. package/build/services/CloudClientService.d.ts.map +1 -1
  116. package/build/services/CloudClientService.js +93 -1
  117. package/build/services/CloudClientService.js.map +1 -1
  118. package/build/services/DeviceEventRouter.js +5 -5
  119. package/build/services/DeviceEventRouter.js.map +1 -1
  120. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  121. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  122. package/build/services/ForegroundLocationPermission.js +12 -0
  123. package/build/services/ForegroundLocationPermission.js.map +1 -0
  124. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  125. package/build/services/GlassesSettingsSync.js +9 -3
  126. package/build/services/GlassesSettingsSync.js.map +1 -1
  127. package/build/services/GlassesStatusProjection.d.ts +2 -1
  128. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  129. package/build/services/GlassesStatusProjection.js +15 -8
  130. package/build/services/GlassesStatusProjection.js.map +1 -1
  131. package/build/services/HotspotOtaTransport.d.ts +29 -0
  132. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  133. package/build/services/HotspotOtaTransport.js +146 -0
  134. package/build/services/HotspotOtaTransport.js.map +1 -0
  135. package/build/services/HotspotShutdown.d.ts +17 -0
  136. package/build/services/HotspotShutdown.d.ts.map +1 -0
  137. package/build/services/HotspotShutdown.js +29 -0
  138. package/build/services/HotspotShutdown.js.map +1 -0
  139. package/build/services/LocalDisplayManager.d.ts +15 -0
  140. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  141. package/build/services/LocalDisplayManager.js +106 -20
  142. package/build/services/LocalDisplayManager.js.map +1 -1
  143. package/build/services/LocalMiniappRuntime.d.ts +74 -2
  144. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  145. package/build/services/LocalMiniappRuntime.js +785 -291
  146. package/build/services/LocalMiniappRuntime.js.map +1 -1
  147. package/build/services/LocalMiniappStorage.d.ts +32 -0
  148. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  149. package/build/services/LocalMiniappStorage.js +66 -0
  150. package/build/services/LocalMiniappStorage.js.map +1 -0
  151. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  152. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  153. package/build/services/LocalMiniappUserIdentity.js +43 -0
  154. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  155. package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
  156. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  157. package/build/services/LocalSttFallbackCoordinator.js +18 -12
  158. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  159. package/build/services/MicStateCoordinator.d.ts +42 -1
  160. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  161. package/build/services/MicStateCoordinator.js +141 -3
  162. package/build/services/MicStateCoordinator.js.map +1 -1
  163. package/build/services/MiniappLauncher.d.ts.map +1 -1
  164. package/build/services/MiniappLauncher.js +23 -3
  165. package/build/services/MiniappLauncher.js.map +1 -1
  166. package/build/services/MiniappLiveness.d.ts +12 -0
  167. package/build/services/MiniappLiveness.d.ts.map +1 -0
  168. package/build/services/MiniappLiveness.js +16 -0
  169. package/build/services/MiniappLiveness.js.map +1 -0
  170. package/build/services/NativeHttpResponse.d.ts +3 -0
  171. package/build/services/NativeHttpResponse.d.ts.map +1 -0
  172. package/build/services/NativeHttpResponse.js +6 -0
  173. package/build/services/NativeHttpResponse.js.map +1 -0
  174. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  175. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  176. package/build/services/OtaArtifactDownloader.js +226 -0
  177. package/build/services/OtaArtifactDownloader.js.map +1 -0
  178. package/build/services/OtaAutoChain.d.ts +34 -0
  179. package/build/services/OtaAutoChain.d.ts.map +1 -0
  180. package/build/services/OtaAutoChain.js +83 -0
  181. package/build/services/OtaAutoChain.js.map +1 -0
  182. package/build/services/OtaErrorMapping.d.ts +18 -0
  183. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  184. package/build/services/OtaErrorMapping.js +63 -0
  185. package/build/services/OtaErrorMapping.js.map +1 -0
  186. package/build/services/OtaInstallCoordinator.d.ts +95 -15
  187. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  188. package/build/services/OtaInstallCoordinator.js +577 -130
  189. package/build/services/OtaInstallCoordinator.js.map +1 -1
  190. package/build/services/OtaService.d.ts.map +1 -1
  191. package/build/services/OtaService.js +8 -1
  192. package/build/services/OtaService.js.map +1 -1
  193. package/build/services/OtaUpdateCheckService.d.ts +39 -4
  194. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  195. package/build/services/OtaUpdateCheckService.js +138 -22
  196. package/build/services/OtaUpdateCheckService.js.map +1 -1
  197. package/build/services/PhoneCalendarHelpers.d.ts +32 -0
  198. package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
  199. package/build/services/PhoneCalendarHelpers.js +157 -0
  200. package/build/services/PhoneCalendarHelpers.js.map +1 -0
  201. package/build/services/PhoneCalendarService.d.ts +5 -0
  202. package/build/services/PhoneCalendarService.d.ts.map +1 -0
  203. package/build/services/PhoneCalendarService.js +45 -0
  204. package/build/services/PhoneCalendarService.js.map +1 -0
  205. package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
  206. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
  207. package/build/services/PhoneCameraFovCoordinator.js +194 -0
  208. package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
  209. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  210. package/build/services/PhoneNotificationsSync.js +12 -10
  211. package/build/services/PhoneNotificationsSync.js.map +1 -1
  212. package/build/services/PhonePhotoCoordinator.d.ts +26 -2
  213. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  214. package/build/services/PhonePhotoCoordinator.js +79 -9
  215. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  216. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  217. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  218. package/build/services/PhoneStreamCoordinator.js +125 -13
  219. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  220. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  221. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  222. package/build/services/PhoneVideoCoordinator.js +10 -0
  223. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  224. package/build/services/SceneRenderer.d.ts.map +1 -1
  225. package/build/services/SceneRenderer.js +15 -0
  226. package/build/services/SceneRenderer.js.map +1 -1
  227. package/build/services/SentenceTtsPipeline.d.ts +31 -0
  228. package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
  229. package/build/services/SentenceTtsPipeline.js +67 -0
  230. package/build/services/SentenceTtsPipeline.js.map +1 -0
  231. package/build/services/SupportProfileSync.d.ts +22 -0
  232. package/build/services/SupportProfileSync.d.ts.map +1 -0
  233. package/build/services/SupportProfileSync.js +213 -0
  234. package/build/services/SupportProfileSync.js.map +1 -0
  235. package/build/services/TranscriptionRouting.d.ts +12 -0
  236. package/build/services/TranscriptionRouting.d.ts.map +1 -0
  237. package/build/services/TranscriptionRouting.js +24 -0
  238. package/build/services/TranscriptionRouting.js.map +1 -0
  239. package/build/services/TtsTextSanitizer.d.ts +5 -0
  240. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  241. package/build/services/TtsTextSanitizer.js +61 -0
  242. package/build/services/TtsTextSanitizer.js.map +1 -0
  243. package/build/services/WifiAdbRequest.d.ts +17 -0
  244. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  245. package/build/services/WifiAdbRequest.js +35 -0
  246. package/build/services/WifiAdbRequest.js.map +1 -0
  247. package/build/services/asg/asgCameraApi.d.ts +43 -0
  248. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  249. package/build/services/asg/asgCameraApi.js +509 -26
  250. package/build/services/asg/asgCameraApi.js.map +1 -1
  251. package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
  252. package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
  253. package/build/services/asg/cameraRollExportCoordinator.js +618 -0
  254. package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
  255. package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
  256. package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
  257. package/build/services/asg/cameraRollExportLedger.js +78 -0
  258. package/build/services/asg/cameraRollExportLedger.js.map +1 -0
  259. package/build/services/asg/galleryNotices.d.ts +1 -1
  260. package/build/services/asg/galleryNotices.d.ts.map +1 -1
  261. package/build/services/asg/galleryNotices.js.map +1 -1
  262. package/build/services/asg/galleryPathMigration.d.ts +3 -0
  263. package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
  264. package/build/services/asg/galleryPathMigration.js +26 -0
  265. package/build/services/asg/galleryPathMigration.js.map +1 -0
  266. package/build/services/asg/gallerySettingsService.d.ts +1 -0
  267. package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
  268. package/build/services/asg/gallerySettingsService.js +2 -0
  269. package/build/services/asg/gallerySettingsService.js.map +1 -1
  270. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  271. package/build/services/asg/gallerySyncService.js +162 -56
  272. package/build/services/asg/gallerySyncService.js.map +1 -1
  273. package/build/services/asg/galleryTransferLedger.d.ts +58 -0
  274. package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
  275. package/build/services/asg/galleryTransferLedger.js +225 -0
  276. package/build/services/asg/galleryTransferLedger.js.map +1 -0
  277. package/build/services/asg/localNetworkTransport.d.ts +15 -0
  278. package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
  279. package/build/services/asg/localNetworkTransport.js +144 -0
  280. package/build/services/asg/localNetworkTransport.js.map +1 -0
  281. package/build/services/asg/localStorageService.d.ts +18 -0
  282. package/build/services/asg/localStorageService.d.ts.map +1 -1
  283. package/build/services/asg/localStorageService.js +168 -19
  284. package/build/services/asg/localStorageService.js.map +1 -1
  285. package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
  286. package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
  287. package/build/services/asg/mediaProcessingQueue.js +193 -62
  288. package/build/services/asg/mediaProcessingQueue.js.map +1 -1
  289. package/build/services/audioPlaybackAssets.d.ts +8 -0
  290. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  291. package/build/services/audioPlaybackAssets.js +7 -0
  292. package/build/services/audioPlaybackAssets.js.map +1 -0
  293. package/build/services/gallerySyncClock.js +1 -1
  294. package/build/services/gallerySyncClock.js.map +1 -1
  295. package/build/services/glassesClockSync.d.ts.map +1 -1
  296. package/build/services/glassesClockSync.js +6 -2
  297. package/build/services/glassesClockSync.js.map +1 -1
  298. package/build/services/manifestActions.d.ts +7 -0
  299. package/build/services/manifestActions.d.ts.map +1 -0
  300. package/build/services/manifestActions.js +25 -0
  301. package/build/services/manifestActions.js.map +1 -0
  302. package/build/services/otaDisplayState.d.ts +23 -12
  303. package/build/services/otaDisplayState.d.ts.map +1 -1
  304. package/build/services/otaDisplayState.js +36 -14
  305. package/build/services/otaDisplayState.js.map +1 -1
  306. package/build/services/otaInstallPolicy.d.ts +16 -4
  307. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  308. package/build/services/otaInstallPolicy.js +24 -3
  309. package/build/services/otaInstallPolicy.js.map +1 -1
  310. package/build/services/otaLegacyMapping.d.ts +1 -1
  311. package/build/services/otaLegacyMapping.d.ts.map +1 -1
  312. package/build/services/otaLegacyMapping.js.map +1 -1
  313. package/build/services/otaManifestPolicy.d.ts +14 -0
  314. package/build/services/otaManifestPolicy.d.ts.map +1 -0
  315. package/build/services/otaManifestPolicy.js +19 -0
  316. package/build/services/otaManifestPolicy.js.map +1 -0
  317. package/build/services/otaManifestUrl.d.ts +3 -0
  318. package/build/services/otaManifestUrl.d.ts.map +1 -0
  319. package/build/services/otaManifestUrl.js +38 -0
  320. package/build/services/otaManifestUrl.js.map +1 -0
  321. package/build/services/slimStreamStatus.d.ts +11 -0
  322. package/build/services/slimStreamStatus.d.ts.map +1 -1
  323. package/build/services/slimStreamStatus.js +14 -4
  324. package/build/services/slimStreamStatus.js.map +1 -1
  325. package/build/stores/apps.d.ts.map +1 -1
  326. package/build/stores/apps.js +11 -0
  327. package/build/stores/apps.js.map +1 -1
  328. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  329. package/build/stores/bluetoothSettingKeys.js +2 -0
  330. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  331. package/build/stores/gallerySync.d.ts +2 -0
  332. package/build/stores/gallerySync.d.ts.map +1 -1
  333. package/build/stores/gallerySync.js +2 -0
  334. package/build/stores/gallerySync.js.map +1 -1
  335. package/build/stores/glasses.d.ts.map +1 -1
  336. package/build/stores/glasses.js +3 -0
  337. package/build/stores/glasses.js.map +1 -1
  338. package/build/stores/settings.d.ts +17 -0
  339. package/build/stores/settings.d.ts.map +1 -1
  340. package/build/stores/settings.js +157 -17
  341. package/build/stores/settings.js.map +1 -1
  342. package/build/types/applet.d.ts +2 -0
  343. package/build/types/applet.d.ts.map +1 -1
  344. package/build/types/applet.js.map +1 -1
  345. package/build/types/asg.d.ts +7 -0
  346. package/build/types/asg.d.ts.map +1 -1
  347. package/build/types/asg.js.map +1 -1
  348. package/build/types/enums.d.ts +2 -25
  349. package/build/types/enums.d.ts.map +1 -1
  350. package/build/types/enums.js +2 -27
  351. package/build/types/enums.js.map +1 -1
  352. package/build/types/hardware.d.ts +4 -13
  353. package/build/types/hardware.d.ts.map +1 -1
  354. package/build/types/hardware.js +15 -3
  355. package/build/types/hardware.js.map +1 -1
  356. package/build/types/index.d.ts +2 -6
  357. package/build/types/index.d.ts.map +1 -1
  358. package/build/types/index.js +2 -6
  359. package/build/types/index.js.map +1 -1
  360. package/build/utils/configuredDevHost.d.ts +6 -0
  361. package/build/utils/configuredDevHost.d.ts.map +1 -0
  362. package/build/utils/configuredDevHost.js +19 -0
  363. package/build/utils/configuredDevHost.js.map +1 -0
  364. package/build/utils/devMiniappLaunch.d.ts +19 -8
  365. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  366. package/build/utils/devMiniappLaunch.js +144 -21
  367. package/build/utils/devMiniappLaunch.js.map +1 -1
  368. package/build/utils/diagnosticContext.d.ts.map +1 -1
  369. package/build/utils/diagnosticContext.js +15 -17
  370. package/build/utils/diagnosticContext.js.map +1 -1
  371. package/build/utils/hardware/hardware.d.ts.map +1 -1
  372. package/build/utils/hardware/hardware.js +7 -3
  373. package/build/utils/hardware/hardware.js.map +1 -1
  374. package/build/utils/miniappDiagnostics.d.ts +64 -0
  375. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  376. package/build/utils/miniappDiagnostics.js +173 -0
  377. package/build/utils/miniappDiagnostics.js.map +1 -0
  378. package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
  379. package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
  380. package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
  381. package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
  382. package/build/utils/timers/timers.d.ts.map +1 -1
  383. package/build/utils/timers/timers.js +55 -18
  384. package/build/utils/timers/timers.js.map +1 -1
  385. package/package.json +59 -31
  386. package/src/assets/silence.wav +0 -0
  387. package/src/bluetooth-sdk/debug.ts +1 -0
  388. package/src/bluetooth-sdk/index.ts +2 -0
  389. package/src/bluetooth-sdk/photo-receiver.ts +2 -0
  390. package/src/bluetooth-sdk/react.ts +1 -0
  391. package/src/bluetooth-sdk/types.ts +1 -0
  392. package/src/engine.ts +9 -4
  393. package/src/facades/dev.ts +17 -12
  394. package/src/facades/display.ts +1 -1
  395. package/src/facades/gallery.ts +1 -1
  396. package/src/facades/glasses.ts +20 -7
  397. package/src/facades/glassesSettings.ts +5 -0
  398. package/src/facades/miniapps.ts +7 -0
  399. package/src/facades/ota.ts +23 -8
  400. package/src/facades/pairing.ts +15 -11
  401. package/src/facades/permissions.ts +14 -0
  402. package/src/facades/phoneNotifications.ts +4 -13
  403. package/src/facades/speech.ts +21 -7
  404. package/src/generated/releaseMetadata.ts +20 -0
  405. package/src/index.ts +39 -13
  406. package/src/react/MentraLiveOtaFlow.tsx +856 -0
  407. package/src/react/index.ts +7 -0
  408. package/src/react/useEngineSnapshot.ts +16 -0
  409. package/src/runtime/bootstrap.ts +33 -1
  410. package/src/runtime/scanQrSeam.ts +20 -0
  411. package/src/services/AppRegistry.ts +240 -149
  412. package/src/services/AudioCloudUplink.ts +23 -1
  413. package/src/services/AudioPlaybackService.ts +287 -38
  414. package/src/services/BlobStore.ts +22 -9
  415. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  416. package/src/services/CloudClientService.ts +96 -1
  417. package/src/services/DeviceEventRouter.ts +5 -5
  418. package/src/services/ForegroundLocationPermission.ts +24 -0
  419. package/src/services/GlassesSettingsSync.ts +9 -3
  420. package/src/services/GlassesStatusProjection.ts +16 -8
  421. package/src/services/HotspotOtaTransport.ts +184 -0
  422. package/src/services/HotspotShutdown.ts +41 -0
  423. package/src/services/LocalDisplayManager.ts +112 -21
  424. package/src/services/LocalMiniappRuntime.ts +967 -346
  425. package/src/services/LocalMiniappStorage.ts +82 -0
  426. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  427. package/src/services/LocalSttFallbackCoordinator.ts +19 -12
  428. package/src/services/MicStateCoordinator.ts +169 -4
  429. package/src/services/MiniappLauncher.ts +30 -3
  430. package/src/services/MiniappLiveness.ts +24 -0
  431. package/src/services/NativeHttpResponse.ts +6 -0
  432. package/src/services/OtaArtifactDownloader.ts +312 -0
  433. package/src/services/OtaAutoChain.ts +106 -0
  434. package/src/services/OtaErrorMapping.ts +80 -0
  435. package/src/services/OtaInstallCoordinator.ts +649 -144
  436. package/src/services/OtaService.ts +11 -5
  437. package/src/services/OtaUpdateCheckService.ts +181 -21
  438. package/src/services/PhoneCalendarHelpers.ts +212 -0
  439. package/src/services/PhoneCalendarService.ts +65 -0
  440. package/src/services/PhoneCameraFovCoordinator.ts +210 -0
  441. package/src/services/PhoneNotificationsSync.ts +12 -10
  442. package/src/services/PhonePhotoCoordinator.ts +116 -18
  443. package/src/services/PhoneStreamCoordinator.ts +139 -25
  444. package/src/services/PhoneVideoCoordinator.ts +11 -0
  445. package/src/services/SceneRenderer.ts +16 -0
  446. package/src/services/SentenceTtsPipeline.ts +106 -0
  447. package/src/services/SupportProfileSync.ts +218 -0
  448. package/src/services/TranscriptionRouting.ts +37 -0
  449. package/src/services/TtsTextSanitizer.ts +66 -0
  450. package/src/services/WifiAdbRequest.ts +53 -0
  451. package/src/services/asg/asgCameraApi.ts +615 -33
  452. package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
  453. package/src/services/asg/cameraRollExportLedger.ts +122 -0
  454. package/src/services/asg/galleryNotices.ts +1 -0
  455. package/src/services/asg/galleryPathMigration.ts +22 -0
  456. package/src/services/asg/gallerySettingsService.ts +3 -0
  457. package/src/services/asg/gallerySyncService.ts +184 -73
  458. package/src/services/asg/galleryTransferLedger.ts +312 -0
  459. package/src/services/asg/localNetworkTransport.ts +169 -0
  460. package/src/services/asg/localStorageService.ts +179 -24
  461. package/src/services/asg/mediaProcessingQueue.ts +209 -62
  462. package/src/services/audioPlaybackAssets.ts +8 -0
  463. package/src/services/gallerySyncClock.ts +1 -1
  464. package/src/services/glassesClockSync.ts +6 -2
  465. package/src/services/manifestActions.ts +30 -0
  466. package/src/services/otaDisplayState.ts +58 -17
  467. package/src/services/otaInstallPolicy.ts +30 -4
  468. package/src/services/otaLegacyMapping.ts +1 -1
  469. package/src/services/otaManifestPolicy.ts +42 -0
  470. package/src/services/otaManifestUrl.ts +44 -0
  471. package/src/services/slimStreamStatus.ts +16 -5
  472. package/src/stores/apps.ts +12 -0
  473. package/src/stores/bluetoothSettingKeys.ts +2 -0
  474. package/src/stores/gallerySync.ts +4 -0
  475. package/src/stores/glasses.ts +3 -0
  476. package/src/stores/settings.ts +179 -18
  477. package/src/types/applet.ts +2 -0
  478. package/src/types/asg.ts +7 -0
  479. package/src/types/enums.ts +3 -28
  480. package/src/types/hardware.ts +20 -13
  481. package/src/types/index.ts +2 -6
  482. package/src/utils/configuredDevHost.ts +17 -0
  483. package/src/utils/devMiniappLaunch.ts +151 -23
  484. package/src/utils/diagnosticContext.ts +17 -17
  485. package/src/utils/hardware/hardware.ts +7 -9
  486. package/src/utils/miniappDiagnostics.ts +226 -0
  487. package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
  488. package/src/utils/timers/timers.ts +57 -21
  489. package/build/devtools.d.ts +0 -11
  490. package/build/devtools.d.ts.map +0 -1
  491. package/build/devtools.js +0 -13
  492. package/build/devtools.js.map +0 -1
  493. package/build/internal.d.ts +0 -66
  494. package/build/internal.d.ts.map +0 -1
  495. package/build/internal.js +0 -89
  496. package/build/internal.js.map +0 -1
  497. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  498. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  499. package/build/services/asgOtaVersionUrl.js +0 -36
  500. package/build/services/asgOtaVersionUrl.js.map +0 -1
  501. package/src/devtools.ts +0 -13
  502. package/src/internal.ts +0 -158
  503. package/src/services/asgOtaVersionUrl.ts +0 -41
@@ -0,0 +1,210 @@
1
+ import BluetoothSdk, {type CameraFovRequest, type CameraFovResult} from "@mentra/bluetooth-sdk/internal"
2
+
3
+ export const CAMERA_FOV_OVERRIDE_TTL_MS = 300_000
4
+ export const CAMERA_FOV_OVERRIDE_REFRESH_MS = 120_000
5
+ // Legacy ASG clients restart the camera HAL for an FOV update but cannot acknowledge
6
+ // when it is usable again. The ASG cooldown is 5s; retain a small settling margin so
7
+ // miniapps cannot submit a photo against the stale camera service.
8
+ const LEGACY_CAMERA_RESTART_SETTLE_MS = 7_000
9
+
10
+ interface OverrideEntry {
11
+ leaseId: string
12
+ fov: number
13
+ roiPosition: "center" | "bottom" | "top"
14
+ order: number
15
+ }
16
+
17
+ let leaseCounter = 0
18
+
19
+ function mintLeaseId(): string {
20
+ leaseCounter = (leaseCounter + 1) & 0xffff
21
+ return `fov-${leaseCounter.toString(16).padStart(4, "0")}`
22
+ }
23
+
24
+ function isLegacyFovCompatibilityError(error: unknown): boolean {
25
+ const message = error instanceof Error ? error.message : String(error)
26
+ return /timed out waiting for glasses response|not available|unknown method/i.test(message)
27
+ }
28
+
29
+ /**
30
+ * Serializes miniapp-owned FOV/ROI overrides. The last live owner wins; releasing it applies the
31
+ * previous owner or asks ASG to restore its persistent base. ASG refreshes are no-restart TTL
32
+ * extensions for crash safety.
33
+ */
34
+ export class PhoneCameraFovCoordinator {
35
+ private readonly overrides = new Map<string, OverrideEntry>()
36
+ private effectiveLeaseId: string | undefined
37
+ private sequence = 0
38
+ private queue: Promise<unknown> = Promise.resolve()
39
+ private refreshTimer: ReturnType<typeof setTimeout> | undefined
40
+ private legacyMode = false
41
+
42
+ constructor(private readonly legacyRestartSettleMs = LEGACY_CAMERA_RESTART_SETTLE_MS) {}
43
+
44
+ /** Report-safe FOV ownership snapshot for incident diagnostics. */
45
+ getDiagnosticSnapshot(): Record<string, unknown> {
46
+ return {
47
+ owners: [...this.overrides.entries()]
48
+ .sort(([, a], [, b]) => b.order - a.order)
49
+ .map(([packageName, entry]) => ({
50
+ packageName,
51
+ effective: entry.leaseId === this.effectiveLeaseId,
52
+ fov: entry.fov,
53
+ roiPosition: entry.roiPosition,
54
+ })),
55
+ legacyMode: this.legacyMode,
56
+ }
57
+ }
58
+
59
+ setOverride(packageName: string, request: CameraFovRequest): Promise<CameraFovResult> {
60
+ return this.enqueue(async () => {
61
+ const previous = this.overrides.get(packageName)
62
+ const leaseId = previous?.leaseId ?? mintLeaseId()
63
+ const order = ++this.sequence
64
+ try {
65
+ if (this.legacyMode) return this.setLegacyOverride(packageName, request, leaseId, order)
66
+ const result = await BluetoothSdk.setCameraFovOverride({
67
+ ...request,
68
+ leaseId,
69
+ ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,
70
+ })
71
+ this.overrides.set(packageName, {
72
+ leaseId,
73
+ fov: result.fov,
74
+ roiPosition: result.roiPosition,
75
+ order,
76
+ })
77
+ this.effectiveLeaseId = leaseId
78
+ this.scheduleRefresh()
79
+ return result
80
+ } catch (error) {
81
+ if (!isLegacyFovCompatibilityError(error)) throw error
82
+ console.warn("[PhoneCameraFovCoordinator] override unavailable; using legacy FOV command", error)
83
+ const result = await this.setLegacyOverride(packageName, request, leaseId, order)
84
+ // Only cache compatibility mode after the fallback itself succeeds. A
85
+ // disconnect or missing native bridge must not permanently downgrade
86
+ // future requests on a healthy/newer glasses connection.
87
+ this.legacyMode = true
88
+ return result
89
+ }
90
+ })
91
+ }
92
+
93
+ releaseForApp(packageName: string): Promise<void> {
94
+ return this.enqueue(async () => {
95
+ const removed = this.overrides.get(packageName)
96
+ if (!removed) return
97
+ if (removed.leaseId !== this.effectiveLeaseId) {
98
+ this.overrides.delete(packageName)
99
+ return
100
+ }
101
+
102
+ const next = [...this.overrides.entries()]
103
+ .filter(([candidatePackage]) => candidatePackage !== packageName)
104
+ .map(([, entry]) => entry)
105
+ .sort((a, b) => b.order - a.order)[0]
106
+ if (this.legacyMode) {
107
+ if (next) {
108
+ await this.applyLegacyFov({fov: next.fov, roiPosition: next.roiPosition})
109
+ this.overrides.delete(packageName)
110
+ this.effectiveLeaseId = next.leaseId
111
+ } else {
112
+ // Legacy commands are one-way and have no lease-release protocol.
113
+ // Ask native to replay its unchanged persistent base setting, then
114
+ // probe the modern override path again for the next ownership cycle.
115
+ await BluetoothSdk.restoreLegacyCameraFov()
116
+ await this.waitForLegacyCameraRestart()
117
+ this.overrides.delete(packageName)
118
+ this.clearRefresh()
119
+ this.effectiveLeaseId = undefined
120
+ this.legacyMode = false
121
+ }
122
+ return
123
+ }
124
+ if (next) {
125
+ await BluetoothSdk.setCameraFovOverride({
126
+ leaseId: next.leaseId,
127
+ fov: next.fov,
128
+ roiPosition: next.roiPosition,
129
+ ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,
130
+ })
131
+ // Commit phone-side ownership only after ASG accepted the replacement. On failure the
132
+ // closing app remains effective here, allowing unregister/reconnect cleanup to retry.
133
+ this.overrides.delete(packageName)
134
+ this.effectiveLeaseId = next.leaseId
135
+ this.scheduleRefresh()
136
+ } else {
137
+ await BluetoothSdk.releaseCameraFovOverride(removed.leaseId)
138
+ this.overrides.delete(packageName)
139
+ this.clearRefresh()
140
+ this.effectiveLeaseId = undefined
141
+ }
142
+ })
143
+ }
144
+
145
+ private scheduleRefresh(): void {
146
+ if (this.legacyMode) return
147
+ this.clearRefresh()
148
+ const leaseId = this.effectiveLeaseId
149
+ if (!leaseId) return
150
+ this.refreshTimer = setTimeout(() => {
151
+ void this.enqueue(async () => {
152
+ if (this.effectiveLeaseId !== leaseId) return
153
+ const entry = [...this.overrides.values()].find((candidate) => candidate.leaseId === leaseId)
154
+ if (!entry) return
155
+ await BluetoothSdk.setCameraFovOverride({
156
+ leaseId,
157
+ fov: entry.fov,
158
+ roiPosition: entry.roiPosition,
159
+ ttlMs: CAMERA_FOV_OVERRIDE_TTL_MS,
160
+ })
161
+ this.scheduleRefresh()
162
+ }).catch((error) => console.warn("[PhoneCameraFovCoordinator] failed to refresh override", error))
163
+ }, CAMERA_FOV_OVERRIDE_REFRESH_MS)
164
+ }
165
+
166
+ private clearRefresh(): void {
167
+ if (this.refreshTimer) clearTimeout(this.refreshTimer)
168
+ this.refreshTimer = undefined
169
+ }
170
+
171
+ private async setLegacyOverride(
172
+ packageName: string,
173
+ request: CameraFovRequest,
174
+ leaseId: string,
175
+ order: number,
176
+ ): Promise<CameraFovResult> {
177
+ const result = await this.applyLegacyFov(request)
178
+ this.overrides.set(packageName, {
179
+ leaseId,
180
+ fov: result.fov,
181
+ roiPosition: result.roiPosition,
182
+ order,
183
+ })
184
+ this.effectiveLeaseId = leaseId
185
+ this.clearRefresh()
186
+ return result
187
+ }
188
+
189
+ private async applyLegacyFov(request: CameraFovRequest): Promise<CameraFovResult> {
190
+ const result = await BluetoothSdk.setLegacyCameraFov(request)
191
+ await this.waitForLegacyCameraRestart()
192
+ return result
193
+ }
194
+
195
+ private waitForLegacyCameraRestart(): Promise<void> {
196
+ if (this.legacyRestartSettleMs <= 0) return Promise.resolve()
197
+ return new Promise<void>((resolve) => setTimeout(resolve, this.legacyRestartSettleMs))
198
+ }
199
+
200
+ private enqueue<T>(operation: () => Promise<T>): Promise<T> {
201
+ const result = this.queue.then(operation, operation)
202
+ this.queue = result.then(
203
+ () => undefined,
204
+ () => undefined,
205
+ )
206
+ return result
207
+ }
208
+ }
209
+
210
+ export const phoneCameraFovCoordinator = new PhoneCameraFovCoordinator()
@@ -1,10 +1,15 @@
1
1
  /**
2
2
  * Phone-notifications sync — engine-owned. Pushes the notification-forwarding
3
- * config (`notifications_enabled` + `notifications_blocklist`) to the native
3
+ * operational kill switch + config (`android_notification_listener_enabled`
4
+ * and `notifications_blocklist`) to the native
4
5
  * NotificationListener via `CrustModule.setNotificationConfig`, so
5
- * `engine.phoneNotifications.setEnabled()/setBlocklist()` actually reach the
6
- * listener for ANY host not just the Mentra app, where this used to live in
7
- * MantleManager. Android-only; a no-op elsewhere. Started by `engine.start()`.
6
+ * the blocklist reaches the listener for ANY host — not just the Mentra App,
7
+ * where this used to live in MantleManager. The Android service is desired by
8
+ * default now that its cold start is isolated from React Native. Native code
9
+ * keeps the component discoverable in Android's notification-access Settings,
10
+ * but only binds the service after access is granted. The debug setting remains
11
+ * a hidden emergency kill switch; Notify's running state gates presentation,
12
+ * not capture. Android-only; a no-op elsewhere. Started by `engine.start()`.
8
13
  */
9
14
  import {shallow} from "zustand/shallow"
10
15
  import CrustModule from "@mentra/crust"
@@ -15,12 +20,9 @@ let unsubscribe: (() => void) | null = null
15
20
 
16
21
  function pushConfig(): void {
17
22
  const s = useSettingsStore.getState()
18
- const enabled = Boolean(s.getSetting(SETTINGS.notifications_enabled.key))
23
+ const listenerEnabled = Boolean(s.getSetting(SETTINGS.android_notification_listener_enabled.key))
19
24
  const blocklist = s.getSetting(SETTINGS.notifications_blocklist.key)
20
- // Unconditional (matches the prior MantleManager sync) the listener is
21
- // Android-only, but CrustModule.setNotificationConfig is a safe no-op elsewhere;
22
- // the Android-only gating lives on the facade's setEnabled/setBlocklist.
23
- CrustModule.setNotificationConfig(enabled, Array.isArray(blocklist) ? blocklist : []).catch((err: unknown) =>
25
+ CrustModule.setNotificationConfig(listenerEnabled, Array.isArray(blocklist) ? blocklist : []).catch((err: unknown) =>
24
26
  console.warn(`PhoneNotificationsSync: setNotificationConfig failed: ${(err as Error)?.message ?? err}`),
25
27
  )
26
28
  }
@@ -30,7 +32,7 @@ export function startPhoneNotificationsSync(): void {
30
32
  pushConfig() // initial sync so the listener has the current config
31
33
  unsubscribe = useSettingsStore.subscribe(
32
34
  (state) => ({
33
- enabled: state.getSetting(SETTINGS.notifications_enabled.key),
35
+ listenerEnabled: state.getSetting(SETTINGS.android_notification_listener_enabled.key),
34
36
  blocklist: state.getSetting(SETTINGS.notifications_blocklist.key),
35
37
  }),
36
38
  () => pushConfig(),
@@ -19,7 +19,7 @@
19
19
  */
20
20
 
21
21
  import BluetoothSdk from "@mentra/bluetooth-sdk/internal"
22
- import type {PhotoSize} from "@mentra/bluetooth-sdk/internal"
22
+ import type {PhotoSize, PhotoTransferMethod} from "@mentra/bluetooth-sdk/internal"
23
23
  import {cloudClientService} from "./CloudClientService"
24
24
  import {isGlassesConnected} from "./GlassesReadiness"
25
25
  import {useGlassesStore} from "../stores/glasses"
@@ -49,10 +49,23 @@ export interface PhotoOpts {
49
49
  /** Legacy cloud size names are normalized before the native take_photo command. */
50
50
  size?: "low" | "medium" | "high" | "max" | "small" | "large" | "full"
51
51
  mode?: "photo" | "text"
52
+ /** Select direct-only, phone-relayed BLE, or the default Wi-Fi/BLE fallback policy. */
53
+ transferMethod?: PhotoTransferMethod
52
54
  compress?: "none" | "low" | "medium" | "high"
53
55
  sound?: boolean
54
56
  saveToGallery?: boolean
55
57
  exposureTimeNs?: number
58
+ iso?: number | null
59
+ aeExposureDivisor?: number
60
+ isoCap?: number
61
+ noiseReduction?: boolean
62
+ edgeEnhancement?: boolean
63
+ /** ZSL preview buffering. */
64
+ zsl?: boolean
65
+ /** MFNR still capture. */
66
+ mfnr?: boolean
67
+ ispDigitalGain?: number
68
+ ispAnalogGain?: string
56
69
  }
57
70
 
58
71
  export interface PhotoTaken {
@@ -80,6 +93,15 @@ export class PhotoError extends Error {
80
93
  }
81
94
  }
82
95
 
96
+ function parsePhotoTransferMethod(value: unknown): PhotoTransferMethod | undefined {
97
+ if (value === undefined) return undefined
98
+ if (value === "auto" || value === "direct" || value === "ble") return value
99
+ throw new PhotoError(
100
+ "INVALID_ARGUMENT",
101
+ `Invalid transferMethod ${JSON.stringify(value)}. Expected "auto", "direct", or "ble".`,
102
+ )
103
+ }
104
+
83
105
  interface ActiveRequest {
84
106
  packageName: string
85
107
  abort: AbortController
@@ -97,6 +119,8 @@ interface ActiveRequest {
97
119
  * rejected successful captures while their upload was still in progress.
98
120
  */
99
121
  export const CAPTURE_PIPELINE_TIMEOUT_MS = 45_000
122
+ export const CAMERA_WARM_UP_DEFAULT_DURATION_MS = 15_000
123
+ export const CAMERA_WARM_UP_MAX_DURATION_MS = 60_000
100
124
 
101
125
  let bleRequestCounter = 0
102
126
 
@@ -120,8 +144,23 @@ export class PhonePhotoCoordinator {
120
144
  private readonly activeRequests = new Map<string, ActiveRequest>()
121
145
  /** Short BLE correlation id (4-char hex) → full cloud requestId. */
122
146
  private readonly bleIdToCloud = new Map<string, string>()
147
+ private readonly activeWarmUps = new Map<
148
+ string,
149
+ {requestId: string; durationMs: number; expiryTimer?: ReturnType<typeof setTimeout>}
150
+ >()
151
+
152
+ /** Report-safe camera ownership snapshot for incident diagnostics. */
153
+ getDiagnosticSnapshot(): Record<string, unknown> {
154
+ return {
155
+ captureOwners: [...new Set([...this.activeRequests.values()].map((request) => request.packageName))].sort(),
156
+ warmUpOwners: [...this.activeWarmUps.keys()].sort(),
157
+ activeCaptureCount: this.activeRequests.size,
158
+ }
159
+ }
123
160
 
124
161
  async takePhoto(packageName: string, opts: PhotoOpts): Promise<PhotoTaken> {
162
+ const transferMethod = parsePhotoTransferMethod(opts.transferMethod)
163
+
125
164
  // Pre-check: if glasses aren't even connected, the BLE photo command
126
165
  // would be sent into the void and we'd wait 30s for the cloud long-poll
127
166
  // to time out. Fail fast with a typed error.
@@ -137,6 +176,10 @@ export class PhonePhotoCoordinator {
137
176
  throw new PhotoError("GLASSES_NOT_CONNECTED", "Glasses are not connected", "command", "ble")
138
177
  }
139
178
 
179
+ // Text-mode sensor resolution is owned by ASG constants; keep cloud metadata on a stable
180
+ // high-capacity tier and let the glasses ignore the public size when mode=text.
181
+ const captureSize = opts.size ?? "medium"
182
+
140
183
  // 1) Presign via the cloud-v2 managed-photo service. Local miniapps use
141
184
  // ONLY the cloud-v2 path: the runtime presigns upload+read URLs and the
142
185
  // phone (as the device controller) delivers the bytes; the legacy
@@ -147,10 +190,16 @@ export class PhonePhotoCoordinator {
147
190
  const flowStarted = performance.now()
148
191
  try {
149
192
  const presignStarted = performance.now()
150
- const r = await cloudClientService.startManagedPhoto({size: opts.size ?? "medium"})
193
+ const r = await cloudClientService.startManagedPhoto({
194
+ size: opts.mode === "text" ? "max" : captureSize,
195
+ })
151
196
  const presignMs = Math.round(performance.now() - presignStarted)
152
197
  if (typeof __DEV__ !== "undefined" && __DEV__) {
153
- console.debug(`[PhonePhotoCoordinator] presign ${presignMs}ms size=${opts.size ?? "medium"}`)
198
+ console.debug(
199
+ `[PhonePhotoCoordinator] presign ${presignMs}ms size=${opts.mode === "text" ? "max" : captureSize} mode=${
200
+ opts.mode ?? "photo"
201
+ }`,
202
+ )
154
203
  }
155
204
  requestId = r.requestId
156
205
  uploadUrl = r.uploadUrl
@@ -204,21 +253,30 @@ export class PhonePhotoCoordinator {
204
253
 
205
254
  // 3) Drive glasses over BLE. requestPhoto now resolves at terminal
206
255
  // photo_response success, so run it beside the cloud poll instead of
207
- // awaiting it before polling. iOS auto-injects transferMethod: "auto"
208
- // (WiFi direct with BLE fallback) see MentraLive.swift.
256
+ // awaiting it before polling. Native defaults transferMethod to "auto"
257
+ // (Wi-Fi direct with BLE fallback) unless the miniapp forces BLE.
209
258
  try {
210
259
  void BluetoothSdk.requestPhoto({
211
260
  requestId: bleRequestId,
212
261
  appId: packageName,
213
- size: normalizePhotoSize(opts.size ?? "medium"),
262
+ size: normalizePhotoSize(captureSize),
214
263
  mode: opts.mode ?? "photo",
215
264
  webhookUrl: uploadUrl,
216
265
  authToken: null,
217
- ...(isLoopbackUpload ? {transferMethod: "ble" as const} : {}),
266
+ ...(isLoopbackUpload ? {transferMethod: "ble" as const} : transferMethod ? {transferMethod} : {}),
218
267
  compress: toNativeCompression(opts.compress),
219
268
  save: opts.saveToGallery ?? false,
220
269
  sound: opts.sound ?? true,
221
270
  exposureTimeNs: opts.exposureTimeNs ?? null,
271
+ iso: opts.iso,
272
+ aeExposureDivisor: opts.aeExposureDivisor,
273
+ isoCap: opts.isoCap,
274
+ noiseReduction: opts.noiseReduction,
275
+ edgeEnhancement: opts.edgeEnhancement,
276
+ ...(opts.zsl != null ? {zsl: opts.zsl} : {}),
277
+ ...(opts.mfnr != null ? {mfnr: opts.mfnr} : {}),
278
+ ispDigitalGain: opts.ispDigitalGain,
279
+ ispAnalogGain: opts.ispAnalogGain,
222
280
  }).catch((err) => {
223
281
  const e = this.activeRequests.get(requestId)
224
282
  if (!e) return
@@ -250,7 +308,9 @@ export class PhonePhotoCoordinator {
250
308
  const result = await outcome
251
309
  if (typeof __DEV__ !== "undefined" && __DEV__) {
252
310
  console.debug(
253
- `[PhonePhotoCoordinator] takePhoto complete ${Math.round(performance.now() - flowStarted)}ms requestId=${requestId}`,
311
+ `[PhonePhotoCoordinator] takePhoto complete ${Math.round(
312
+ performance.now() - flowStarted,
313
+ )}ms requestId=${requestId}`,
254
314
  )
255
315
  }
256
316
  return {
@@ -273,13 +333,20 @@ export class PhonePhotoCoordinator {
273
333
  /**
274
334
  * Pre-warm the glasses camera so the next takePhoto() is near-instant.
275
335
  *
276
- * Pure BLE — NO cloud presign, NO upload, NO long-poll. The SDK mints the
277
- * requestId, sends the warm-up command, and resolves when the camera reports
336
+ * Pure BLE — NO cloud presign, NO upload, NO long-poll. The phone mints and owns
337
+ * the requestId, sends the warm-up command, and resolves when the camera reports
278
338
  * ready (the native promise resolves on the ready status event).
279
339
  */
280
340
  async warmUpCamera(
281
341
  packageName: string,
282
- opts: {size?: "low" | "medium" | "high" | "max"; exposureTimeNs?: number; durationMs?: number},
342
+ opts: {
343
+ size?: "low" | "medium" | "high" | "max"
344
+ mode?: "photo" | "text"
345
+ exposureTimeNs?: number
346
+ durationMs?: number
347
+ zsl?: boolean
348
+ mfnr?: boolean
349
+ },
283
350
  ): Promise<void> {
284
351
  // Pre-check: if glasses aren't connected, the BLE warm-up command would be
285
352
  // sent into the void. Fail fast with a typed error.
@@ -287,17 +354,53 @@ export class PhonePhotoCoordinator {
287
354
  throw new PhotoError("GLASSES_NOT_CONNECTED", "Glasses are not connected", "command", "ble")
288
355
  }
289
356
 
357
+ let lease: {requestId: string; durationMs: number; expiryTimer?: ReturnType<typeof setTimeout>} | undefined
290
358
  try {
359
+ await this.stopWarmUpForApp(packageName)
360
+ const requestId = mintBleRequestId()
361
+ const requestedDuration =
362
+ typeof opts.durationMs === "number" && Number.isFinite(opts.durationMs) && opts.durationMs > 0
363
+ ? Math.round(opts.durationMs)
364
+ : CAMERA_WARM_UP_DEFAULT_DURATION_MS
365
+ const durationMs = Math.min(requestedDuration, CAMERA_WARM_UP_MAX_DURATION_MS)
366
+ lease = {requestId, durationMs}
367
+ this.activeWarmUps.set(packageName, lease)
291
368
  await BluetoothSdk.warmUpCamera({
369
+ requestId,
292
370
  size: normalizePhotoSize(opts.size ?? "medium"),
371
+ mode: opts.mode ?? "photo",
293
372
  exposureTimeNs: opts.exposureTimeNs ?? null,
294
- durationMs: opts.durationMs ?? 15000,
373
+ durationMs,
374
+ ...(opts.zsl != null ? {zsl: opts.zsl} : {}),
375
+ ...(opts.mfnr != null ? {mfnr: opts.mfnr} : {}),
295
376
  })
377
+ if (this.activeWarmUps.get(packageName) === lease) {
378
+ lease.expiryTimer = setTimeout(() => {
379
+ if (this.activeWarmUps.get(packageName) === lease) {
380
+ this.activeWarmUps.delete(packageName)
381
+ }
382
+ }, durationMs)
383
+ }
296
384
  } catch (err) {
385
+ if (lease && this.activeWarmUps.get(packageName) === lease) {
386
+ if (lease.expiryTimer) clearTimeout(lease.expiryTimer)
387
+ this.activeWarmUps.delete(packageName)
388
+ }
297
389
  throw this.toPhotoError(err, "WARM_UP_FAILED", "command", "ble")
298
390
  }
299
391
  }
300
392
 
393
+ /** Release a miniapp's warm-up even if its original warmUpCamera promise is still opening. */
394
+ async stopWarmUpForApp(packageName: string): Promise<void> {
395
+ const active = this.activeWarmUps.get(packageName)
396
+ if (!active) return
397
+ await BluetoothSdk.stopCameraWarmUp(active.requestId)
398
+ if (this.activeWarmUps.get(packageName) === active) {
399
+ this.activeWarmUps.delete(packageName)
400
+ if (active.expiryTimer) clearTimeout(active.expiryTimer)
401
+ }
402
+ }
403
+
301
404
  /** True iff this requestId (short BLE id or cloud id) is one we're currently waiting on. */
302
405
  owns(requestId: string): boolean {
303
406
  const cloudId = this.resolveCloudRequestId(requestId)
@@ -320,12 +423,7 @@ export class PhonePhotoCoordinator {
320
423
  // cloud-v2 pending photo requests TTL out on their own; nothing to free.
321
424
  }
322
425
 
323
- private toPhotoError(
324
- err: unknown,
325
- fallbackCode: string,
326
- stage?: PhotoStage,
327
- transport?: PhotoTransport,
328
- ): PhotoError {
426
+ private toPhotoError(err: unknown, fallbackCode: string, stage?: PhotoStage, transport?: PhotoTransport): PhotoError {
329
427
  if (err instanceof PhotoError) return err
330
428
  const code = (err as {code?: string})?.code
331
429
  const message = err instanceof Error ? err.message : String(err)