@glassly/engine 0.1.0-dev.0

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 (1053) hide show
  1. package/README.md +96 -0
  2. package/build/devtools.d.ts +11 -0
  3. package/build/devtools.d.ts.map +1 -0
  4. package/build/devtools.js +13 -0
  5. package/build/devtools.js.map +1 -0
  6. package/build/engine.d.ts +336 -0
  7. package/build/engine.d.ts.map +1 -0
  8. package/build/engine.js +198 -0
  9. package/build/engine.js.map +1 -0
  10. package/build/facades/dev.d.ts +69 -0
  11. package/build/facades/dev.d.ts.map +1 -0
  12. package/build/facades/dev.js +204 -0
  13. package/build/facades/dev.js.map +1 -0
  14. package/build/facades/display.d.ts +21 -0
  15. package/build/facades/display.d.ts.map +1 -0
  16. package/build/facades/display.js +17 -0
  17. package/build/facades/display.js.map +1 -0
  18. package/build/facades/displayMirror.d.ts +15 -0
  19. package/build/facades/displayMirror.d.ts.map +1 -0
  20. package/build/facades/displayMirror.js +29 -0
  21. package/build/facades/displayMirror.js.map +1 -0
  22. package/build/facades/gallery.d.ts +62 -0
  23. package/build/facades/gallery.d.ts.map +1 -0
  24. package/build/facades/gallery.js +61 -0
  25. package/build/facades/gallery.js.map +1 -0
  26. package/build/facades/glasses.d.ts +142 -0
  27. package/build/facades/glasses.d.ts.map +1 -0
  28. package/build/facades/glasses.js +214 -0
  29. package/build/facades/glasses.js.map +1 -0
  30. package/build/facades/glassesSettings.d.ts +13 -0
  31. package/build/facades/glassesSettings.d.ts.map +1 -0
  32. package/build/facades/glassesSettings.js +55 -0
  33. package/build/facades/glassesSettings.js.map +1 -0
  34. package/build/facades/glassesWifi.d.ts +25 -0
  35. package/build/facades/glassesWifi.d.ts.map +1 -0
  36. package/build/facades/glassesWifi.js +57 -0
  37. package/build/facades/glassesWifi.js.map +1 -0
  38. package/build/facades/maps.d.ts +18 -0
  39. package/build/facades/maps.d.ts.map +1 -0
  40. package/build/facades/maps.js +13 -0
  41. package/build/facades/maps.js.map +1 -0
  42. package/build/facades/memory.d.ts +38 -0
  43. package/build/facades/memory.d.ts.map +1 -0
  44. package/build/facades/memory.js +33 -0
  45. package/build/facades/memory.js.map +1 -0
  46. package/build/facades/miniapps.d.ts +47 -0
  47. package/build/facades/miniapps.d.ts.map +1 -0
  48. package/build/facades/miniapps.js +54 -0
  49. package/build/facades/miniapps.js.map +1 -0
  50. package/build/facades/notifications.d.ts +13 -0
  51. package/build/facades/notifications.d.ts.map +1 -0
  52. package/build/facades/notifications.js +12 -0
  53. package/build/facades/notifications.js.map +1 -0
  54. package/build/facades/ota.d.ts +106 -0
  55. package/build/facades/ota.d.ts.map +1 -0
  56. package/build/facades/ota.js +159 -0
  57. package/build/facades/ota.js.map +1 -0
  58. package/build/facades/pairing.d.ts +115 -0
  59. package/build/facades/pairing.d.ts.map +1 -0
  60. package/build/facades/pairing.js +275 -0
  61. package/build/facades/pairing.js.map +1 -0
  62. package/build/facades/permissions.d.ts +33 -0
  63. package/build/facades/permissions.d.ts.map +1 -0
  64. package/build/facades/permissions.js +155 -0
  65. package/build/facades/permissions.js.map +1 -0
  66. package/build/facades/phoneNotifications.d.ts +17 -0
  67. package/build/facades/phoneNotifications.d.ts.map +1 -0
  68. package/build/facades/phoneNotifications.js +41 -0
  69. package/build/facades/phoneNotifications.js.map +1 -0
  70. package/build/facades/providerKeys.d.ts +26 -0
  71. package/build/facades/providerKeys.d.ts.map +1 -0
  72. package/build/facades/providerKeys.js +26 -0
  73. package/build/facades/providerKeys.js.map +1 -0
  74. package/build/facades/reports.d.ts +36 -0
  75. package/build/facades/reports.d.ts.map +1 -0
  76. package/build/facades/reports.js +134 -0
  77. package/build/facades/reports.js.map +1 -0
  78. package/build/facades/session.d.ts +21 -0
  79. package/build/facades/session.d.ts.map +1 -0
  80. package/build/facades/session.js +52 -0
  81. package/build/facades/session.js.map +1 -0
  82. package/build/facades/settings.d.ts +37 -0
  83. package/build/facades/settings.d.ts.map +1 -0
  84. package/build/facades/settings.js +55 -0
  85. package/build/facades/settings.js.map +1 -0
  86. package/build/facades/speakers.d.ts +41 -0
  87. package/build/facades/speakers.d.ts.map +1 -0
  88. package/build/facades/speakers.js +139 -0
  89. package/build/facades/speakers.js.map +1 -0
  90. package/build/facades/speech.d.ts +44 -0
  91. package/build/facades/speech.d.ts.map +1 -0
  92. package/build/facades/speech.js +46 -0
  93. package/build/facades/speech.js.map +1 -0
  94. package/build/index.d.ts +48 -0
  95. package/build/index.d.ts.map +1 -0
  96. package/build/index.js +49 -0
  97. package/build/index.js.map +1 -0
  98. package/build/internal.d.ts +67 -0
  99. package/build/internal.d.ts.map +1 -0
  100. package/build/internal.js +90 -0
  101. package/build/internal.js.map +1 -0
  102. package/build/runtime/bootstrap.d.ts +115 -0
  103. package/build/runtime/bootstrap.d.ts.map +1 -0
  104. package/build/runtime/bootstrap.js +73 -0
  105. package/build/runtime/bootstrap.js.map +1 -0
  106. package/build/runtime/config.d.ts +152 -0
  107. package/build/runtime/config.d.ts.map +1 -0
  108. package/build/runtime/config.js +19 -0
  109. package/build/runtime/config.js.map +1 -0
  110. package/build/runtime/scanQrSeam.d.ts +7 -0
  111. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  112. package/build/runtime/scanQrSeam.js +16 -0
  113. package/build/runtime/scanQrSeam.js.map +1 -0
  114. package/build/runtime/streamConfig.d.ts +4 -0
  115. package/build/runtime/streamConfig.d.ts.map +1 -0
  116. package/build/runtime/streamConfig.js +38 -0
  117. package/build/runtime/streamConfig.js.map +1 -0
  118. package/build/services/AiTierResolution.d.ts +61 -0
  119. package/build/services/AiTierResolution.d.ts.map +1 -0
  120. package/build/services/AiTierResolution.js +83 -0
  121. package/build/services/AiTierResolution.js.map +1 -0
  122. package/build/services/AppRegistry.d.ts +303 -0
  123. package/build/services/AppRegistry.d.ts.map +1 -0
  124. package/build/services/AppRegistry.js +1108 -0
  125. package/build/services/AppRegistry.js.map +1 -0
  126. package/build/services/AudioCloudUplink.d.ts +15 -0
  127. package/build/services/AudioCloudUplink.d.ts.map +1 -0
  128. package/build/services/AudioCloudUplink.js +54 -0
  129. package/build/services/AudioCloudUplink.js.map +1 -0
  130. package/build/services/AudioPlaybackService.d.ts +183 -0
  131. package/build/services/AudioPlaybackService.d.ts.map +1 -0
  132. package/build/services/AudioPlaybackService.js +750 -0
  133. package/build/services/AudioPlaybackService.js.map +1 -0
  134. package/build/services/AutomaticReportResult.d.ts +20 -0
  135. package/build/services/AutomaticReportResult.d.ts.map +1 -0
  136. package/build/services/AutomaticReportResult.js +29 -0
  137. package/build/services/AutomaticReportResult.js.map +1 -0
  138. package/build/services/BlobStore.d.ts +106 -0
  139. package/build/services/BlobStore.d.ts.map +1 -0
  140. package/build/services/BlobStore.js +741 -0
  141. package/build/services/BlobStore.js.map +1 -0
  142. package/build/services/CaptionsTesterReportService.d.ts +4 -0
  143. package/build/services/CaptionsTesterReportService.d.ts.map +1 -0
  144. package/build/services/CaptionsTesterReportService.js +80 -0
  145. package/build/services/CaptionsTesterReportService.js.map +1 -0
  146. package/build/services/CloudAudioSubscriptionSync.d.ts +24 -0
  147. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -0
  148. package/build/services/CloudAudioSubscriptionSync.js +51 -0
  149. package/build/services/CloudAudioSubscriptionSync.js.map +1 -0
  150. package/build/services/CloudClientService.d.ts +293 -0
  151. package/build/services/CloudClientService.d.ts.map +1 -0
  152. package/build/services/CloudClientService.js +965 -0
  153. package/build/services/CloudClientService.js.map +1 -0
  154. package/build/services/CloudTranscriptE2EMetrics.d.ts +4 -0
  155. package/build/services/CloudTranscriptE2EMetrics.d.ts.map +1 -0
  156. package/build/services/CloudTranscriptE2EMetrics.js +24 -0
  157. package/build/services/CloudTranscriptE2EMetrics.js.map +1 -0
  158. package/build/services/ConnectionCoordinator.d.ts +51 -0
  159. package/build/services/ConnectionCoordinator.d.ts.map +1 -0
  160. package/build/services/ConnectionCoordinator.js +34 -0
  161. package/build/services/ConnectionCoordinator.js.map +1 -0
  162. package/build/services/DevServerBridge.d.ts +63 -0
  163. package/build/services/DevServerBridge.d.ts.map +1 -0
  164. package/build/services/DevServerBridge.js +296 -0
  165. package/build/services/DevServerBridge.js.map +1 -0
  166. package/build/services/DeviceEventRouter.d.ts +3 -0
  167. package/build/services/DeviceEventRouter.d.ts.map +1 -0
  168. package/build/services/DeviceEventRouter.js +214 -0
  169. package/build/services/DeviceEventRouter.js.map +1 -0
  170. package/build/services/DeviceStoreHydration.d.ts +38 -0
  171. package/build/services/DeviceStoreHydration.d.ts.map +1 -0
  172. package/build/services/DeviceStoreHydration.js +124 -0
  173. package/build/services/DeviceStoreHydration.js.map +1 -0
  174. package/build/services/DisplayProcessor.d.ts +223 -0
  175. package/build/services/DisplayProcessor.d.ts.map +1 -0
  176. package/build/services/DisplayProcessor.js +552 -0
  177. package/build/services/DisplayProcessor.js.map +1 -0
  178. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  179. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  180. package/build/services/ForegroundLocationPermission.js +12 -0
  181. package/build/services/ForegroundLocationPermission.js.map +1 -0
  182. package/build/services/GlassesReadiness.d.ts +41 -0
  183. package/build/services/GlassesReadiness.d.ts.map +1 -0
  184. package/build/services/GlassesReadiness.js +82 -0
  185. package/build/services/GlassesReadiness.js.map +1 -0
  186. package/build/services/GlassesSettingsSync.d.ts +33 -0
  187. package/build/services/GlassesSettingsSync.d.ts.map +1 -0
  188. package/build/services/GlassesSettingsSync.js +127 -0
  189. package/build/services/GlassesSettingsSync.js.map +1 -0
  190. package/build/services/GlassesStatusProjection.d.ts +3 -0
  191. package/build/services/GlassesStatusProjection.d.ts.map +1 -0
  192. package/build/services/GlassesStatusProjection.js +65 -0
  193. package/build/services/GlassesStatusProjection.js.map +1 -0
  194. package/build/services/HeadingService.d.ts +33 -0
  195. package/build/services/HeadingService.d.ts.map +1 -0
  196. package/build/services/HeadingService.js +123 -0
  197. package/build/services/HeadingService.js.map +1 -0
  198. package/build/services/HotspotOtaTransport.d.ts +29 -0
  199. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  200. package/build/services/HotspotOtaTransport.js +146 -0
  201. package/build/services/HotspotOtaTransport.js.map +1 -0
  202. package/build/services/HotspotShutdown.d.ts +17 -0
  203. package/build/services/HotspotShutdown.d.ts.map +1 -0
  204. package/build/services/HotspotShutdown.js +29 -0
  205. package/build/services/HotspotShutdown.js.map +1 -0
  206. package/build/services/JSCrashController.d.ts +97 -0
  207. package/build/services/JSCrashController.d.ts.map +1 -0
  208. package/build/services/JSCrashController.js +138 -0
  209. package/build/services/JSCrashController.js.map +1 -0
  210. package/build/services/JSCrashloopReportService.d.ts +9 -0
  211. package/build/services/JSCrashloopReportService.d.ts.map +1 -0
  212. package/build/services/JSCrashloopReportService.js +54 -0
  213. package/build/services/JSCrashloopReportService.js.map +1 -0
  214. package/build/services/JSLogPipeline.d.ts +87 -0
  215. package/build/services/JSLogPipeline.d.ts.map +1 -0
  216. package/build/services/JSLogPipeline.js +137 -0
  217. package/build/services/JSLogPipeline.js.map +1 -0
  218. package/build/services/JSRouter.d.ts +203 -0
  219. package/build/services/JSRouter.d.ts.map +1 -0
  220. package/build/services/JSRouter.js +482 -0
  221. package/build/services/JSRouter.js.map +1 -0
  222. package/build/services/LocalDisplayManager.d.ts +162 -0
  223. package/build/services/LocalDisplayManager.d.ts.map +1 -0
  224. package/build/services/LocalDisplayManager.js +687 -0
  225. package/build/services/LocalDisplayManager.js.map +1 -0
  226. package/build/services/LocalMiniappDataMigration.d.ts +46 -0
  227. package/build/services/LocalMiniappDataMigration.d.ts.map +1 -0
  228. package/build/services/LocalMiniappDataMigration.js +78 -0
  229. package/build/services/LocalMiniappDataMigration.js.map +1 -0
  230. package/build/services/LocalMiniappRuntime.d.ts +677 -0
  231. package/build/services/LocalMiniappRuntime.d.ts.map +1 -0
  232. package/build/services/LocalMiniappRuntime.js +5068 -0
  233. package/build/services/LocalMiniappRuntime.js.map +1 -0
  234. package/build/services/LocalMiniappStorage.d.ts +32 -0
  235. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  236. package/build/services/LocalMiniappStorage.js +66 -0
  237. package/build/services/LocalMiniappStorage.js.map +1 -0
  238. package/build/services/LocalMiniappUserIdentity.d.ts +41 -0
  239. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  240. package/build/services/LocalMiniappUserIdentity.js +73 -0
  241. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  242. package/build/services/LocalSttFallbackCoordinator.d.ts +101 -0
  243. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -0
  244. package/build/services/LocalSttFallbackCoordinator.js +210 -0
  245. package/build/services/LocalSttFallbackCoordinator.js.map +1 -0
  246. package/build/services/MapboxTokenService.d.ts +33 -0
  247. package/build/services/MapboxTokenService.d.ts.map +1 -0
  248. package/build/services/MapboxTokenService.js +115 -0
  249. package/build/services/MapboxTokenService.js.map +1 -0
  250. package/build/services/MemoryCapture.d.ts +40 -0
  251. package/build/services/MemoryCapture.d.ts.map +1 -0
  252. package/build/services/MemoryCapture.js +42 -0
  253. package/build/services/MemoryCapture.js.map +1 -0
  254. package/build/services/MemoryStore.d.ts +184 -0
  255. package/build/services/MemoryStore.d.ts.map +1 -0
  256. package/build/services/MemoryStore.js +541 -0
  257. package/build/services/MemoryStore.js.map +1 -0
  258. package/build/services/MicStateCoordinator.d.ts +78 -0
  259. package/build/services/MicStateCoordinator.d.ts.map +1 -0
  260. package/build/services/MicStateCoordinator.js +219 -0
  261. package/build/services/MicStateCoordinator.js.map +1 -0
  262. package/build/services/MiniappEngine.d.ts +31 -0
  263. package/build/services/MiniappEngine.d.ts.map +1 -0
  264. package/build/services/MiniappEngine.js +119 -0
  265. package/build/services/MiniappEngine.js.map +1 -0
  266. package/build/services/MiniappLauncher.d.ts +127 -0
  267. package/build/services/MiniappLauncher.d.ts.map +1 -0
  268. package/build/services/MiniappLauncher.js +309 -0
  269. package/build/services/MiniappLauncher.js.map +1 -0
  270. package/build/services/MiniappLiveness.d.ts +12 -0
  271. package/build/services/MiniappLiveness.d.ts.map +1 -0
  272. package/build/services/MiniappLiveness.js +16 -0
  273. package/build/services/MiniappLiveness.js.map +1 -0
  274. package/build/services/MiniappRunningRegistry.d.ts +24 -0
  275. package/build/services/MiniappRunningRegistry.d.ts.map +1 -0
  276. package/build/services/MiniappRunningRegistry.js +52 -0
  277. package/build/services/MiniappRunningRegistry.js.map +1 -0
  278. package/build/services/NativeHttpResponse.d.ts +3 -0
  279. package/build/services/NativeHttpResponse.d.ts.map +1 -0
  280. package/build/services/NativeHttpResponse.js +6 -0
  281. package/build/services/NativeHttpResponse.js.map +1 -0
  282. package/build/services/NativeNavigationService.d.ts +51 -0
  283. package/build/services/NativeNavigationService.d.ts.map +1 -0
  284. package/build/services/NativeNavigationService.js +154 -0
  285. package/build/services/NativeNavigationService.js.map +1 -0
  286. package/build/services/NavigationHandlers.d.ts +107 -0
  287. package/build/services/NavigationHandlers.d.ts.map +1 -0
  288. package/build/services/NavigationHandlers.js +479 -0
  289. package/build/services/NavigationHandlers.js.map +1 -0
  290. package/build/services/NavigationService.d.ts +283 -0
  291. package/build/services/NavigationService.d.ts.map +1 -0
  292. package/build/services/NavigationService.js +696 -0
  293. package/build/services/NavigationService.js.map +1 -0
  294. package/build/services/NotificationsEmitter.d.ts +28 -0
  295. package/build/services/NotificationsEmitter.d.ts.map +1 -0
  296. package/build/services/NotificationsEmitter.js +22 -0
  297. package/build/services/NotificationsEmitter.js.map +1 -0
  298. package/build/services/OfflineSpeechModelService.d.ts +33 -0
  299. package/build/services/OfflineSpeechModelService.d.ts.map +1 -0
  300. package/build/services/OfflineSpeechModelService.js +136 -0
  301. package/build/services/OfflineSpeechModelService.js.map +1 -0
  302. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  303. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  304. package/build/services/OtaArtifactDownloader.js +226 -0
  305. package/build/services/OtaArtifactDownloader.js.map +1 -0
  306. package/build/services/OtaInstallCoordinator.d.ts +275 -0
  307. package/build/services/OtaInstallCoordinator.d.ts.map +1 -0
  308. package/build/services/OtaInstallCoordinator.js +1491 -0
  309. package/build/services/OtaInstallCoordinator.js.map +1 -0
  310. package/build/services/OtaService.d.ts +3 -0
  311. package/build/services/OtaService.d.ts.map +1 -0
  312. package/build/services/OtaService.js +72 -0
  313. package/build/services/OtaService.js.map +1 -0
  314. package/build/services/OtaUpdateCheckService.d.ts +100 -0
  315. package/build/services/OtaUpdateCheckService.d.ts.map +1 -0
  316. package/build/services/OtaUpdateCheckService.js +380 -0
  317. package/build/services/OtaUpdateCheckService.js.map +1 -0
  318. package/build/services/PairingIdentity.d.ts +80 -0
  319. package/build/services/PairingIdentity.d.ts.map +1 -0
  320. package/build/services/PairingIdentity.js +145 -0
  321. package/build/services/PairingIdentity.js.map +1 -0
  322. package/build/services/PhoneCalendarHelpers.d.ts +32 -0
  323. package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
  324. package/build/services/PhoneCalendarHelpers.js +157 -0
  325. package/build/services/PhoneCalendarHelpers.js.map +1 -0
  326. package/build/services/PhoneCalendarService.d.ts +5 -0
  327. package/build/services/PhoneCalendarService.d.ts.map +1 -0
  328. package/build/services/PhoneCalendarService.js +45 -0
  329. package/build/services/PhoneCalendarService.js.map +1 -0
  330. package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
  331. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
  332. package/build/services/PhoneCameraFovCoordinator.js +194 -0
  333. package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
  334. package/build/services/PhoneLocationService.d.ts +36 -0
  335. package/build/services/PhoneLocationService.d.ts.map +1 -0
  336. package/build/services/PhoneLocationService.js +115 -0
  337. package/build/services/PhoneLocationService.js.map +1 -0
  338. package/build/services/PhoneNotificationsSync.d.ts +3 -0
  339. package/build/services/PhoneNotificationsSync.d.ts.map +1 -0
  340. package/build/services/PhoneNotificationsSync.js +37 -0
  341. package/build/services/PhoneNotificationsSync.js.map +1 -0
  342. package/build/services/PhonePhotoCoordinator.d.ts +110 -0
  343. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -0
  344. package/build/services/PhonePhotoCoordinator.js +344 -0
  345. package/build/services/PhonePhotoCoordinator.js.map +1 -0
  346. package/build/services/PhoneStreamCoordinator.d.ts +175 -0
  347. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -0
  348. package/build/services/PhoneStreamCoordinator.js +740 -0
  349. package/build/services/PhoneStreamCoordinator.js.map +1 -0
  350. package/build/services/PhoneVideoCoordinator.d.ts +52 -0
  351. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -0
  352. package/build/services/PhoneVideoCoordinator.js +157 -0
  353. package/build/services/PhoneVideoCoordinator.js.map +1 -0
  354. package/build/services/ProviderKeyValidation.d.ts +27 -0
  355. package/build/services/ProviderKeyValidation.d.ts.map +1 -0
  356. package/build/services/ProviderKeyValidation.js +42 -0
  357. package/build/services/ProviderKeyValidation.js.map +1 -0
  358. package/build/services/STTModelManager.d.ts +65 -0
  359. package/build/services/STTModelManager.d.ts.map +1 -0
  360. package/build/services/STTModelManager.js +366 -0
  361. package/build/services/STTModelManager.js.map +1 -0
  362. package/build/services/SceneRenderer.d.ts +90 -0
  363. package/build/services/SceneRenderer.d.ts.map +1 -0
  364. package/build/services/SceneRenderer.js +274 -0
  365. package/build/services/SceneRenderer.js.map +1 -0
  366. package/build/services/SentenceTtsPipeline.d.ts +31 -0
  367. package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
  368. package/build/services/SentenceTtsPipeline.js +67 -0
  369. package/build/services/SentenceTtsPipeline.js.map +1 -0
  370. package/build/services/SpeakerIdModelManager.d.ts +36 -0
  371. package/build/services/SpeakerIdModelManager.d.ts.map +1 -0
  372. package/build/services/SpeakerIdModelManager.js +132 -0
  373. package/build/services/SpeakerIdModelManager.js.map +1 -0
  374. package/build/services/SpeakerIdSync.d.ts +14 -0
  375. package/build/services/SpeakerIdSync.d.ts.map +1 -0
  376. package/build/services/SpeakerIdSync.js +62 -0
  377. package/build/services/SpeakerIdSync.js.map +1 -0
  378. package/build/services/SpeakerLabelResolver.d.ts +80 -0
  379. package/build/services/SpeakerLabelResolver.d.ts.map +1 -0
  380. package/build/services/SpeakerLabelResolver.js +108 -0
  381. package/build/services/SpeakerLabelResolver.js.map +1 -0
  382. package/build/services/SpeakerProfileStore.d.ts +90 -0
  383. package/build/services/SpeakerProfileStore.d.ts.map +1 -0
  384. package/build/services/SpeakerProfileStore.js +213 -0
  385. package/build/services/SpeakerProfileStore.js.map +1 -0
  386. package/build/services/SpeakerSegmentResolver.d.ts +87 -0
  387. package/build/services/SpeakerSegmentResolver.d.ts.map +1 -0
  388. package/build/services/SpeakerSegmentResolver.js +137 -0
  389. package/build/services/SpeakerSegmentResolver.js.map +1 -0
  390. package/build/services/StreamLifecycleController.d.ts +63 -0
  391. package/build/services/StreamLifecycleController.d.ts.map +1 -0
  392. package/build/services/StreamLifecycleController.js +148 -0
  393. package/build/services/StreamLifecycleController.js.map +1 -0
  394. package/build/services/SupportProfileSync.d.ts +22 -0
  395. package/build/services/SupportProfileSync.d.ts.map +1 -0
  396. package/build/services/SupportProfileSync.js +213 -0
  397. package/build/services/SupportProfileSync.js.map +1 -0
  398. package/build/services/TTSModelManager.d.ts +90 -0
  399. package/build/services/TTSModelManager.d.ts.map +1 -0
  400. package/build/services/TTSModelManager.js +366 -0
  401. package/build/services/TTSModelManager.js.map +1 -0
  402. package/build/services/TranscriptionRouting.d.ts +22 -0
  403. package/build/services/TranscriptionRouting.d.ts.map +1 -0
  404. package/build/services/TranscriptionRouting.js +34 -0
  405. package/build/services/TranscriptionRouting.js.map +1 -0
  406. package/build/services/TtsTextSanitizer.d.ts +5 -0
  407. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  408. package/build/services/TtsTextSanitizer.js +61 -0
  409. package/build/services/TtsTextSanitizer.js.map +1 -0
  410. package/build/services/UIRouter.d.ts +137 -0
  411. package/build/services/UIRouter.d.ts.map +1 -0
  412. package/build/services/UIRouter.js +210 -0
  413. package/build/services/UIRouter.js.map +1 -0
  414. package/build/services/WebviewBridge.d.ts +22 -0
  415. package/build/services/WebviewBridge.d.ts.map +1 -0
  416. package/build/services/WebviewBridge.js +47 -0
  417. package/build/services/WebviewBridge.js.map +1 -0
  418. package/build/services/WifiAdbRequest.d.ts +17 -0
  419. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  420. package/build/services/WifiAdbRequest.js +35 -0
  421. package/build/services/WifiAdbRequest.js.map +1 -0
  422. package/build/services/asg/GalleryMediaIntegrityReportService.d.ts +17 -0
  423. package/build/services/asg/GalleryMediaIntegrityReportService.d.ts.map +1 -0
  424. package/build/services/asg/GalleryMediaIntegrityReportService.js +43 -0
  425. package/build/services/asg/GalleryMediaIntegrityReportService.js.map +1 -0
  426. package/build/services/asg/asgCameraApi.d.ts +208 -0
  427. package/build/services/asg/asgCameraApi.d.ts.map +1 -0
  428. package/build/services/asg/asgCameraApi.js +1480 -0
  429. package/build/services/asg/asgCameraApi.js.map +1 -0
  430. package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
  431. package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
  432. package/build/services/asg/cameraRollExportCoordinator.js +618 -0
  433. package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
  434. package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
  435. package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
  436. package/build/services/asg/cameraRollExportLedger.js +78 -0
  437. package/build/services/asg/cameraRollExportLedger.js.map +1 -0
  438. package/build/services/asg/galleryMediaValidation.d.ts +29 -0
  439. package/build/services/asg/galleryMediaValidation.d.ts.map +1 -0
  440. package/build/services/asg/galleryMediaValidation.js +149 -0
  441. package/build/services/asg/galleryMediaValidation.js.map +1 -0
  442. package/build/services/asg/galleryNotices.d.ts +33 -0
  443. package/build/services/asg/galleryNotices.d.ts.map +1 -0
  444. package/build/services/asg/galleryNotices.js +29 -0
  445. package/build/services/asg/galleryNotices.js.map +1 -0
  446. package/build/services/asg/galleryPathMigration.d.ts +3 -0
  447. package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
  448. package/build/services/asg/galleryPathMigration.js +26 -0
  449. package/build/services/asg/galleryPathMigration.js.map +1 -0
  450. package/build/services/asg/gallerySettingsService.d.ts +20 -0
  451. package/build/services/asg/gallerySettingsService.d.ts.map +1 -0
  452. package/build/services/asg/gallerySettingsService.js +53 -0
  453. package/build/services/asg/gallerySettingsService.js.map +1 -0
  454. package/build/services/asg/gallerySyncNotifications.d.ts +56 -0
  455. package/build/services/asg/gallerySyncNotifications.d.ts.map +1 -0
  456. package/build/services/asg/gallerySyncNotifications.js +198 -0
  457. package/build/services/asg/gallerySyncNotifications.js.map +1 -0
  458. package/build/services/asg/gallerySyncService.d.ts +137 -0
  459. package/build/services/asg/gallerySyncService.d.ts.map +1 -0
  460. package/build/services/asg/gallerySyncService.js +1945 -0
  461. package/build/services/asg/gallerySyncService.js.map +1 -0
  462. package/build/services/asg/galleryTransferLedger.d.ts +58 -0
  463. package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
  464. package/build/services/asg/galleryTransferLedger.js +225 -0
  465. package/build/services/asg/galleryTransferLedger.js.map +1 -0
  466. package/build/services/asg/localNetworkTransport.d.ts +15 -0
  467. package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
  468. package/build/services/asg/localNetworkTransport.js +144 -0
  469. package/build/services/asg/localNetworkTransport.js.map +1 -0
  470. package/build/services/asg/localStorageService.d.ts +146 -0
  471. package/build/services/asg/localStorageService.d.ts.map +1 -0
  472. package/build/services/asg/localStorageService.js +572 -0
  473. package/build/services/asg/localStorageService.js.map +1 -0
  474. package/build/services/asg/mediaProcessingQueue.d.ts +70 -0
  475. package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -0
  476. package/build/services/asg/mediaProcessingQueue.js +451 -0
  477. package/build/services/asg/mediaProcessingQueue.js.map +1 -0
  478. package/build/services/audioPlaybackAssets.d.ts +8 -0
  479. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  480. package/build/services/audioPlaybackAssets.js +7 -0
  481. package/build/services/audioPlaybackAssets.js.map +1 -0
  482. package/build/services/blobPaths.d.ts +31 -0
  483. package/build/services/blobPaths.d.ts.map +1 -0
  484. package/build/services/blobPaths.js +86 -0
  485. package/build/services/blobPaths.js.map +1 -0
  486. package/build/services/cloudStreamApi.d.ts +59 -0
  487. package/build/services/cloudStreamApi.d.ts.map +1 -0
  488. package/build/services/cloudStreamApi.js +81 -0
  489. package/build/services/cloudStreamApi.js.map +1 -0
  490. package/build/services/effectiveCapabilities.d.ts +8 -0
  491. package/build/services/effectiveCapabilities.d.ts.map +1 -0
  492. package/build/services/effectiveCapabilities.js +23 -0
  493. package/build/services/effectiveCapabilities.js.map +1 -0
  494. package/build/services/gallerySyncClock.d.ts +17 -0
  495. package/build/services/gallerySyncClock.d.ts.map +1 -0
  496. package/build/services/gallerySyncClock.js +21 -0
  497. package/build/services/gallerySyncClock.js.map +1 -0
  498. package/build/services/glassesClockSync.d.ts +20 -0
  499. package/build/services/glassesClockSync.d.ts.map +1 -0
  500. package/build/services/glassesClockSync.js +97 -0
  501. package/build/services/glassesClockSync.js.map +1 -0
  502. package/build/services/manifestActions.d.ts +31 -0
  503. package/build/services/manifestActions.d.ts.map +1 -0
  504. package/build/services/manifestActions.js +54 -0
  505. package/build/services/manifestActions.js.map +1 -0
  506. package/build/services/manifestVersionGate.d.ts +28 -0
  507. package/build/services/manifestVersionGate.d.ts.map +1 -0
  508. package/build/services/manifestVersionGate.js +41 -0
  509. package/build/services/manifestVersionGate.js.map +1 -0
  510. package/build/services/memoryStoreInstance.d.ts +19 -0
  511. package/build/services/memoryStoreInstance.d.ts.map +1 -0
  512. package/build/services/memoryStoreInstance.js +65 -0
  513. package/build/services/memoryStoreInstance.js.map +1 -0
  514. package/build/services/navigation/roadNameResolver.d.ts +67 -0
  515. package/build/services/navigation/roadNameResolver.d.ts.map +1 -0
  516. package/build/services/navigation/roadNameResolver.js +87 -0
  517. package/build/services/navigation/roadNameResolver.js.map +1 -0
  518. package/build/services/navigation/routesApiCodec.d.ts +38 -0
  519. package/build/services/navigation/routesApiCodec.d.ts.map +1 -0
  520. package/build/services/navigation/routesApiCodec.js +68 -0
  521. package/build/services/navigation/routesApiCodec.js.map +1 -0
  522. package/build/services/otaDisplayState.d.ts +53 -0
  523. package/build/services/otaDisplayState.d.ts.map +1 -0
  524. package/build/services/otaDisplayState.js +114 -0
  525. package/build/services/otaDisplayState.js.map +1 -0
  526. package/build/services/otaInstallPolicy.d.ts +93 -0
  527. package/build/services/otaInstallPolicy.d.ts.map +1 -0
  528. package/build/services/otaInstallPolicy.js +117 -0
  529. package/build/services/otaInstallPolicy.js.map +1 -0
  530. package/build/services/otaLegacyMapping.d.ts +22 -0
  531. package/build/services/otaLegacyMapping.d.ts.map +1 -0
  532. package/build/services/otaLegacyMapping.js +56 -0
  533. package/build/services/otaLegacyMapping.js.map +1 -0
  534. package/build/services/otaManifestUrl.d.ts +2 -0
  535. package/build/services/otaManifestUrl.d.ts.map +1 -0
  536. package/build/services/otaManifestUrl.js +46 -0
  537. package/build/services/otaManifestUrl.js.map +1 -0
  538. package/build/services/slimStreamStatus.d.ts +18 -0
  539. package/build/services/slimStreamStatus.d.ts.map +1 -0
  540. package/build/services/slimStreamStatus.js +36 -0
  541. package/build/services/slimStreamStatus.js.map +1 -0
  542. package/build/services/soniox/SonioxDirectService.d.ts +109 -0
  543. package/build/services/soniox/SonioxDirectService.d.ts.map +1 -0
  544. package/build/services/soniox/SonioxDirectService.js +449 -0
  545. package/build/services/soniox/SonioxDirectService.js.map +1 -0
  546. package/build/services/soniox/SonioxRealtimeClient.d.ts +121 -0
  547. package/build/services/soniox/SonioxRealtimeClient.d.ts.map +1 -0
  548. package/build/services/soniox/SonioxRealtimeClient.js +301 -0
  549. package/build/services/soniox/SonioxRealtimeClient.js.map +1 -0
  550. package/build/services/soniox/SonioxTokenAssembler.d.ts +98 -0
  551. package/build/services/soniox/SonioxTokenAssembler.d.ts.map +1 -0
  552. package/build/services/soniox/SonioxTokenAssembler.js +394 -0
  553. package/build/services/soniox/SonioxTokenAssembler.js.map +1 -0
  554. package/build/services/speakerProfileStoreInstance.d.ts +8 -0
  555. package/build/services/speakerProfileStoreInstance.d.ts.map +1 -0
  556. package/build/services/speakerProfileStoreInstance.js +24 -0
  557. package/build/services/speakerProfileStoreInstance.js.map +1 -0
  558. package/build/services/uiShim.d.ts +38 -0
  559. package/build/services/uiShim.d.ts.map +1 -0
  560. package/build/services/uiShim.js +369 -0
  561. package/build/services/uiShim.js.map +1 -0
  562. package/build/stores/apps.d.ts +104 -0
  563. package/build/stores/apps.d.ts.map +1 -0
  564. package/build/stores/apps.js +503 -0
  565. package/build/stores/apps.js.map +1 -0
  566. package/build/stores/bluetoothSettingKeys.d.ts +4 -0
  567. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -0
  568. package/build/stores/bluetoothSettingKeys.js +33 -0
  569. package/build/stores/bluetoothSettingKeys.js.map +1 -0
  570. package/build/stores/cloudClientStatus.d.ts +9 -0
  571. package/build/stores/cloudClientStatus.d.ts.map +1 -0
  572. package/build/stores/cloudClientStatus.js +24 -0
  573. package/build/stores/cloudClientStatus.js.map +1 -0
  574. package/build/stores/connection.d.ts +22 -0
  575. package/build/stores/connection.d.ts.map +1 -0
  576. package/build/stores/connection.js +43 -0
  577. package/build/stores/connection.js.map +1 -0
  578. package/build/stores/core.d.ts +15 -0
  579. package/build/stores/core.d.ts.map +1 -0
  580. package/build/stores/core.js +21 -0
  581. package/build/stores/core.js.map +1 -0
  582. package/build/stores/display.d.ts +24 -0
  583. package/build/stores/display.d.ts.map +1 -0
  584. package/build/stores/display.js +96 -0
  585. package/build/stores/display.js.map +1 -0
  586. package/build/stores/gallerySync.d.ts +103 -0
  587. package/build/stores/gallerySync.d.ts.map +1 -0
  588. package/build/stores/gallerySync.js +219 -0
  589. package/build/stores/gallerySync.js.map +1 -0
  590. package/build/stores/glasses.d.ts +62 -0
  591. package/build/stores/glasses.d.ts.map +1 -0
  592. package/build/stores/glasses.js +208 -0
  593. package/build/stores/glasses.js.map +1 -0
  594. package/build/stores/settings.d.ts +54 -0
  595. package/build/stores/settings.d.ts.map +1 -0
  596. package/build/stores/settings.js +1200 -0
  597. package/build/stores/settings.js.map +1 -0
  598. package/build/stores/transcriptionDebug.d.ts +25 -0
  599. package/build/stores/transcriptionDebug.d.ts.map +1 -0
  600. package/build/stores/transcriptionDebug.js +0 -0
  601. package/build/stores/transcriptionDebug.js.map +1 -0
  602. package/build/types/applet.d.ts +101 -0
  603. package/build/types/applet.d.ts.map +1 -0
  604. package/build/types/applet.js +5 -0
  605. package/build/types/applet.js.map +1 -0
  606. package/build/types/asg.d.ts +53 -0
  607. package/build/types/asg.d.ts.map +1 -0
  608. package/build/types/asg.js +2 -0
  609. package/build/types/asg.js.map +1 -0
  610. package/build/types/capabilities/even-realities-g1.d.ts +12 -0
  611. package/build/types/capabilities/even-realities-g1.d.ts.map +1 -0
  612. package/build/types/capabilities/even-realities-g1.js +57 -0
  613. package/build/types/capabilities/even-realities-g1.js.map +1 -0
  614. package/build/types/capabilities/even-realities-g2.d.ts +12 -0
  615. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -0
  616. package/build/types/capabilities/even-realities-g2.js +83 -0
  617. package/build/types/capabilities/even-realities-g2.js.map +1 -0
  618. package/build/types/capabilities/mentra-display.d.ts +12 -0
  619. package/build/types/capabilities/mentra-display.d.ts.map +1 -0
  620. package/build/types/capabilities/mentra-display.js +65 -0
  621. package/build/types/capabilities/mentra-display.js.map +1 -0
  622. package/build/types/capabilities/mentra-live.d.ts +12 -0
  623. package/build/types/capabilities/mentra-live.d.ts.map +1 -0
  624. package/build/types/capabilities/mentra-live.js +94 -0
  625. package/build/types/capabilities/mentra-live.js.map +1 -0
  626. package/build/types/capabilities/nimo.d.ts +13 -0
  627. package/build/types/capabilities/nimo.d.ts.map +1 -0
  628. package/build/types/capabilities/nimo.js +72 -0
  629. package/build/types/capabilities/nimo.js.map +1 -0
  630. package/build/types/capabilities/none.d.ts +13 -0
  631. package/build/types/capabilities/none.d.ts.map +1 -0
  632. package/build/types/capabilities/none.js +67 -0
  633. package/build/types/capabilities/none.js.map +1 -0
  634. package/build/types/capabilities/simulated-glasses.d.ts +13 -0
  635. package/build/types/capabilities/simulated-glasses.d.ts.map +1 -0
  636. package/build/types/capabilities/simulated-glasses.js +82 -0
  637. package/build/types/capabilities/simulated-glasses.js.map +1 -0
  638. package/build/types/capabilities/vuzix-z100.d.ts +12 -0
  639. package/build/types/capabilities/vuzix-z100.d.ts.map +1 -0
  640. package/build/types/capabilities/vuzix-z100.js +54 -0
  641. package/build/types/capabilities/vuzix-z100.js.map +1 -0
  642. package/build/types/enums.d.ts +22 -0
  643. package/build/types/enums.d.ts.map +1 -0
  644. package/build/types/enums.js +27 -0
  645. package/build/types/enums.js.map +1 -0
  646. package/build/types/hardware.d.ts +155 -0
  647. package/build/types/hardware.d.ts.map +1 -0
  648. package/build/types/hardware.js +52 -0
  649. package/build/types/hardware.js.map +1 -0
  650. package/build/types/index.d.ts +11 -0
  651. package/build/types/index.d.ts.map +1 -0
  652. package/build/types/index.js +10 -0
  653. package/build/types/index.js.map +1 -0
  654. package/build/utils/GlobalEventEmitter.d.ts +11 -0
  655. package/build/utils/GlobalEventEmitter.d.ts.map +1 -0
  656. package/build/utils/GlobalEventEmitter.js +14 -0
  657. package/build/utils/GlobalEventEmitter.js.map +1 -0
  658. package/build/utils/cloudClient/RnUdpAdapter.d.ts +3 -0
  659. package/build/utils/cloudClient/RnUdpAdapter.d.ts.map +1 -0
  660. package/build/utils/cloudClient/RnUdpAdapter.js +41 -0
  661. package/build/utils/cloudClient/RnUdpAdapter.js.map +1 -0
  662. package/build/utils/cloudClient/cloudSecureStore.d.ts +3 -0
  663. package/build/utils/cloudClient/cloudSecureStore.d.ts.map +1 -0
  664. package/build/utils/cloudClient/cloudSecureStore.js +26 -0
  665. package/build/utils/cloudClient/cloudSecureStore.js.map +1 -0
  666. package/build/utils/configuredDevHost.d.ts +6 -0
  667. package/build/utils/configuredDevHost.d.ts.map +1 -0
  668. package/build/utils/configuredDevHost.js +19 -0
  669. package/build/utils/configuredDevHost.js.map +1 -0
  670. package/build/utils/debouncedPatch.d.ts +6 -0
  671. package/build/utils/debouncedPatch.d.ts.map +1 -0
  672. package/build/utils/debouncedPatch.js +25 -0
  673. package/build/utils/debouncedPatch.js.map +1 -0
  674. package/build/utils/devLogging.d.ts +26 -0
  675. package/build/utils/devLogging.d.ts.map +1 -0
  676. package/build/utils/devLogging.js +116 -0
  677. package/build/utils/devLogging.js.map +1 -0
  678. package/build/utils/devMiniappLaunch.d.ts +55 -0
  679. package/build/utils/devMiniappLaunch.d.ts.map +1 -0
  680. package/build/utils/devMiniappLaunch.js +175 -0
  681. package/build/utils/devMiniappLaunch.js.map +1 -0
  682. package/build/utils/diagnosticContext.d.ts +3 -0
  683. package/build/utils/diagnosticContext.d.ts.map +1 -0
  684. package/build/utils/diagnosticContext.js +122 -0
  685. package/build/utils/diagnosticContext.js.map +1 -0
  686. package/build/utils/display/composer/ColumnComposer.d.ts +131 -0
  687. package/build/utils/display/composer/ColumnComposer.d.ts.map +1 -0
  688. package/build/utils/display/composer/ColumnComposer.js +204 -0
  689. package/build/utils/display/composer/ColumnComposer.js.map +1 -0
  690. package/build/utils/display/composer/index.d.ts +9 -0
  691. package/build/utils/display/composer/index.d.ts.map +1 -0
  692. package/build/utils/display/composer/index.js +9 -0
  693. package/build/utils/display/composer/index.js.map +1 -0
  694. package/build/utils/display/helpers/DisplayHelpers.d.ts +165 -0
  695. package/build/utils/display/helpers/DisplayHelpers.d.ts.map +1 -0
  696. package/build/utils/display/helpers/DisplayHelpers.js +312 -0
  697. package/build/utils/display/helpers/DisplayHelpers.js.map +1 -0
  698. package/build/utils/display/helpers/ScrollView.d.ts +183 -0
  699. package/build/utils/display/helpers/ScrollView.d.ts.map +1 -0
  700. package/build/utils/display/helpers/ScrollView.js +257 -0
  701. package/build/utils/display/helpers/ScrollView.js.map +1 -0
  702. package/build/utils/display/helpers/index.d.ts +11 -0
  703. package/build/utils/display/helpers/index.d.ts.map +1 -0
  704. package/build/utils/display/helpers/index.js +10 -0
  705. package/build/utils/display/helpers/index.js.map +1 -0
  706. package/build/utils/display/index.d.ts +174 -0
  707. package/build/utils/display/index.d.ts.map +1 -0
  708. package/build/utils/display/index.js +188 -0
  709. package/build/utils/display/index.js.map +1 -0
  710. package/build/utils/display/measurer/TextMeasurer.d.ts +160 -0
  711. package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -0
  712. package/build/utils/display/measurer/TextMeasurer.js +273 -0
  713. package/build/utils/display/measurer/TextMeasurer.js.map +1 -0
  714. package/build/utils/display/measurer/index.d.ts +10 -0
  715. package/build/utils/display/measurer/index.d.ts.map +1 -0
  716. package/build/utils/display/measurer/index.js +11 -0
  717. package/build/utils/display/measurer/index.js.map +1 -0
  718. package/build/utils/display/measurer/script-detection.d.ts +53 -0
  719. package/build/utils/display/measurer/script-detection.d.ts.map +1 -0
  720. package/build/utils/display/measurer/script-detection.js +184 -0
  721. package/build/utils/display/measurer/script-detection.js.map +1 -0
  722. package/build/utils/display/profiles/g1.d.ts +33 -0
  723. package/build/utils/display/profiles/g1.d.ts.map +1 -0
  724. package/build/utils/display/profiles/g1.js +213 -0
  725. package/build/utils/display/profiles/g1.js.map +1 -0
  726. package/build/utils/display/profiles/g2.d.ts +13 -0
  727. package/build/utils/display/profiles/g2.d.ts.map +1 -0
  728. package/build/utils/display/profiles/g2.js +34 -0
  729. package/build/utils/display/profiles/g2.js.map +1 -0
  730. package/build/utils/display/profiles/index.d.ts +12 -0
  731. package/build/utils/display/profiles/index.d.ts.map +1 -0
  732. package/build/utils/display/profiles/index.js +15 -0
  733. package/build/utils/display/profiles/index.js.map +1 -0
  734. package/build/utils/display/profiles/nex.d.ts +10 -0
  735. package/build/utils/display/profiles/nex.d.ts.map +1 -0
  736. package/build/utils/display/profiles/nex.js +150 -0
  737. package/build/utils/display/profiles/nex.js.map +1 -0
  738. package/build/utils/display/profiles/types.d.ts +103 -0
  739. package/build/utils/display/profiles/types.d.ts.map +1 -0
  740. package/build/utils/display/profiles/types.js +2 -0
  741. package/build/utils/display/profiles/types.js.map +1 -0
  742. package/build/utils/display/profiles/z100.d.ts +33 -0
  743. package/build/utils/display/profiles/z100.d.ts.map +1 -0
  744. package/build/utils/display/profiles/z100.js +182 -0
  745. package/build/utils/display/profiles/z100.js.map +1 -0
  746. package/build/utils/display/scene/anchor.d.ts +17 -0
  747. package/build/utils/display/scene/anchor.d.ts.map +1 -0
  748. package/build/utils/display/scene/anchor.js +33 -0
  749. package/build/utils/display/scene/anchor.js.map +1 -0
  750. package/build/utils/display/scene/degrade.d.ts +25 -0
  751. package/build/utils/display/scene/degrade.d.ts.map +1 -0
  752. package/build/utils/display/scene/degrade.js +64 -0
  753. package/build/utils/display/scene/degrade.js.map +1 -0
  754. package/build/utils/display/scene/differ.d.ts +38 -0
  755. package/build/utils/display/scene/differ.d.ts.map +1 -0
  756. package/build/utils/display/scene/differ.js +107 -0
  757. package/build/utils/display/scene/differ.js.map +1 -0
  758. package/build/utils/display/scene/index.d.ts +11 -0
  759. package/build/utils/display/scene/index.d.ts.map +1 -0
  760. package/build/utils/display/scene/index.js +7 -0
  761. package/build/utils/display/scene/index.js.map +1 -0
  762. package/build/utils/display/scene/process.d.ts +35 -0
  763. package/build/utils/display/scene/process.d.ts.map +1 -0
  764. package/build/utils/display/scene/process.js +201 -0
  765. package/build/utils/display/scene/process.js.map +1 -0
  766. package/build/utils/display/scene/store.d.ts +48 -0
  767. package/build/utils/display/scene/store.d.ts.map +1 -0
  768. package/build/utils/display/scene/store.js +0 -0
  769. package/build/utils/display/scene/store.js.map +1 -0
  770. package/build/utils/display/scene/types.d.ts +139 -0
  771. package/build/utils/display/scene/types.d.ts.map +1 -0
  772. package/build/utils/display/scene/types.js +0 -0
  773. package/build/utils/display/scene/types.js.map +1 -0
  774. package/build/utils/display/wrapper/TextWrapper.d.ts +102 -0
  775. package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -0
  776. package/build/utils/display/wrapper/TextWrapper.js +471 -0
  777. package/build/utils/display/wrapper/TextWrapper.js.map +1 -0
  778. package/build/utils/display/wrapper/index.d.ts +12 -0
  779. package/build/utils/display/wrapper/index.d.ts.map +1 -0
  780. package/build/utils/display/wrapper/index.js +12 -0
  781. package/build/utils/display/wrapper/index.js.map +1 -0
  782. package/build/utils/display/wrapper/types.d.ts +75 -0
  783. package/build/utils/display/wrapper/types.d.ts.map +1 -0
  784. package/build/utils/display/wrapper/types.js +11 -0
  785. package/build/utils/display/wrapper/types.js.map +1 -0
  786. package/build/utils/e2eMetrics.d.ts +6 -0
  787. package/build/utils/e2eMetrics.d.ts.map +1 -0
  788. package/build/utils/e2eMetrics.js +27 -0
  789. package/build/utils/e2eMetrics.js.map +1 -0
  790. package/build/utils/hardware/hardware.d.ts +42 -0
  791. package/build/utils/hardware/hardware.d.ts.map +1 -0
  792. package/build/utils/hardware/hardware.js +131 -0
  793. package/build/utils/hardware/hardware.js.map +1 -0
  794. package/build/utils/hardware/index.d.ts +2 -0
  795. package/build/utils/hardware/index.d.ts.map +1 -0
  796. package/build/utils/hardware/index.js +2 -0
  797. package/build/utils/hardware/index.js.map +1 -0
  798. package/build/utils/memory/search.d.ts +72 -0
  799. package/build/utils/memory/search.d.ts.map +1 -0
  800. package/build/utils/memory/search.js +178 -0
  801. package/build/utils/memory/search.js.map +1 -0
  802. package/build/utils/miniappDiagnostics.d.ts +64 -0
  803. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  804. package/build/utils/miniappDiagnostics.js +173 -0
  805. package/build/utils/miniappDiagnostics.js.map +1 -0
  806. package/build/utils/miniappGlobals.d.ts +59 -0
  807. package/build/utils/miniappGlobals.d.ts.map +1 -0
  808. package/build/utils/miniappGlobals.js +223 -0
  809. package/build/utils/miniappGlobals.js.map +1 -0
  810. package/build/utils/permissions/MediaLibraryPermissions.d.ts +45 -0
  811. package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -0
  812. package/build/utils/permissions/MediaLibraryPermissions.js +145 -0
  813. package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -0
  814. package/build/utils/permissions/galleryDisplayName.d.ts +8 -0
  815. package/build/utils/permissions/galleryDisplayName.d.ts.map +1 -0
  816. package/build/utils/permissions/galleryDisplayName.js +25 -0
  817. package/build/utils/permissions/galleryDisplayName.js.map +1 -0
  818. package/build/utils/speakerEmbedding.d.ts +8 -0
  819. package/build/utils/speakerEmbedding.d.ts.map +1 -0
  820. package/build/utils/speakerEmbedding.js +63 -0
  821. package/build/utils/speakerEmbedding.js.map +1 -0
  822. package/build/utils/storage/index.d.ts +3 -0
  823. package/build/utils/storage/index.d.ts.map +1 -0
  824. package/build/utils/storage/index.js +3 -0
  825. package/build/utils/storage/index.js.map +1 -0
  826. package/build/utils/storage/storage.d.ts +24 -0
  827. package/build/utils/storage/storage.d.ts.map +1 -0
  828. package/build/utils/storage/storage.js +85 -0
  829. package/build/utils/storage/storage.js.map +1 -0
  830. package/build/utils/storage/zip.d.ts +3 -0
  831. package/build/utils/storage/zip.d.ts.map +1 -0
  832. package/build/utils/storage/zip.js +14 -0
  833. package/build/utils/storage/zip.js.map +1 -0
  834. package/build/utils/timers/index.d.ts +3 -0
  835. package/build/utils/timers/index.d.ts.map +1 -0
  836. package/build/utils/timers/index.js +3 -0
  837. package/build/utils/timers/index.js.map +1 -0
  838. package/build/utils/timers/timers.d.ts +9 -0
  839. package/build/utils/timers/timers.d.ts.map +1 -0
  840. package/build/utils/timers/timers.js +142 -0
  841. package/build/utils/timers/timers.js.map +1 -0
  842. package/package.json +122 -0
  843. package/src/assets/silence.wav +0 -0
  844. package/src/devtools.ts +13 -0
  845. package/src/engine.ts +198 -0
  846. package/src/facades/dev.ts +213 -0
  847. package/src/facades/display.ts +17 -0
  848. package/src/facades/displayMirror.ts +33 -0
  849. package/src/facades/gallery.ts +69 -0
  850. package/src/facades/glasses.ts +219 -0
  851. package/src/facades/glassesSettings.ts +57 -0
  852. package/src/facades/glassesWifi.ts +68 -0
  853. package/src/facades/maps.ts +13 -0
  854. package/src/facades/memory.ts +46 -0
  855. package/src/facades/miniapps.ts +62 -0
  856. package/src/facades/notifications.ts +14 -0
  857. package/src/facades/ota.ts +177 -0
  858. package/src/facades/pairing.ts +329 -0
  859. package/src/facades/permissions.ts +165 -0
  860. package/src/facades/phoneNotifications.ts +41 -0
  861. package/src/facades/providerKeys.ts +31 -0
  862. package/src/facades/reports.ts +180 -0
  863. package/src/facades/session.ts +54 -0
  864. package/src/facades/settings.ts +57 -0
  865. package/src/facades/speakers.ts +152 -0
  866. package/src/facades/speech.ts +49 -0
  867. package/src/index.ts +214 -0
  868. package/src/internal.ts +155 -0
  869. package/src/runtime/bootstrap.ts +159 -0
  870. package/src/runtime/config.ts +155 -0
  871. package/src/runtime/scanQrSeam.ts +20 -0
  872. package/src/runtime/streamConfig.ts +34 -0
  873. package/src/services/AiTierResolution.ts +106 -0
  874. package/src/services/AppRegistry.ts +1245 -0
  875. package/src/services/AudioCloudUplink.ts +56 -0
  876. package/src/services/AudioPlaybackService.ts +873 -0
  877. package/src/services/AutomaticReportResult.ts +50 -0
  878. package/src/services/BlobStore.ts +823 -0
  879. package/src/services/CaptionsTesterReportService.ts +107 -0
  880. package/src/services/CloudAudioSubscriptionSync.ts +53 -0
  881. package/src/services/CloudClientService.ts +1031 -0
  882. package/src/services/CloudTranscriptE2EMetrics.ts +27 -0
  883. package/src/services/ConnectionCoordinator.ts +65 -0
  884. package/src/services/DevServerBridge.ts +334 -0
  885. package/src/services/DeviceEventRouter.ts +266 -0
  886. package/src/services/DeviceStoreHydration.ts +130 -0
  887. package/src/services/DisplayProcessor.ts +775 -0
  888. package/src/services/ForegroundLocationPermission.ts +24 -0
  889. package/src/services/GlassesReadiness.ts +103 -0
  890. package/src/services/GlassesSettingsSync.ts +140 -0
  891. package/src/services/GlassesStatusProjection.ts +73 -0
  892. package/src/services/HeadingService.ts +122 -0
  893. package/src/services/HotspotOtaTransport.ts +184 -0
  894. package/src/services/HotspotShutdown.ts +41 -0
  895. package/src/services/JSCrashController.ts +189 -0
  896. package/src/services/JSCrashloopReportService.ts +66 -0
  897. package/src/services/JSLogPipeline.ts +166 -0
  898. package/src/services/JSRouter.ts +555 -0
  899. package/src/services/LocalDisplayManager.ts +815 -0
  900. package/src/services/LocalMiniappDataMigration.ts +102 -0
  901. package/src/services/LocalMiniappRuntime.ts +5747 -0
  902. package/src/services/LocalMiniappStorage.ts +82 -0
  903. package/src/services/LocalMiniappUserIdentity.ts +79 -0
  904. package/src/services/LocalSttFallbackCoordinator.ts +247 -0
  905. package/src/services/MapboxTokenService.ts +118 -0
  906. package/src/services/MemoryCapture.ts +61 -0
  907. package/src/services/MemoryStore.ts +633 -0
  908. package/src/services/MicStateCoordinator.ts +259 -0
  909. package/src/services/MiniappEngine.ts +143 -0
  910. package/src/services/MiniappLauncher.ts +365 -0
  911. package/src/services/MiniappLiveness.ts +24 -0
  912. package/src/services/MiniappRunningRegistry.ts +57 -0
  913. package/src/services/NativeHttpResponse.ts +6 -0
  914. package/src/services/NativeNavigationService.ts +176 -0
  915. package/src/services/NavigationHandlers.ts +527 -0
  916. package/src/services/NavigationService.ts +926 -0
  917. package/src/services/NotificationsEmitter.ts +49 -0
  918. package/src/services/OfflineSpeechModelService.ts +168 -0
  919. package/src/services/OtaArtifactDownloader.ts +312 -0
  920. package/src/services/OtaInstallCoordinator.ts +1707 -0
  921. package/src/services/OtaService.ts +89 -0
  922. package/src/services/OtaUpdateCheckService.ts +550 -0
  923. package/src/services/PairingIdentity.ts +154 -0
  924. package/src/services/PhoneCalendarHelpers.ts +212 -0
  925. package/src/services/PhoneCalendarService.ts +61 -0
  926. package/src/services/PhoneCameraFovCoordinator.ts +210 -0
  927. package/src/services/PhoneLocationService.ts +120 -0
  928. package/src/services/PhoneNotificationsSync.ts +46 -0
  929. package/src/services/PhonePhotoCoordinator.ts +435 -0
  930. package/src/services/PhoneStreamCoordinator.ts +874 -0
  931. package/src/services/PhoneVideoCoordinator.ts +203 -0
  932. package/src/services/ProviderKeyValidation.ts +57 -0
  933. package/src/services/STTModelManager.ts +434 -0
  934. package/src/services/SceneRenderer.ts +320 -0
  935. package/src/services/SentenceTtsPipeline.ts +106 -0
  936. package/src/services/SpeakerIdModelManager.ts +151 -0
  937. package/src/services/SpeakerIdSync.ts +79 -0
  938. package/src/services/SpeakerLabelResolver.ts +140 -0
  939. package/src/services/SpeakerProfileStore.ts +265 -0
  940. package/src/services/SpeakerSegmentResolver.ts +194 -0
  941. package/src/services/StreamLifecycleController.ts +203 -0
  942. package/src/services/SupportProfileSync.ts +218 -0
  943. package/src/services/TTSModelManager.ts +466 -0
  944. package/src/services/TranscriptionRouting.ts +47 -0
  945. package/src/services/TtsTextSanitizer.ts +66 -0
  946. package/src/services/UIRouter.ts +250 -0
  947. package/src/services/WebviewBridge.ts +50 -0
  948. package/src/services/WifiAdbRequest.ts +53 -0
  949. package/src/services/asg/GalleryMediaIntegrityReportService.ts +72 -0
  950. package/src/services/asg/asgCameraApi.ts +1786 -0
  951. package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
  952. package/src/services/asg/cameraRollExportLedger.ts +122 -0
  953. package/src/services/asg/galleryMediaValidation.ts +185 -0
  954. package/src/services/asg/galleryNotices.ts +61 -0
  955. package/src/services/asg/galleryPathMigration.ts +22 -0
  956. package/src/services/asg/gallerySettingsService.ts +68 -0
  957. package/src/services/asg/gallerySyncNotifications.ts +235 -0
  958. package/src/services/asg/gallerySyncService.ts +2278 -0
  959. package/src/services/asg/galleryTransferLedger.ts +312 -0
  960. package/src/services/asg/localNetworkTransport.ts +169 -0
  961. package/src/services/asg/localStorageService.ts +652 -0
  962. package/src/services/asg/mediaProcessingQueue.ts +518 -0
  963. package/src/services/audioPlaybackAssets.ts +8 -0
  964. package/src/services/blobPaths.ts +86 -0
  965. package/src/services/cloudStreamApi.ts +142 -0
  966. package/src/services/effectiveCapabilities.ts +27 -0
  967. package/src/services/gallerySyncClock.ts +39 -0
  968. package/src/services/glassesClockSync.ts +115 -0
  969. package/src/services/manifestActions.ts +80 -0
  970. package/src/services/manifestVersionGate.ts +43 -0
  971. package/src/services/memoryStoreInstance.ts +70 -0
  972. package/src/services/navigation/roadNameResolver.ts +103 -0
  973. package/src/services/navigation/routesApiCodec.ts +69 -0
  974. package/src/services/otaDisplayState.ts +156 -0
  975. package/src/services/otaInstallPolicy.ts +132 -0
  976. package/src/services/otaLegacyMapping.ts +71 -0
  977. package/src/services/otaManifestUrl.ts +53 -0
  978. package/src/services/slimStreamStatus.ts +39 -0
  979. package/src/services/soniox/SonioxDirectService.ts +517 -0
  980. package/src/services/soniox/SonioxRealtimeClient.ts +349 -0
  981. package/src/services/soniox/SonioxTokenAssembler.ts +451 -0
  982. package/src/services/speakerProfileStoreInstance.ts +25 -0
  983. package/src/services/uiShim.ts +375 -0
  984. package/src/stores/apps.ts +626 -0
  985. package/src/stores/bluetoothSettingKeys.ts +35 -0
  986. package/src/stores/cloudClientStatus.ts +37 -0
  987. package/src/stores/connection.ts +69 -0
  988. package/src/stores/core.ts +32 -0
  989. package/src/stores/display.ts +121 -0
  990. package/src/stores/gallerySync.ts +384 -0
  991. package/src/stores/glasses.ts +314 -0
  992. package/src/stores/settings.ts +1299 -0
  993. package/src/stores/transcriptionDebug.ts +0 -0
  994. package/src/types/applet.ts +121 -0
  995. package/src/types/asg.ts +58 -0
  996. package/src/types/capabilities/even-realities-g1.ts +70 -0
  997. package/src/types/capabilities/even-realities-g2.ts +98 -0
  998. package/src/types/capabilities/mentra-display.ts +78 -0
  999. package/src/types/capabilities/mentra-live.ts +106 -0
  1000. package/src/types/capabilities/nimo.ts +84 -0
  1001. package/src/types/capabilities/none.ts +79 -0
  1002. package/src/types/capabilities/simulated-glasses.ts +95 -0
  1003. package/src/types/capabilities/vuzix-z100.ts +67 -0
  1004. package/src/types/enums.ts +27 -0
  1005. package/src/types/hardware.ts +220 -0
  1006. package/src/types/index.ts +38 -0
  1007. package/src/utils/GlobalEventEmitter.ts +15 -0
  1008. package/src/utils/cloudClient/RnUdpAdapter.ts +47 -0
  1009. package/src/utils/cloudClient/cloudSecureStore.ts +28 -0
  1010. package/src/utils/configuredDevHost.ts +17 -0
  1011. package/src/utils/debouncedPatch.ts +28 -0
  1012. package/src/utils/devLogging.ts +140 -0
  1013. package/src/utils/devMiniappLaunch.ts +196 -0
  1014. package/src/utils/diagnosticContext.ts +159 -0
  1015. package/src/utils/display/composer/ColumnComposer.ts +285 -0
  1016. package/src/utils/display/composer/index.ts +15 -0
  1017. package/src/utils/display/helpers/DisplayHelpers.ts +409 -0
  1018. package/src/utils/display/helpers/ScrollView.ts +326 -0
  1019. package/src/utils/display/helpers/index.ts +14 -0
  1020. package/src/utils/display/index.ts +273 -0
  1021. package/src/utils/display/measurer/TextMeasurer.ts +346 -0
  1022. package/src/utils/display/measurer/index.ts +21 -0
  1023. package/src/utils/display/measurer/script-detection.ts +218 -0
  1024. package/src/utils/display/profiles/g1.ts +236 -0
  1025. package/src/utils/display/profiles/g2.ts +39 -0
  1026. package/src/utils/display/profiles/index.ts +28 -0
  1027. package/src/utils/display/profiles/nex.ts +166 -0
  1028. package/src/utils/display/profiles/types.ts +132 -0
  1029. package/src/utils/display/profiles/z100.ts +198 -0
  1030. package/src/utils/display/scene/anchor.ts +39 -0
  1031. package/src/utils/display/scene/degrade.ts +80 -0
  1032. package/src/utils/display/scene/differ.ts +128 -0
  1033. package/src/utils/display/scene/index.ts +24 -0
  1034. package/src/utils/display/scene/process.ts +228 -0
  1035. package/src/utils/display/scene/store.ts +0 -0
  1036. package/src/utils/display/scene/types.ts +0 -0
  1037. package/src/utils/display/wrapper/TextWrapper.ts +546 -0
  1038. package/src/utils/display/wrapper/index.ts +15 -0
  1039. package/src/utils/display/wrapper/types.ts +102 -0
  1040. package/src/utils/e2eMetrics.ts +30 -0
  1041. package/src/utils/hardware/hardware.ts +171 -0
  1042. package/src/utils/hardware/index.ts +1 -0
  1043. package/src/utils/memory/search.ts +204 -0
  1044. package/src/utils/miniappDiagnostics.ts +226 -0
  1045. package/src/utils/miniappGlobals.ts +259 -0
  1046. package/src/utils/permissions/MediaLibraryPermissions.ts +161 -0
  1047. package/src/utils/permissions/galleryDisplayName.ts +28 -0
  1048. package/src/utils/speakerEmbedding.ts +58 -0
  1049. package/src/utils/storage/index.ts +2 -0
  1050. package/src/utils/storage/storage.ts +101 -0
  1051. package/src/utils/storage/zip.ts +13 -0
  1052. package/src/utils/timers/index.ts +2 -0
  1053. package/src/utils/timers/timers.ts +175 -0
@@ -0,0 +1,873 @@
1
+ import {createAudioPlayer, AudioPlayer, AudioStatus, setAudioModeAsync} from "expo-audio"
2
+ import BluetoothSdk from "@glassly/bluetooth-sdk/internal"
3
+ import {AppState, Platform} from "react-native"
4
+ import {BgTimer} from "../utils/timers"
5
+ import {setAudioCloudUplinkSuppressed} from "./AudioCloudUplink"
6
+ import {SILENT_AUDIO_SOURCE} from "./audioPlaybackAssets"
7
+
8
+ const RESTORE_GLASSES_VOLUME_AFTER_PLAYBACK = false
9
+
10
+ interface AudioPlayRequest {
11
+ requestId: string
12
+ audioUrl: string
13
+ appId?: string
14
+ volume?: number
15
+ stopOtherAudio?: boolean
16
+ /**
17
+ * Suppress microphone audio sent to cloud STT while this audio is audible.
18
+ * Opt-in and off by default: the suppression is global to the uplink, so a
19
+ * caller that sets this silences STT for every running app, not just itself.
20
+ * No platform path sets it today (see AudioCloudUplink and OS-1741).
21
+ */
22
+ suppressCloudUplink?: boolean
23
+ }
24
+
25
+ export type AudioPlaybackCompletionReason = "completed" | "interrupted" | "error"
26
+
27
+ type AudioPlaybackCompletion = (
28
+ requestId: string,
29
+ success: boolean,
30
+ error: string | null,
31
+ duration: number | null,
32
+ reason: AudioPlaybackCompletionReason,
33
+ ) => void
34
+
35
+ interface PlaybackState {
36
+ requestId: string
37
+ audioUrl: string
38
+ uplinkSuppressionId: string
39
+ appId?: string
40
+ startTime: number
41
+ completed: boolean // Guard against double callbacks
42
+ suppressCloudUplink: boolean
43
+ onComplete: AudioPlaybackCompletion
44
+ }
45
+
46
+ interface PendingPlaybackState {
47
+ cancelled: boolean
48
+ audioUrl: string
49
+ appId?: string
50
+ createdAt: number
51
+ }
52
+
53
+ /** Open request for a live PCM output stream (miniapp speaker.createStream). */
54
+ export interface AudioStreamOpenRequest {
55
+ streamId: string
56
+ appId: string
57
+ /** PCM sample rate in Hz (16000 / 24000 / 48000). */
58
+ sampleRate: number
59
+ /** Channel count. v1 is mono. */
60
+ channels: number
61
+ volume?: number
62
+ stopOtherAudio?: boolean
63
+ /**
64
+ * Called when the stream ends for any reason (drained after close, aborted,
65
+ * interrupted by other audio, or native error).
66
+ */
67
+ onEnded: (streamId: string, success: boolean, error: string | null, durationMs: number | null) => void
68
+ }
69
+
70
+ /** One live PCM stream session, backed by native streaming audio. */
71
+ interface StreamState {
72
+ streamId: string
73
+ appId: string
74
+ startTime: number
75
+ ended: boolean // Guard against double onEnded
76
+ onEnded: AudioStreamOpenRequest["onEnded"]
77
+ }
78
+
79
+ class AudioPlaybackService {
80
+ private static instance: AudioPlaybackService | null = null
81
+ // Reuse a single AudioPlayer to avoid AudioTrack exhaustion
82
+ // Creating new ExoPlayer instances per request leads to -12 ENOMEM errors
83
+ private player: AudioPlayer | null = null
84
+ // The source currently loaded into the reusable player. Keep object identity
85
+ // so a delayed tail cleanup from an older request cannot unload a newer one.
86
+ private loadedPlayback: PlaybackState | null = null
87
+ private currentPlayback: PlaybackState | null = null
88
+ // Requests that entered play() but have not yet reached the native player.
89
+ // Keeping these addressable prevents a cancelled request from starting after
90
+ // an async audio-mode or stream-cleanup step finishes.
91
+ private pendingPlaybacks = new Map<string, PendingPlaybackState>()
92
+ // Live PCM streams (speaker.createStream), keyed by streamId. The runtime
93
+ // enforces one per app; stopOtherAudio interrupts across apps.
94
+ private streams = new Map<string, StreamState>()
95
+ private audioModeConfigured: boolean = false
96
+ // Debounce timer for notifying native that audio stopped
97
+ // Prevents mic toggle flicker when playing back-to-back audio
98
+ // Uses BgTimer to work reliably when app is backgrounded on Android
99
+ private audioStopDebounceTimer: number | null = null
100
+ // Mentra Live's A2DP route may go idle between prompts. Keep a short warm
101
+ // window after actual audio so we only pre-roll the first sound after idle.
102
+ private audioRouteWarmUntil = 0
103
+ private audioRouteWarmupPromise: Promise<void> | null = null
104
+ // Playback that opted into suppression stays suppressed briefly while its
105
+ // A2DP tail drains. Track those completed sources so a later unsuppressed
106
+ // sound can resume listening immediately instead of inheriting that gate.
107
+ private tailUplinkSuppressions = new Set<string>()
108
+ // Original glasses media volume captured before we bump it for A2DP playback.
109
+ private glassesVolumeRestoreLevel: number | null = null
110
+ private static readonly AUDIO_STOP_DEBOUNCE_MS = 1500
111
+ private static readonly A2DP_TAIL_DRAIN_MS = 700
112
+ private static readonly AUDIO_ROUTE_WARM_WINDOW_MS = 1500
113
+ private static readonly AUDIO_ROUTE_PREWARM_MS = 200
114
+ private static readonly AUDIO_ROUTE_PREWARM_SAMPLE_RATE = 16_000
115
+ /** Break accidental same-app replay storms without affecting deliberate later replays. */
116
+ private static readonly DUPLICATE_PLAY_WINDOW_MS = 750
117
+ private static readonly AUDIO_ROUTE_PREWARM_PCM_BASE64 =
118
+ "AAAA".repeat(
119
+ Math.floor(
120
+ (AudioPlaybackService.AUDIO_ROUTE_PREWARM_MS * AudioPlaybackService.AUDIO_ROUTE_PREWARM_SAMPLE_RATE * 2) /
121
+ (1000 * 3),
122
+ ),
123
+ ) + "AA=="
124
+ /** If glasses report step volume at or below this, bump to FLOOR before A2DP playback. */
125
+ private static readonly GLASSES_VOLUME_LOW_THRESHOLD = 2
126
+ private static readonly GLASSES_VOLUME_FLOOR = 9
127
+
128
+ private constructor() {}
129
+
130
+ /**
131
+ * Configure audio mode for playback, re-asserting it on EVERY play.
132
+ *
133
+ * This must run before each play — not just once — because other parts of the
134
+ * app put the shared iOS AVAudioSession into a record-oriented category and
135
+ * never restore it. In particular the phone mic (PhoneMic.swift) switches the
136
+ * session to `.playAndRecord` (sometimes `.voiceChat`/earpiece routing) while
137
+ * capturing and only deactivates it on stop, leaving the category sticky. A
138
+ * miniapp like the Recorder records and then immediately plays back through
139
+ * this service; if we kept the old "configure once" guard, playback would land
140
+ * in the leftover `.playAndRecord` session and be inaudible on the phone
141
+ * speaker (the symptom: the progress bar runs but no sound comes out). Calling
142
+ * setAudioModeAsync with no `allowsRecording` maps to category `.playback`,
143
+ * reclaiming the speaker route. `audioModeConfigured` is kept only to gate the
144
+ * one-time log.
145
+ */
146
+ private async ensureAudioModeConfigured(): Promise<void> {
147
+ try {
148
+ await setAudioModeAsync({
149
+ shouldPlayInBackground: true,
150
+ playsInSilentMode: true,
151
+ interruptionMode: "duckOthers",
152
+ })
153
+ if (!this.audioModeConfigured) {
154
+ this.audioModeConfigured = true
155
+ console.log("AUDIO: Audio mode configured for playback")
156
+ }
157
+ } catch (error) {
158
+ console.error("AUDIO: Failed to configure audio mode:", error)
159
+ // Don't block playback if audio mode config fails
160
+ }
161
+ }
162
+
163
+ public static getInstance(): AudioPlaybackService {
164
+ if (!AudioPlaybackService.instance) {
165
+ AudioPlaybackService.instance = new AudioPlaybackService()
166
+ }
167
+ return AudioPlaybackService.instance
168
+ }
169
+
170
+ /**
171
+ * Ensure we have a reusable player instance
172
+ */
173
+ private ensurePlayer(): AudioPlayer {
174
+ if (!this.player) {
175
+ console.log("AUDIO: Creating reusable AudioPlayer instance")
176
+ this.player = createAudioPlayer(null)
177
+
178
+ // Add status listener once - it will handle all playback completions
179
+ this.player.addListener("playbackStatusUpdate", (status: AudioStatus) => {
180
+ this.onPlaybackStatusUpdate(status)
181
+ })
182
+ }
183
+ return this.player
184
+ }
185
+
186
+ private markAudioRouteWarm(): void {
187
+ this.audioRouteWarmUntil = Date.now() + AudioPlaybackService.AUDIO_ROUTE_WARM_WINDOW_MS
188
+ }
189
+
190
+ private isAudioRouteWarm(): boolean {
191
+ return this.currentPlayback !== null || this.streams.size > 0 || Date.now() < this.audioRouteWarmUntil
192
+ }
193
+
194
+ /**
195
+ * Wake a cold Android A2DP route with silent PCM before a user-facing sound.
196
+ *
197
+ * Do not call pcmStreamClose here: some Bluetooth routes do not advance an
198
+ * idle AudioTrack playback head, so close waits for its drain timeout. After
199
+ * exactly 200ms of silence we abort the stream instead, which releases the
200
+ * pre-roll immediately and lets the real URL playback begin.
201
+ */
202
+ private async prewarmAudioRouteIfCold(): Promise<void> {
203
+ if (Platform.OS !== "android" || this.isAudioRouteWarm()) return
204
+ // This silent PCM pre-roll is only an anti-clipping optimization. Some
205
+ // Android devices defer opening its AudioTrack until the host Activity
206
+ // resumes even though the real URL player supports background playback.
207
+ // Never let that optional pre-roll block a glasses-initiated prompt.
208
+ if (AppState.currentState !== "active") {
209
+ console.log(`AUDIO: Skipping cold-route prewarm while app is ${AppState.currentState}`)
210
+ return
211
+ }
212
+ if (this.audioRouteWarmupPromise) return this.audioRouteWarmupPromise
213
+
214
+ const streamId = `audio-route-prewarm-${Date.now()}-${Math.random().toString(36).slice(2)}`
215
+ const warmup = (async () => {
216
+ let opened = false
217
+ const startedAt = Date.now()
218
+ try {
219
+ console.log(`AUDIO: Cold route; prewarming with ${AudioPlaybackService.AUDIO_ROUTE_PREWARM_MS}ms silence`)
220
+ await BluetoothSdk.pcmStreamOpen(streamId, AudioPlaybackService.AUDIO_ROUTE_PREWARM_SAMPLE_RATE, 1, 1)
221
+ opened = true
222
+ await BluetoothSdk.pcmStreamWrite(streamId, AudioPlaybackService.AUDIO_ROUTE_PREWARM_PCM_BASE64)
223
+ await new Promise<void>((resolve) => {
224
+ BgTimer.setTimeout(resolve, AudioPlaybackService.AUDIO_ROUTE_PREWARM_MS)
225
+ })
226
+ await BluetoothSdk.pcmStreamAbort(streamId)
227
+ opened = false
228
+ this.markAudioRouteWarm()
229
+ console.log(`AUDIO: Cold-route prewarm completed in ${Date.now() - startedAt}ms`)
230
+ } catch (error) {
231
+ console.warn("AUDIO: Cold-route prewarm failed; continuing with requested audio:", error)
232
+ } finally {
233
+ if (opened) await BluetoothSdk.pcmStreamAbort(streamId).catch(() => {})
234
+ }
235
+ })()
236
+ this.audioRouteWarmupPromise = warmup
237
+ try {
238
+ await warmup
239
+ } finally {
240
+ if (this.audioRouteWarmupPromise === warmup) this.audioRouteWarmupPromise = null
241
+ }
242
+ }
243
+
244
+ private async getGlassesMediaVolumeWithTiming() {
245
+ const startedAt = Date.now()
246
+ try {
247
+ const result = await BluetoothSdk.getGlassesMediaVolume()
248
+ console.log(`AUDIO: Glasses media volume read completed in ${Date.now() - startedAt}ms`)
249
+ return result
250
+ } catch (error) {
251
+ console.warn(
252
+ `AUDIO: Glasses media volume read failed after ${Date.now() - startedAt}ms:`,
253
+ error instanceof Error ? error.message : String(error),
254
+ )
255
+ throw error
256
+ }
257
+ }
258
+
259
+ private async setGlassesMediaVolumeWithTiming(level: number) {
260
+ const startedAt = Date.now()
261
+ try {
262
+ const result = await BluetoothSdk.setGlassesMediaVolume(level)
263
+ console.log(`AUDIO: Glasses media volume set(${level}) completed in ${Date.now() - startedAt}ms`)
264
+ return result
265
+ } catch (error) {
266
+ console.warn(
267
+ `AUDIO: Glasses media volume set(${level}) failed after ${Date.now() - startedAt}ms:`,
268
+ error instanceof Error ? error.message : String(error),
269
+ )
270
+ throw error
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Mentra Live: raise glasses media volume over BLE when it is very low so A2DP prompts are audible.
276
+ * Fail-open on unsupported devices, timeouts, or errors.
277
+ */
278
+ private async ensureGlassesMediaVolumeForA2dp(playback: PlaybackState): Promise<void> {
279
+ if (this.glassesVolumeRestoreLevel !== null) {
280
+ console.log(
281
+ `AUDIO: Keeping bumped glasses media volume at ${AudioPlaybackService.GLASSES_VOLUME_FLOOR} during ongoing playback`,
282
+ )
283
+ return
284
+ }
285
+
286
+ try {
287
+ const raw = await this.getGlassesMediaVolumeWithTiming()
288
+ const level = Number(raw.level)
289
+ const statusCode = Number(raw.statusCode)
290
+ if (!Number.isFinite(level)) {
291
+ console.log("AUDIO: Received glasses media volume response without numeric level:", JSON.stringify(raw))
292
+ return
293
+ }
294
+ const k900S = Number.isFinite(statusCode) && statusCode >= 0 ? ` K900_S=${statusCode}` : ""
295
+ console.log(`AUDIO: Glasses media step volume (wearable knob, 0-15 scale): ${level}/15.${k900S}`)
296
+ if (level > AudioPlaybackService.GLASSES_VOLUME_LOW_THRESHOLD) {
297
+ return
298
+ }
299
+ if (this.currentPlayback !== playback || playback.completed) {
300
+ console.log("AUDIO: Skipping glasses volume bump; playback already ended")
301
+ return
302
+ }
303
+ console.log(`AUDIO: Raising glasses media volume (was ${level})`)
304
+ await this.setGlassesMediaVolumeWithTiming(AudioPlaybackService.GLASSES_VOLUME_FLOOR)
305
+ if (this.currentPlayback === playback && !playback.completed) {
306
+ this.glassesVolumeRestoreLevel = level
307
+ } else if (RESTORE_GLASSES_VOLUME_AFTER_PLAYBACK) {
308
+ console.log("AUDIO: Restoring glasses volume immediately; playback ended during volume bump")
309
+ await this.setGlassesMediaVolumeWithTiming(level)
310
+ } else {
311
+ console.log("AUDIO: Leaving bumped glasses media volume unchanged after playback")
312
+ }
313
+ } catch (e) {
314
+ const msg = e instanceof Error ? e.message : String(e)
315
+ console.warn("AUDIO: Skipping glasses volume bump:", msg)
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Restore the user's original glasses media step volume after A2DP playback finishes.
321
+ */
322
+ private async restoreGlassesMediaVolume(): Promise<void> {
323
+ const restoreLevel = this.glassesVolumeRestoreLevel
324
+ if (restoreLevel === null) {
325
+ return
326
+ }
327
+ if (!RESTORE_GLASSES_VOLUME_AFTER_PLAYBACK) {
328
+ this.glassesVolumeRestoreLevel = null
329
+ console.log("AUDIO: Leaving bumped glasses media volume unchanged after playback")
330
+ return
331
+ }
332
+
333
+ try {
334
+ console.log(`AUDIO: Restoring glasses media volume to ${restoreLevel}`)
335
+ await this.setGlassesMediaVolumeWithTiming(restoreLevel)
336
+ } catch (e) {
337
+ const msg = e instanceof Error ? e.message : String(e)
338
+ console.warn(`AUDIO: Failed to restore glasses volume to ${restoreLevel}:`, msg)
339
+ } finally {
340
+ this.glassesVolumeRestoreLevel = null
341
+ }
342
+ }
343
+
344
+ private unloadPlaybackSource(playback: PlaybackState, reason: string): void {
345
+ if (this.loadedPlayback !== playback) return
346
+ const player = this.player
347
+ if (!player) {
348
+ this.loadedPlayback = null
349
+ return
350
+ }
351
+
352
+ try {
353
+ player.pause()
354
+ } catch (e) {
355
+ console.warn(`AUDIO: Error pausing ${playback.requestId} during ${reason}:`, e)
356
+ }
357
+
358
+ try {
359
+ // replace(null) fails native argument casting on iOS, while remove()
360
+ // destroys the ExoPlayer that Android must reuse to avoid AudioTrack
361
+ // exhaustion. Replacing with bundled silence detaches the previous media
362
+ // item on both platforms and leaves the native player alive.
363
+ player.replace(SILENT_AUDIO_SOURCE)
364
+ console.log(`AUDIO: Cleared source for ${playback.requestId} during ${reason}`)
365
+ } catch (e) {
366
+ console.warn(`AUDIO: Error clearing ${playback.requestId} during ${reason}:`, e)
367
+ } finally {
368
+ if (this.loadedPlayback === playback) this.loadedPlayback = null
369
+ }
370
+ }
371
+
372
+ private clearFinishedPlayerAfterTail(playback: PlaybackState): void {
373
+ if (playback.suppressCloudUplink) {
374
+ this.tailUplinkSuppressions.add(playback.uplinkSuppressionId)
375
+ }
376
+ BgTimer.setTimeout(() => {
377
+ // ExoPlayer's completion event precedes the final A2DP audio reaching the
378
+ // glasses. Keep cloud STT gated until that audible tail has drained, then
379
+ // accept fresh microphone audio immediately without restarting LC3.
380
+ if (playback.suppressCloudUplink && this.tailUplinkSuppressions.delete(playback.uplinkSuppressionId)) {
381
+ setAudioCloudUplinkSuppressed(playback.uplinkSuppressionId, false)
382
+ }
383
+ this.unloadPlaybackSource(playback, `${AudioPlaybackService.A2DP_TAIL_DRAIN_MS}ms A2DP tail drain`)
384
+ }, AudioPlaybackService.A2DP_TAIL_DRAIN_MS)
385
+ }
386
+
387
+ private releaseTailUplinkSuppressions(): void {
388
+ for (const sourceId of this.tailUplinkSuppressions) {
389
+ setAudioCloudUplinkSuppressed(sourceId, false)
390
+ }
391
+ this.tailUplinkSuppressions.clear()
392
+ }
393
+
394
+ /**
395
+ * Play audio from a URL.
396
+ * Returns a promise that resolves with playback result when audio finishes or errors.
397
+ */
398
+ public async play(request: AudioPlayRequest, onComplete: AudioPlaybackCompletion): Promise<void> {
399
+ const {requestId, audioUrl, appId, volume = 1.0, stopOtherAudio = true, suppressCloudUplink = false} = request
400
+ const now = Date.now()
401
+ const activeDuplicate =
402
+ this.currentPlayback &&
403
+ !this.currentPlayback.completed &&
404
+ this.currentPlayback.appId === appId &&
405
+ this.currentPlayback.audioUrl === audioUrl &&
406
+ now - this.currentPlayback.startTime < AudioPlaybackService.DUPLICATE_PLAY_WINDOW_MS
407
+ const pendingDuplicate = [...this.pendingPlaybacks.values()].some(
408
+ (candidate) =>
409
+ !candidate.cancelled &&
410
+ candidate.appId === appId &&
411
+ candidate.audioUrl === audioUrl &&
412
+ now - candidate.createdAt < AudioPlaybackService.DUPLICATE_PLAY_WINDOW_MS,
413
+ )
414
+ if (activeDuplicate || pendingDuplicate) {
415
+ console.warn(`AUDIO: Suppressed duplicate play request ${requestId}${appId ? ` from ${appId}` : ""}`)
416
+ onComplete(requestId, false, "Duplicate audio request suppressed", 0, "error")
417
+ return
418
+ }
419
+
420
+ const pending: PendingPlaybackState = {cancelled: false, audioUrl, appId, createdAt: now}
421
+ this.pendingPlaybacks.set(requestId, pending)
422
+
423
+ console.log(`AUDIO: Play request ${requestId}${appId ? ` from ${appId}` : ""}: ${audioUrl}`)
424
+
425
+ try {
426
+ // Ensure audio mode is configured for background playback
427
+ await this.ensureAudioModeConfigured()
428
+ if (pending.cancelled) {
429
+ onComplete(requestId, true, null, 0, "interrupted")
430
+ return
431
+ }
432
+ await this.prewarmAudioRouteIfCold()
433
+ if (pending.cancelled) {
434
+ onComplete(requestId, true, null, 0, "interrupted")
435
+ return
436
+ }
437
+
438
+ // URL playback reuses one native player, so replacing its source always
439
+ // interrupts the previous URL even when stopOtherAudio is false. Notify
440
+ // that request before replacing it so its promise cannot hang. The option
441
+ // still controls whether separate PCM streams are interrupted below.
442
+ if (this.currentPlayback && !this.currentPlayback.completed) {
443
+ console.log(`AUDIO: Interrupting current URL playback for new request`)
444
+ this.interruptCurrentPlayback(true)
445
+ }
446
+ // Live PCM streams count as "other audio" too.
447
+ if (stopOtherAudio) {
448
+ await this.abortAllStreams()
449
+ }
450
+ if (pending.cancelled) {
451
+ onComplete(requestId, true, null, 0, "interrupted")
452
+ return
453
+ }
454
+
455
+ if (!suppressCloudUplink) {
456
+ this.releaseTailUplinkSuppressions()
457
+ }
458
+
459
+ // Get or create the reusable player
460
+ const player = this.ensurePlayer()
461
+
462
+ // Set volume
463
+ player.volume = Math.max(0, Math.min(1, volume))
464
+
465
+ // Store the new playback state
466
+ const playback: PlaybackState = {
467
+ requestId,
468
+ audioUrl,
469
+ uplinkSuppressionId: `url:${requestId}`,
470
+ appId,
471
+ startTime: Date.now(),
472
+ completed: false,
473
+ suppressCloudUplink,
474
+ onComplete,
475
+ }
476
+ this.currentPlayback = playback
477
+ this.pendingPlaybacks.delete(requestId)
478
+ this.markAudioRouteWarm()
479
+ if (playback.suppressCloudUplink) {
480
+ setAudioCloudUplinkSuppressed(playback.uplinkSuppressionId, true)
481
+ }
482
+
483
+ // Replace the source and play
484
+ // Using replace() reuses the existing ExoPlayer/AudioTrack instead of creating new ones
485
+ player.replace({uri: audioUrl})
486
+ this.loadedPlayback = playback
487
+ player.play()
488
+
489
+ // Mentra Live volume reads can block up to 5s when the glasses don't
490
+ // answer. Do not put that in front of playback; guard it against late
491
+ // completion so a stale volume response cannot bump after this request is
492
+ // already over.
493
+ void this.ensureGlassesMediaVolumeForA2dp(playback)
494
+
495
+ // Notify native that our app is playing audio
496
+ // Used to suspend LC3 mic during audio playback to avoid MCU overload
497
+ // Cancel any pending "stop" notification first (handles back-to-back audio)
498
+ if (this.audioStopDebounceTimer !== null) {
499
+ BgTimer.clearTimeout(this.audioStopDebounceTimer)
500
+ this.audioStopDebounceTimer = null
501
+ }
502
+ BluetoothSdk.setOwnAppAudioPlaying(true).catch((e) => {
503
+ console.warn("AUDIO: Failed to notify native of audio start:", e)
504
+ })
505
+
506
+ console.log(`AUDIO: Started playback for ${requestId}`)
507
+ } catch (error) {
508
+ if (suppressCloudUplink) {
509
+ setAudioCloudUplinkSuppressed(`url:${requestId}`, false)
510
+ }
511
+ const failedPlayback = this.currentPlayback?.requestId === requestId ? this.currentPlayback : null
512
+ if (failedPlayback) {
513
+ failedPlayback.completed = true
514
+ this.currentPlayback = null
515
+ this.unloadPlaybackSource(failedPlayback, "playback start failure")
516
+ }
517
+ if (pending.cancelled) {
518
+ onComplete(requestId, true, null, 0, "interrupted")
519
+ return
520
+ }
521
+ const errorMessage = error instanceof Error ? error.message : "Unknown error loading audio"
522
+ console.error(`AUDIO: Failed to play ${requestId}:`, errorMessage)
523
+ void this.restoreGlassesMediaVolume()
524
+ onComplete(requestId, false, errorMessage, null, "error")
525
+ } finally {
526
+ if (this.pendingPlaybacks.get(requestId) === pending) {
527
+ this.pendingPlaybacks.delete(requestId)
528
+ }
529
+ }
530
+ }
531
+
532
+ /**
533
+ * Cancel one URL playback without touching audio owned by another request.
534
+ * Pending requests are prevented from reaching the native player; active
535
+ * requests are paused synchronously before their completion callback fires.
536
+ */
537
+ public cancelPlayback(requestId: string): void {
538
+ const pending = this.pendingPlaybacks.get(requestId)
539
+ if (pending) pending.cancelled = true
540
+
541
+ if (this.currentPlayback?.requestId === requestId && !this.currentPlayback.completed) {
542
+ this.interruptCurrentPlayback()
543
+ }
544
+ }
545
+
546
+ /**
547
+ * Interrupt current playback and notify its callback
548
+ */
549
+ private interruptCurrentPlayback(preserveGlassesMediaVolume: boolean = false): void {
550
+ if (!this.currentPlayback || this.currentPlayback.completed) return
551
+
552
+ const playback = this.currentPlayback
553
+ playback.completed = true
554
+ this.currentPlayback = null
555
+ if (playback.suppressCloudUplink) {
556
+ setAudioCloudUplinkSuppressed(playback.uplinkSuppressionId, false)
557
+ }
558
+ this.markAudioRouteWarm()
559
+
560
+ // Pausing alone leaves the URI available to OS/Bluetooth media Play.
561
+ // Unload it unless a newer request has already replaced this source.
562
+ this.unloadPlaybackSource(playback, "interruption")
563
+
564
+ // Notify native that our app stopped playing audio (debounced)
565
+ this.notifyAudioStopDebounced()
566
+ if (!preserveGlassesMediaVolume) {
567
+ void this.restoreGlassesMediaVolume()
568
+ }
569
+
570
+ // Notify that playback was interrupted
571
+ const elapsedMs = Date.now() - playback.startTime
572
+ playback.onComplete(playback.requestId, true, null, elapsedMs, "interrupted")
573
+ console.log(`AUDIO: Interrupted ${playback.requestId} after ${elapsedMs}ms`)
574
+ }
575
+
576
+ /**
577
+ * Handle playback status updates from expo-audio
578
+ */
579
+ private onPlaybackStatusUpdate(status: AudioStatus): void {
580
+ const playback = this.currentPlayback
581
+
582
+ // Guard against callbacks for unknown or completed playbacks
583
+ if (!playback || playback.completed) {
584
+ return
585
+ }
586
+
587
+ // Check if playback finished
588
+ if (status.didJustFinish) {
589
+ const durationMs = (status.duration || 0) * 1000 // expo-audio uses seconds
590
+ console.log(`AUDIO: Playback finished for ${playback.requestId}, duration: ${durationMs}ms`)
591
+ playback.completed = true
592
+
593
+ // ExoPlayer can report finished before an A2DP sink has audibly drained
594
+ // the last buffered audio. Pausing immediately can clip the tail on
595
+ // Mentra Live; defer cleanup and guard it against a newer loaded source.
596
+ this.clearFinishedPlayerAfterTail(playback)
597
+
598
+ this.currentPlayback = null
599
+ playback.onComplete(playback.requestId, true, null, durationMs, "completed")
600
+ this.markAudioRouteWarm()
601
+
602
+ // Notify native that our app stopped playing audio (debounced)
603
+ this.notifyAudioStopDebounced()
604
+ void this.restoreGlassesMediaVolume()
605
+ return
606
+ }
607
+
608
+ // Detect silent playback failures: expo-audio doesn't surface errors to JS,
609
+ // so when ExoPlayer fails to load/play a URL (network error, HTTP 500, etc.),
610
+ // the player state goes to "idle" with nothing loaded and no buffering.
611
+ // We wait 1500ms after play() to avoid false positives during initial load.
612
+ if (status.playbackState === "idle" && !status.isBuffering && !status.isLoaded) {
613
+ const elapsedMs = Date.now() - playback.startTime
614
+ if (elapsedMs > 1500) {
615
+ console.error(`AUDIO: Playback failed for ${playback.requestId} (player went idle after ${elapsedMs}ms)`)
616
+ playback.completed = true
617
+ this.currentPlayback = null
618
+ if (playback.suppressCloudUplink) {
619
+ setAudioCloudUplinkSuppressed(playback.uplinkSuppressionId, false)
620
+ }
621
+ this.unloadPlaybackSource(playback, "playback failure")
622
+ playback.onComplete(playback.requestId, false, "Playback failed (player went idle)", null, "error")
623
+ this.markAudioRouteWarm()
624
+ this.notifyAudioStopDebounced()
625
+ void this.restoreGlassesMediaVolume()
626
+ }
627
+ }
628
+ }
629
+
630
+ /**
631
+ * Notify native that audio stopped, with debouncing to prevent mic toggle flicker
632
+ * when playing back-to-back audio files
633
+ */
634
+ private notifyAudioStopDebounced(): void {
635
+ // Clear any existing timer
636
+ if (this.audioStopDebounceTimer !== null) {
637
+ BgTimer.clearTimeout(this.audioStopDebounceTimer)
638
+ }
639
+
640
+ // Set a new timer - if new audio starts within this window, the timer gets cancelled
641
+ // Uses BgTimer to work reliably when app is backgrounded on Android
642
+ this.audioStopDebounceTimer = BgTimer.setTimeout(() => {
643
+ this.audioStopDebounceTimer = null
644
+ // URL playback and live PCM streams may overlap when stopOtherAudio is false.
645
+ // A URL that ends must not clear the native playback signal while another
646
+ // source is still active, or the mic watchdog can interrupt that source.
647
+ if (this.isPlaying()) return
648
+ BluetoothSdk.setOwnAppAudioPlaying(false).catch((e) => {
649
+ console.warn("AUDIO: Failed to notify native of audio stop:", e)
650
+ })
651
+ }, AudioPlaybackService.AUDIO_STOP_DEBOUNCE_MS)
652
+ }
653
+
654
+ // ── live PCM output streams (miniapp speaker.createStream) ────────────────
655
+
656
+ /**
657
+ * Open a live PCM stream session. Chunks are pushed with writeStreamChunk
658
+ * into native streaming audio (AudioTrack on Android, AVAudioEngine on iOS),
659
+ * following the media route such as A2DP to connected glasses.
660
+ */
661
+ public async openStream(request: AudioStreamOpenRequest): Promise<void> {
662
+ const {streamId, appId, sampleRate, channels, volume = 1.0, stopOtherAudio = true} = request
663
+ console.log(`AUDIO: Stream open ${streamId} from ${appId}: rate=${sampleRate} ch=${channels}`)
664
+
665
+ await this.ensureAudioModeConfigured()
666
+ await this.prewarmAudioRouteIfCold()
667
+
668
+ if (stopOtherAudio) {
669
+ if (this.currentPlayback && !this.currentPlayback.completed) {
670
+ console.log("AUDIO: Interrupting current playback for new stream")
671
+ this.interruptCurrentPlayback(true)
672
+ }
673
+ await this.abortAllStreams(streamId)
674
+ }
675
+
676
+ await BluetoothSdk.pcmStreamOpen(streamId, sampleRate, channels, Math.max(0, Math.min(1, volume)))
677
+ this.releaseTailUplinkSuppressions()
678
+
679
+ const stream: StreamState = {
680
+ streamId,
681
+ appId,
682
+ startTime: Date.now(),
683
+ ended: false,
684
+ onEnded: request.onEnded,
685
+ }
686
+ this.streams.set(streamId, stream)
687
+ this.markAudioRouteWarm()
688
+
689
+ // Cancel any pending "stopped" notification and mark our app as playing
690
+ // audio. PCM streams intentionally do not suppress cloud STT.
691
+ if (this.audioStopDebounceTimer !== null) {
692
+ BgTimer.clearTimeout(this.audioStopDebounceTimer)
693
+ this.audioStopDebounceTimer = null
694
+ }
695
+ BluetoothSdk.setOwnAppAudioPlaying(true).catch((e) => {
696
+ console.warn("AUDIO: Failed to notify native of stream audio start:", e)
697
+ })
698
+
699
+ // Guarded against the stream ending mid-read, same as the play() path.
700
+ void this.ensureGlassesMediaVolumeForA2dpStream(stream)
701
+ }
702
+
703
+ /**
704
+ * Append base64 PCM to an open stream. Resolves with the host-side backlog
705
+ * in ms; the native write blocks while the backlog is above the
706
+ * backpressure ceiling, so awaited writes self-throttle to realtime.
707
+ */
708
+ public async writeStreamChunk(streamId: string, base64: string): Promise<{bufferedMs: number}> {
709
+ const stream = this.streams.get(streamId)
710
+ if (!stream || stream.ended) {
711
+ throw new Error(`stream ${streamId} is not open`)
712
+ }
713
+ try {
714
+ return await BluetoothSdk.pcmStreamWrite(streamId, base64)
715
+ } catch (error) {
716
+ const message = error instanceof Error ? error.message : String(error)
717
+ this.endStream(stream, false, message, Date.now() - stream.startTime)
718
+ throw error
719
+ }
720
+ }
721
+
722
+ /** Drain the backlog, then finish. Resolves with the total played duration. */
723
+ public async closeStream(streamId: string): Promise<{durationMs?: number}> {
724
+ const stream = this.streams.get(streamId)
725
+ if (!stream || stream.ended) {
726
+ throw new Error(`stream ${streamId} is not open`)
727
+ }
728
+ try {
729
+ const result = await BluetoothSdk.pcmStreamClose(streamId)
730
+ this.endStream(stream, true, null, result?.durationMs ?? Date.now() - stream.startTime)
731
+ return result ?? {}
732
+ } catch (error) {
733
+ const message = error instanceof Error ? error.message : String(error)
734
+ this.endStream(stream, false, message, Date.now() - stream.startTime)
735
+ throw error
736
+ }
737
+ }
738
+
739
+ /** Stop immediately, dropping the backlog. Safe on unknown/ended ids. */
740
+ public async abortStream(streamId: string): Promise<void> {
741
+ const stream = this.streams.get(streamId)
742
+ await BluetoothSdk.pcmStreamAbort(streamId).catch((e) => {
743
+ console.warn(`AUDIO: Stream abort ${streamId} native call failed:`, e)
744
+ })
745
+ if (stream) {
746
+ this.endStream(stream, true, null, Date.now() - stream.startTime)
747
+ }
748
+ }
749
+
750
+ /** Abort every active stream (optionally sparing one about to replace them). */
751
+ private async abortAllStreams(exceptStreamId?: string): Promise<void> {
752
+ const streamIds = [...this.streams.values()]
753
+ .filter((stream) => stream.streamId !== exceptStreamId)
754
+ .map((stream) => stream.streamId)
755
+ await Promise.all(streamIds.map((streamId) => this.abortStream(streamId)))
756
+ }
757
+
758
+ /** Terminal bookkeeping for a stream: dedup, unregister, notify. */
759
+ private endStream(stream: StreamState, success: boolean, error: string | null, durationMs: number | null): void {
760
+ if (stream.ended) return
761
+ stream.ended = true
762
+ this.streams.delete(stream.streamId)
763
+ this.markAudioRouteWarm()
764
+ // Only signal "audio stopped" when nothing else is making noise.
765
+ if (this.streams.size === 0 && (!this.currentPlayback || this.currentPlayback.completed)) {
766
+ this.notifyAudioStopDebounced()
767
+ void this.restoreGlassesMediaVolume()
768
+ }
769
+ stream.onEnded(stream.streamId, success, error, durationMs)
770
+ }
771
+
772
+ /** Stream twin of ensureGlassesMediaVolumeForA2dp, guarded by stream.ended. */
773
+ private async ensureGlassesMediaVolumeForA2dpStream(stream: StreamState): Promise<void> {
774
+ if (this.glassesVolumeRestoreLevel !== null) return
775
+ try {
776
+ const raw = await this.getGlassesMediaVolumeWithTiming()
777
+ const level = Number(raw.level)
778
+ if (!Number.isFinite(level) || level > AudioPlaybackService.GLASSES_VOLUME_LOW_THRESHOLD) return
779
+ if (stream.ended) return
780
+ console.log(`AUDIO: Raising glasses media volume for stream (was ${level})`)
781
+ await this.setGlassesMediaVolumeWithTiming(AudioPlaybackService.GLASSES_VOLUME_FLOOR)
782
+ if (!stream.ended) {
783
+ this.glassesVolumeRestoreLevel = level
784
+ } else {
785
+ await this.setGlassesMediaVolumeWithTiming(level)
786
+ }
787
+ } catch (e) {
788
+ console.warn("AUDIO: Skipping glasses volume bump for stream:", e instanceof Error ? e.message : String(e))
789
+ }
790
+ }
791
+
792
+ /**
793
+ * Stop playback for a specific app.
794
+ * If appId is not provided, stops all playback.
795
+ */
796
+ public async stopForApp(appId?: string): Promise<void> {
797
+ // Abort this app's live PCM streams too (miniapp stop/disconnect path).
798
+ const streamIds = [...this.streams.values()]
799
+ .filter((stream) => !appId || stream.appId === appId)
800
+ .map((stream) => stream.streamId)
801
+ await Promise.all(streamIds.map((streamId) => this.abortStream(streamId)))
802
+
803
+ if (!this.currentPlayback || this.currentPlayback.completed) return
804
+
805
+ if (!appId || this.currentPlayback.appId === appId) {
806
+ console.log(`AUDIO: Stopping playback for app ${appId || "(all)"}`)
807
+ this.interruptCurrentPlayback()
808
+ }
809
+ }
810
+
811
+ /**
812
+ * Stop all audio playback
813
+ */
814
+ public async stopAll(): Promise<void> {
815
+ await this.abortAllStreams()
816
+ if (this.currentPlayback && !this.currentPlayback.completed) {
817
+ console.log("AUDIO: Stopping all playback")
818
+ this.interruptCurrentPlayback()
819
+ }
820
+ }
821
+
822
+ /**
823
+ * Check if audio is currently playing
824
+ */
825
+ public isPlaying(): boolean {
826
+ return (this.currentPlayback !== null && !this.currentPlayback.completed) || this.streams.size > 0
827
+ }
828
+
829
+ /**
830
+ * Get current playback app IDs (all active)
831
+ */
832
+ public getActiveAppIds(): string[] {
833
+ const appIds = new Set<string>()
834
+ if (this.currentPlayback && !this.currentPlayback.completed && this.currentPlayback.appId) {
835
+ appIds.add(this.currentPlayback.appId)
836
+ }
837
+ for (const stream of this.streams.values()) appIds.add(stream.appId)
838
+ return [...appIds]
839
+ }
840
+
841
+ /**
842
+ * Get number of active playbacks
843
+ */
844
+ public getActiveCount(): number {
845
+ return (this.currentPlayback && !this.currentPlayback.completed ? 1 : 0) + this.streams.size
846
+ }
847
+
848
+ /**
849
+ * Release the player entirely (call when app is shutting down)
850
+ */
851
+ public release(): void {
852
+ void this.abortAllStreams()
853
+ if (this.currentPlayback && !this.currentPlayback.completed) {
854
+ this.interruptCurrentPlayback()
855
+ } else {
856
+ void this.restoreGlassesMediaVolume()
857
+ }
858
+
859
+ if (this.player) {
860
+ try {
861
+ this.player.remove()
862
+ console.log("AUDIO: Released AudioPlayer")
863
+ } catch (error) {
864
+ console.error("AUDIO: Error releasing player:", error)
865
+ }
866
+ this.player = null
867
+ this.loadedPlayback = null
868
+ }
869
+ }
870
+ }
871
+
872
+ const audioPlaybackService = AudioPlaybackService.getInstance()
873
+ export default audioPlaybackService