@glassly/bluetooth-sdk 0.1.0-dev.100

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 (553) hide show
  1. package/README.md +563 -0
  2. package/android/build.gradle +450 -0
  3. package/android/gradle.properties.example +9 -0
  4. package/android/lc3Lib/CMakeLists.txt +6 -0
  5. package/android/lc3Lib/build.gradle +212 -0
  6. package/android/lc3Lib/proguard-rules.pro +33 -0
  7. package/android/lc3Lib/src/main/AndroidManifest.xml +2 -0
  8. package/android/lc3Lib/src/main/cpp/CMakeLists.txt +8 -0
  9. package/android/lc3Lib/src/main/cpp/google_opus_stuff/CMakeLists.txt +30 -0
  10. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/CMakeLists.txt +7 -0
  11. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.cc +96 -0
  12. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.h +53 -0
  13. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/Makefile.am +6 -0
  14. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h +26 -0
  15. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h.in +26 -0
  16. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/ogg.h +209 -0
  17. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/os_types.h +158 -0
  18. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus.h +981 -0
  19. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_custom.h +342 -0
  20. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_defines.h +799 -0
  21. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_multistream.h +660 -0
  22. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_projection.h +568 -0
  23. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_types.h +166 -0
  24. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.cc +268 -0
  25. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.h +115 -0
  26. package/android/lc3Lib/src/main/cpp/google_opus_stuff/opus_tools/opus_header.h +59 -0
  27. package/android/lc3Lib/src/main/cpp/liblc3/CMakeLists.txt +38 -0
  28. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3.h +309 -0
  29. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3_private.h +162 -0
  30. package/android/lc3Lib/src/main/cpp/liblc3/include/rnnoise.h +114 -0
  31. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/CMakeLists.txt +19 -0
  32. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.c +92 -0
  33. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.h +44 -0
  34. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.c +375 -0
  35. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.h +315 -0
  36. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.c +129 -0
  37. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.h +69 -0
  38. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/common.h +148 -0
  39. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.c +70 -0
  40. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.h +43 -0
  41. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/fastmath.h +158 -0
  42. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/lc3.c +702 -0
  43. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.c +893 -0
  44. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.h +111 -0
  45. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_arm.h +506 -0
  46. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_neon.h +281 -0
  47. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/makefile.mk +35 -0
  48. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.c +452 -0
  49. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.h +57 -0
  50. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct_neon.h +296 -0
  51. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/meson.build +46 -0
  52. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.c +61 -0
  53. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.h +57 -0
  54. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.c +880 -0
  55. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.h +103 -0
  56. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.c +904 -0
  57. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.h +119 -0
  58. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.c +3457 -0
  59. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.h +94 -0
  60. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.c +457 -0
  61. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.h +99 -0
  62. package/android/lc3Lib/src/main/cpp/liblc3/liblc3.cpp +159 -0
  63. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/_kiss_fft_guts.h +182 -0
  64. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/arch.h +261 -0
  65. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.c +279 -0
  66. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.h +59 -0
  67. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/common.h +48 -0
  68. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/compile.sh +3 -0
  69. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/denoise.c +646 -0
  70. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.c +601 -0
  71. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.h +203 -0
  72. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/opus_types.h +159 -0
  73. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.c +526 -0
  74. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.h +149 -0
  75. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.c +178 -0
  76. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.h +69 -0
  77. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.c +11051 -0
  78. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.h +34 -0
  79. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_reader.c +168 -0
  80. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_train.py +66 -0
  81. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/tansig_table.h +45 -0
  82. package/android/lc3Lib/src/main/java/com/glassly/lc3Lib/Lc3Cpp.java +38 -0
  83. package/android/lc3Lib/third_party/CMakeLists.txt +23 -0
  84. package/android/lc3Lib/third_party/CMakeLists_libogg.txt +18 -0
  85. package/android/lc3Lib/third_party/CMakeLists_libopus.txt +18 -0
  86. package/android/lc3Lib/third_party/CMakeLists_opus-tools.txt +23 -0
  87. package/android/lc3Lib/third_party/opus_tools/src/AUTHORS +5 -0
  88. package/android/lc3Lib/third_party/opus_tools/src/CMakeLists.txt +4 -0
  89. package/android/lc3Lib/third_party/opus_tools/src/COPYING +371 -0
  90. package/android/lc3Lib/third_party/opus_tools/src/ChangeLog +3 -0
  91. package/android/lc3Lib/third_party/opus_tools/src/Makefile.am +42 -0
  92. package/android/lc3Lib/third_party/opus_tools/src/Makefile.unix +23 -0
  93. package/android/lc3Lib/third_party/opus_tools/src/NEWS +0 -0
  94. package/android/lc3Lib/third_party/opus_tools/src/README +0 -0
  95. package/android/lc3Lib/third_party/opus_tools/src/autogen.sh +115 -0
  96. package/android/lc3Lib/third_party/opus_tools/src/configure.ac +293 -0
  97. package/android/lc3Lib/third_party/opus_tools/src/src/arch.h +239 -0
  98. package/android/lc3Lib/third_party/opus_tools/src/src/audio-in.c +1046 -0
  99. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.c +245 -0
  100. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.h +28 -0
  101. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.c +320 -0
  102. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.h +51 -0
  103. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.c +157 -0
  104. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.h +27 -0
  105. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.c +286 -0
  106. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.h +59 -0
  107. package/android/lc3Lib/third_party/opus_tools/src/src/opusdec.c +884 -0
  108. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.c +1021 -0
  109. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.h +101 -0
  110. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.c +639 -0
  111. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.h +51 -0
  112. package/android/lc3Lib/third_party/opus_tools/src/src/os_support.h +167 -0
  113. package/android/lc3Lib/third_party/opus_tools/src/src/resample.c +1137 -0
  114. package/android/lc3Lib/third_party/opus_tools/src/src/speex_resampler.h +344 -0
  115. package/android/lc3Lib/third_party/opus_tools/src/src/stack_alloc.h +115 -0
  116. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.c +125 -0
  117. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.h +62 -0
  118. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.c +223 -0
  119. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.h +60 -0
  120. package/android/settings.gradle +4 -0
  121. package/android/silero/LICENSE.md +17 -0
  122. package/android/silero/build.gradle +50 -0
  123. package/android/silero/proguard-rules.pro +24 -0
  124. package/android/silero/src/androidTest/assets/hello.wav +0 -0
  125. package/android/silero/src/androidTest/java/com/konovalov/vad/silero/VadSileroTest.kt +79 -0
  126. package/android/silero/src/main/assets/LICENSE +21 -0
  127. package/android/silero/src/main/assets/silero_vad.onnx +0 -0
  128. package/android/silero/src/main/java/com/konovalov/vad/silero/Vad.kt +160 -0
  129. package/android/silero/src/main/java/com/konovalov/vad/silero/VadSilero.kt +449 -0
  130. package/android/silero/src/main/java/com/konovalov/vad/silero/config/FrameSize.kt +15 -0
  131. package/android/silero/src/main/java/com/konovalov/vad/silero/config/Mode.kt +14 -0
  132. package/android/silero/src/main/java/com/konovalov/vad/silero/config/SampleRate.kt +12 -0
  133. package/android/silero/src/main/java/com/konovalov/vad/silero/utils/AudioUtils.kt +47 -0
  134. package/android/silero/src/main/java/com/konovalov/vad/silero/utils/TensorMap.kt +41 -0
  135. package/android/silero/src/test/java/com/konovalov/vad/silero/utils/AudioUtilsTest.kt +44 -0
  136. package/android/src/main/AndroidManifest.xml +42 -0
  137. package/android/src/main/assets/G2Firmware/README.md +11 -0
  138. package/android/src/main/assets/G2Firmware/g2-glassly-cfw-2.2.9.22.evenota.bin +0 -0
  139. package/android/src/main/assets/G2Firmware/g2-stock-2.2.9.22.evenota.bin +0 -0
  140. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdk.kt +2321 -0
  141. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkAnalytics.kt +216 -0
  142. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkDebug.kt +14 -0
  143. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkDefaults.kt +7 -0
  144. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkModule.kt +1087 -0
  145. package/android/src/main/java/com/glassly/bluetoothsdk/Bridge.kt +953 -0
  146. package/android/src/main/java/com/glassly/bluetoothsdk/DeviceManager.kt +2472 -0
  147. package/android/src/main/java/com/glassly/bluetoothsdk/DeviceStore.kt +359 -0
  148. package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedChangelogCatalog.kt +9 -0
  149. package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedReleaseMetadata.kt +11 -0
  150. package/android/src/main/java/com/glassly/bluetoothsdk/LocalNetworkModule.kt +414 -0
  151. package/android/src/main/java/com/glassly/bluetoothsdk/ObservableStore.kt +88 -0
  152. package/android/src/main/java/com/glassly/bluetoothsdk/OtaManifest.kt +191 -0
  153. package/android/src/main/java/com/glassly/bluetoothsdk/ReleaseChangelog.kt +61 -0
  154. package/android/src/main/java/com/glassly/bluetoothsdk/ScopedNetworkReadiness.kt +17 -0
  155. package/android/src/main/java/com/glassly/bluetoothsdk/audio/AudioModels.kt +144 -0
  156. package/android/src/main/java/com/glassly/bluetoothsdk/camera/CameraModels.kt +486 -0
  157. package/android/src/main/java/com/glassly/bluetoothsdk/connection/ConnectionModels.kt +78 -0
  158. package/android/src/main/java/com/glassly/bluetoothsdk/controllers/ControllerManager.kt +158 -0
  159. package/android/src/main/java/com/glassly/bluetoothsdk/controllers/R1.kt +1057 -0
  160. package/android/src/main/java/com/glassly/bluetoothsdk/debug/BleTraceLogger.kt +165 -0
  161. package/android/src/main/java/com/glassly/bluetoothsdk/events/BluetoothEvents.kt +178 -0
  162. package/android/src/main/java/com/glassly/bluetoothsdk/internal/MapParsing.kt +140 -0
  163. package/android/src/main/java/com/glassly/bluetoothsdk/net/LocalIpv4.kt +57 -0
  164. package/android/src/main/java/com/glassly/bluetoothsdk/otaserver/LocalOtaServer.kt +304 -0
  165. package/android/src/main/java/com/glassly/bluetoothsdk/otaserver/OtaServerModule.kt +120 -0
  166. package/android/src/main/java/com/glassly/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistry.java +108 -0
  167. package/android/src/main/java/com/glassly/bluetoothsdk/photoreceiver/LocalPhotoUploadServer.kt +622 -0
  168. package/android/src/main/java/com/glassly/bluetoothsdk/photoreceiver/PhotoReceiverModule.kt +156 -0
  169. package/android/src/main/java/com/glassly/bluetoothsdk/requests/DisplayRequests.kt +56 -0
  170. package/android/src/main/java/com/glassly/bluetoothsdk/services/Foreground.kt +272 -0
  171. package/android/src/main/java/com/glassly/bluetoothsdk/services/PhoneMic.kt +1195 -0
  172. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Ar99.java +2653 -0
  173. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/BesOtaHeartbeatGuard.kt +49 -0
  174. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/BesOtaProgressMapper.kt +27 -0
  175. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G1.kt +3837 -0
  176. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G1TextSanitizer.kt +38 -0
  177. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2.kt +6457 -0
  178. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwClassification.kt +49 -0
  179. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwRenderer.kt +1253 -0
  180. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwTextureCache.kt +270 -0
  181. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2FlashProtocol.kt +291 -0
  182. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2Flasher.kt +411 -0
  183. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/GlasslyBle.java +43189 -0
  184. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Mach1.kt +1267 -0
  185. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLive.kt +10742 -0
  186. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLiveL2capChannel.kt +274 -0
  187. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLivePairingAdvertisement.kt +54 -0
  188. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraNex.kt +2008 -0
  189. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Nimo.kt +2532 -0
  190. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/SGCManager.kt +470 -0
  191. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Simulated.kt +228 -0
  192. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/Ar99OtaManager.java +566 -0
  193. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaByteUtils.java +18 -0
  194. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaCommandConstants.java +35 -0
  195. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaCrc32Util.java +13 -0
  196. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaGattTransport.java +11 -0
  197. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaProtocol.java +92 -0
  198. package/android/src/main/java/com/glassly/bluetoothsdk/speakerid/SpeakerIdEngine.kt +525 -0
  199. package/android/src/main/java/com/glassly/bluetoothsdk/status/DeviceStatus.kt +669 -0
  200. package/android/src/main/java/com/glassly/bluetoothsdk/status/RuntimeState.kt +201 -0
  201. package/android/src/main/java/com/glassly/bluetoothsdk/status/WifiHotspotStatus.kt +189 -0
  202. package/android/src/main/java/com/glassly/bluetoothsdk/streaming/StreamModels.kt +518 -0
  203. package/android/src/main/java/com/glassly/bluetoothsdk/stt/STTTools.kt +391 -0
  204. package/android/src/main/java/com/glassly/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +518 -0
  205. package/android/src/main/java/com/glassly/bluetoothsdk/stt/VadGateSpeechPolicy.kt +227 -0
  206. package/android/src/main/java/com/glassly/bluetoothsdk/tts/TTSTools.kt +248 -0
  207. package/android/src/main/java/com/glassly/bluetoothsdk/types/DeviceModels.kt +96 -0
  208. package/android/src/main/java/com/glassly/bluetoothsdk/utils/AES.java +106 -0
  209. package/android/src/main/java/com/glassly/bluetoothsdk/utils/AudioSessionMonitor.kt +189 -0
  210. package/android/src/main/java/com/glassly/bluetoothsdk/utils/AvifExifStripper.java +573 -0
  211. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BitmapJavaUtils.java +169 -0
  212. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BleJsonCompact.java +496 -0
  213. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BlePhotoUploadService.java +677 -0
  214. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BleWireProtocol.java +108 -0
  215. package/android/src/main/java/com/glassly/bluetoothsdk/utils/Constants.kt +46 -0
  216. package/android/src/main/java/com/glassly/bluetoothsdk/utils/G1Text.kt +436 -0
  217. package/android/src/main/java/com/glassly/bluetoothsdk/utils/HeifExifTagReader.java +199 -0
  218. package/android/src/main/java/com/glassly/bluetoothsdk/utils/IncidentLogBleRelayNaming.java +29 -0
  219. package/android/src/main/java/com/glassly/bluetoothsdk/utils/IncidentLogBleUploadService.java +77 -0
  220. package/android/src/main/java/com/glassly/bluetoothsdk/utils/K900LengthCodec.java +115 -0
  221. package/android/src/main/java/com/glassly/bluetoothsdk/utils/K900ProtocolUtils.java +827 -0
  222. package/android/src/main/java/com/glassly/bluetoothsdk/utils/MessageChunkReassembler.java +228 -0
  223. package/android/src/main/java/com/glassly/bluetoothsdk/utils/MessageChunker.java +325 -0
  224. package/android/src/main/java/com/glassly/bluetoothsdk/utils/NexSGCUtils.kt +698 -0
  225. package/android/src/main/java/com/glassly/bluetoothsdk/utils/PhoneAudioMonitor.kt +348 -0
  226. package/android/src/main/java/com/glassly/bluetoothsdk/utils/SmartGlassesConnectionState.java +9 -0
  227. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/Ar99OpusPcmDecoder.java +398 -0
  228. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/ByteUtilAudioPlayer.java +655 -0
  229. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/Lc3Player.java +441 -0
  230. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/PCMAudioPlayer.java +431 -0
  231. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/PcmStreamPlayer.kt +328 -0
  232. package/android/src/main/res/values/strings.xml +4 -0
  233. package/android/src/test/java/com/glassly/bluetoothsdk/BluetoothSdkExceptionTest.kt +18 -0
  234. package/android/src/test/java/com/glassly/bluetoothsdk/OtaManifestDowngradeTest.kt +86 -0
  235. package/android/src/test/java/com/glassly/bluetoothsdk/OtaStartResponsePolicyTest.kt +30 -0
  236. package/android/src/test/java/com/glassly/bluetoothsdk/ReleaseChangelogTest.kt +13 -0
  237. package/android/src/test/java/com/glassly/bluetoothsdk/ScopedNetworkReadinessTest.kt +39 -0
  238. package/android/src/test/java/com/glassly/bluetoothsdk/StreamStatusEventTest.kt +29 -0
  239. package/android/src/test/java/com/glassly/bluetoothsdk/camera/PhotoRequestTest.kt +141 -0
  240. package/android/src/test/java/com/glassly/bluetoothsdk/otaserver/LocalOtaServerTest.kt +82 -0
  241. package/android/src/test/java/com/glassly/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistryTest.java +75 -0
  242. package/android/src/test/java/com/glassly/bluetoothsdk/services/ForegroundServiceTypeTest.kt +69 -0
  243. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/Ar99AdvertisementMatcherTest.java +22 -0
  244. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/BesOtaHeartbeatGuardTest.kt +73 -0
  245. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/BesOtaProgressMapperTest.kt +67 -0
  246. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/EvenRleTest.kt +63 -0
  247. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G1TextSanitizerTest.kt +31 -0
  248. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwClassificationTest.kt +89 -0
  249. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwRendererTest.kt +344 -0
  250. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwTextureCacheTest.kt +200 -0
  251. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2FlashProtocolTest.kt +131 -0
  252. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/MentraLiveGattCharacteristicsTest.kt +39 -0
  253. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/MentraLivePairingAdvertisementParserTest.kt +133 -0
  254. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/NimoProtocolTest.kt +333 -0
  255. package/android/src/test/java/com/glassly/bluetoothsdk/utils/AvifExifStripperTest.java +46 -0
  256. package/android/src/test/java/com/glassly/bluetoothsdk/utils/BinaryMessageChunkerTest.java +84 -0
  257. package/android/src/test/java/com/glassly/bluetoothsdk/utils/BleJsonCompactTest.java +319 -0
  258. package/android/src/test/java/com/glassly/bluetoothsdk/utils/BlePhotoUploadServiceTest.java +107 -0
  259. package/android/src/test/java/com/glassly/bluetoothsdk/utils/K900ProtocolUtilsEndiannessTest.java +172 -0
  260. package/android/src/test/java/com/glassly/bluetoothsdk/utils/K900ProtocolUtilsTest.java +24 -0
  261. package/android/src/test/java/com/glassly/bluetoothsdk/utils/PhoneAudioMonitorTest.kt +45 -0
  262. package/android/src/test/resources/avif_with_exif.avif +0 -0
  263. package/app.plugin.js +3 -0
  264. package/build/BluetoothSdk.types.d.ts +1390 -0
  265. package/build/BluetoothSdk.types.d.ts.map +1 -0
  266. package/build/BluetoothSdk.types.js +41 -0
  267. package/build/BluetoothSdk.types.js.map +1 -0
  268. package/build/_internal.d.ts +17 -0
  269. package/build/_internal.d.ts.map +1 -0
  270. package/build/_internal.js +16 -0
  271. package/build/_internal.js.map +1 -0
  272. package/build/_private/BluetoothSdkModule.d.ts +171 -0
  273. package/build/_private/BluetoothSdkModule.d.ts.map +1 -0
  274. package/build/_private/BluetoothSdkModule.js +300 -0
  275. package/build/_private/BluetoothSdkModule.js.map +1 -0
  276. package/build/_private/LocalNetworkModule.d.ts +38 -0
  277. package/build/_private/LocalNetworkModule.d.ts.map +1 -0
  278. package/build/_private/LocalNetworkModule.js +3 -0
  279. package/build/_private/LocalNetworkModule.js.map +1 -0
  280. package/build/_private/cameraRequestPayload.d.ts +4 -0
  281. package/build/_private/cameraRequestPayload.d.ts.map +1 -0
  282. package/build/_private/cameraRequestPayload.js +32 -0
  283. package/build/_private/cameraRequestPayload.js.map +1 -0
  284. package/build/_private/photoRequestPayload.d.ts +6 -0
  285. package/build/_private/photoRequestPayload.d.ts.map +1 -0
  286. package/build/_private/photoRequestPayload.js +86 -0
  287. package/build/_private/photoRequestPayload.js.map +1 -0
  288. package/build/_private/sdkOtaManifest.d.ts +11 -0
  289. package/build/_private/sdkOtaManifest.d.ts.map +1 -0
  290. package/build/_private/sdkOtaManifest.js +15 -0
  291. package/build/_private/sdkOtaManifest.js.map +1 -0
  292. package/build/changelogs.d.ts +7 -0
  293. package/build/changelogs.d.ts.map +1 -0
  294. package/build/changelogs.js +46 -0
  295. package/build/changelogs.js.map +1 -0
  296. package/build/debug.d.ts +3 -0
  297. package/build/debug.d.ts.map +1 -0
  298. package/build/debug.js +8 -0
  299. package/build/debug.js.map +1 -0
  300. package/build/generated/changelogCatalog.d.ts +12 -0
  301. package/build/generated/changelogCatalog.d.ts.map +1 -0
  302. package/build/generated/changelogCatalog.js +16 -0
  303. package/build/generated/changelogCatalog.js.map +1 -0
  304. package/build/generated/releaseMetadata.d.ts +12 -0
  305. package/build/generated/releaseMetadata.d.ts.map +1 -0
  306. package/build/generated/releaseMetadata.js +10 -0
  307. package/build/generated/releaseMetadata.js.map +1 -0
  308. package/build/index.d.ts +6 -0
  309. package/build/index.d.ts.map +1 -0
  310. package/build/index.js +170 -0
  311. package/build/index.js.map +1 -0
  312. package/build/ota-server/OtaServer.types.d.ts +14 -0
  313. package/build/ota-server/OtaServer.types.d.ts.map +1 -0
  314. package/build/ota-server/OtaServer.types.js +2 -0
  315. package/build/ota-server/OtaServer.types.js.map +1 -0
  316. package/build/ota-server/OtaServerModule.d.ts +21 -0
  317. package/build/ota-server/OtaServerModule.d.ts.map +1 -0
  318. package/build/ota-server/OtaServerModule.js +3 -0
  319. package/build/ota-server/OtaServerModule.js.map +1 -0
  320. package/build/ota-server/OtaServerModule.web.d.ts +10 -0
  321. package/build/ota-server/OtaServerModule.web.d.ts.map +1 -0
  322. package/build/ota-server/OtaServerModule.web.js +12 -0
  323. package/build/ota-server/OtaServerModule.web.js.map +1 -0
  324. package/build/ota-server/index.d.ts +3 -0
  325. package/build/ota-server/index.d.ts.map +1 -0
  326. package/build/ota-server/index.js +3 -0
  327. package/build/ota-server/index.js.map +1 -0
  328. package/build/ota-transport/index.d.ts +67 -0
  329. package/build/ota-transport/index.d.ts.map +1 -0
  330. package/build/ota-transport/index.js +58 -0
  331. package/build/ota-transport/index.js.map +1 -0
  332. package/build/photo-receiver/PhotoReceiver.types.d.ts +18 -0
  333. package/build/photo-receiver/PhotoReceiver.types.d.ts.map +1 -0
  334. package/build/photo-receiver/PhotoReceiver.types.js +2 -0
  335. package/build/photo-receiver/PhotoReceiver.types.js.map +1 -0
  336. package/build/photo-receiver/PhotoReceiverModule.d.ts +10 -0
  337. package/build/photo-receiver/PhotoReceiverModule.d.ts.map +1 -0
  338. package/build/photo-receiver/PhotoReceiverModule.js +3 -0
  339. package/build/photo-receiver/PhotoReceiverModule.js.map +1 -0
  340. package/build/photo-receiver/PhotoReceiverModule.web.d.ts +10 -0
  341. package/build/photo-receiver/PhotoReceiverModule.web.d.ts.map +1 -0
  342. package/build/photo-receiver/PhotoReceiverModule.web.js +12 -0
  343. package/build/photo-receiver/PhotoReceiverModule.web.js.map +1 -0
  344. package/build/photo-receiver/index.d.ts +3 -0
  345. package/build/photo-receiver/index.d.ts.map +1 -0
  346. package/build/photo-receiver/index.js +3 -0
  347. package/build/photo-receiver/index.js.map +1 -0
  348. package/build/react/index.d.ts +5 -0
  349. package/build/react/index.d.ts.map +1 -0
  350. package/build/react/index.js +4 -0
  351. package/build/react/index.js.map +1 -0
  352. package/build/react/useBluetooth.d.ts +100 -0
  353. package/build/react/useBluetooth.d.ts.map +1 -0
  354. package/build/react/useBluetooth.js +167 -0
  355. package/build/react/useBluetooth.js.map +1 -0
  356. package/build/react/useBluetoothEvent.d.ts +6 -0
  357. package/build/react/useBluetoothEvent.d.ts.map +1 -0
  358. package/build/react/useBluetoothEvent.js +21 -0
  359. package/build/react/useBluetoothEvent.js.map +1 -0
  360. package/build/react/useBluetoothScan.d.ts +22 -0
  361. package/build/react/useBluetoothScan.d.ts.map +1 -0
  362. package/build/react/useBluetoothScan.js +135 -0
  363. package/build/react/useBluetoothScan.js.map +1 -0
  364. package/build/react/useBluetoothStatus.d.ts +16 -0
  365. package/build/react/useBluetoothStatus.d.ts.map +1 -0
  366. package/build/react/useBluetoothStatus.js +137 -0
  367. package/build/react/useBluetoothStatus.js.map +1 -0
  368. package/build/react/useGlassesConnection.d.ts +29 -0
  369. package/build/react/useGlassesConnection.d.ts.map +1 -0
  370. package/build/react/useGlassesConnection.js +153 -0
  371. package/build/react/useGlassesConnection.js.map +1 -0
  372. package/build/types/index.d.ts +3 -0
  373. package/build/types/index.d.ts.map +1 -0
  374. package/build/types/index.js +2 -0
  375. package/build/types/index.js.map +1 -0
  376. package/expo-module.config.json +14 -0
  377. package/ios/BackgroundOtaArtifactDownloader.swift +125 -0
  378. package/ios/BluetoothSdkModule.swift +1028 -0
  379. package/ios/GlasslyBluetoothSDK.podspec +106 -0
  380. package/ios/LocalIPv4.swift +150 -0
  381. package/ios/LocalOtaServer.swift +309 -0
  382. package/ios/LocalPhotoUploadServer.swift +754 -0
  383. package/ios/OtaServerModule.swift +147 -0
  384. package/ios/Packages/CoreObjC/CoreObjC.xcodeproj/project.pbxproj +213 -0
  385. package/ios/Packages/CoreObjC/PcmConverter.h +22 -0
  386. package/ios/Packages/CoreObjC/PcmConverter.m +266 -0
  387. package/ios/Packages/CoreObjC/attdet.c +92 -0
  388. package/ios/Packages/CoreObjC/attdet.h +44 -0
  389. package/ios/Packages/CoreObjC/bits.c +375 -0
  390. package/ios/Packages/CoreObjC/bits.h +315 -0
  391. package/ios/Packages/CoreObjC/bwdet.c +129 -0
  392. package/ios/Packages/CoreObjC/bwdet.h +69 -0
  393. package/ios/Packages/CoreObjC/common.h +151 -0
  394. package/ios/Packages/CoreObjC/energy.c +70 -0
  395. package/ios/Packages/CoreObjC/energy.h +43 -0
  396. package/ios/Packages/CoreObjC/fastmath.h +158 -0
  397. package/ios/Packages/CoreObjC/include/PcmConverter.h +22 -0
  398. package/ios/Packages/CoreObjC/lc3.c +704 -0
  399. package/ios/Packages/CoreObjC/lc3.h +313 -0
  400. package/ios/Packages/CoreObjC/lc3_cpp.h +283 -0
  401. package/ios/Packages/CoreObjC/lc3_private.h +163 -0
  402. package/ios/Packages/CoreObjC/ltpf.c +905 -0
  403. package/ios/Packages/CoreObjC/ltpf.h +111 -0
  404. package/ios/Packages/CoreObjC/ltpf_arm.h +506 -0
  405. package/ios/Packages/CoreObjC/ltpf_neon.h +281 -0
  406. package/ios/Packages/CoreObjC/makefile.mk +35 -0
  407. package/ios/Packages/CoreObjC/mdct.c +469 -0
  408. package/ios/Packages/CoreObjC/mdct.h +57 -0
  409. package/ios/Packages/CoreObjC/mdct_neon.h +296 -0
  410. package/ios/Packages/CoreObjC/meson.build +61 -0
  411. package/ios/Packages/CoreObjC/plc.c +61 -0
  412. package/ios/Packages/CoreObjC/plc.h +57 -0
  413. package/ios/Packages/CoreObjC/rnnoise.h +114 -0
  414. package/ios/Packages/CoreObjC/sns.c +880 -0
  415. package/ios/Packages/CoreObjC/sns.h +103 -0
  416. package/ios/Packages/CoreObjC/spec.c +907 -0
  417. package/ios/Packages/CoreObjC/spec.h +119 -0
  418. package/ios/Packages/CoreObjC/tables.c +3457 -0
  419. package/ios/Packages/CoreObjC/tables.h +94 -0
  420. package/ios/Packages/CoreObjC/tns.c +457 -0
  421. package/ios/Packages/CoreObjC/tns.h +99 -0
  422. package/ios/Packages/SherpaOnnx/Model/joiner.onnx +0 -0
  423. package/ios/Packages/SherpaOnnx/Model/tokens.txt +502 -0
  424. package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +2383 -0
  425. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +48 -0
  426. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/c-api.h +4689 -0
  427. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/cxx-api.h +2036 -0
  428. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
  429. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/c-api.h +4689 -0
  430. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/cxx-api.h +2036 -0
  431. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
  432. package/ios/Packages/libbz2/module.modulemap +5 -0
  433. package/ios/Packages/libbz2/shim.h +1 -0
  434. package/ios/PhotoReceiverModule.swift +129 -0
  435. package/ios/Source/BluetoothSDK.swift +2299 -0
  436. package/ios/Source/BluetoothSDKDebug.swift +12 -0
  437. package/ios/Source/BluetoothSdkDefaults.swift +29 -0
  438. package/ios/Source/Bridge.swift +708 -0
  439. package/ios/Source/Bridging-Header.h +16 -0
  440. package/ios/Source/DeviceManager.swift +2054 -0
  441. package/ios/Source/DeviceStore.swift +350 -0
  442. package/ios/Source/GeneratedChangelogCatalog.swift +8 -0
  443. package/ios/Source/GeneratedReleaseMetadata.swift +11 -0
  444. package/ios/Source/ObservableStore.swift +118 -0
  445. package/ios/Source/OtaManifest.swift +211 -0
  446. package/ios/Source/PrivacyInfo.xcprivacy +23 -0
  447. package/ios/Source/ReleaseChangelog.swift +65 -0
  448. package/ios/Source/Resources/G2Firmware/README.md +10 -0
  449. package/ios/Source/Resources/G2Firmware/g2-glassly-cfw-2.2.9.22.evenota.bin +0 -0
  450. package/ios/Source/Resources/G2Firmware/g2-stock-2.2.9.22.evenota.bin +0 -0
  451. package/ios/Source/audio/AudioModels.swift +178 -0
  452. package/ios/Source/audio/PcmStreamPlayer.swift +410 -0
  453. package/ios/Source/camera/CameraModels.swift +866 -0
  454. package/ios/Source/connection/ScanSession.swift +27 -0
  455. package/ios/Source/controllers/ControllerManager.swift +184 -0
  456. package/ios/Source/controllers/R1.swift +925 -0
  457. package/ios/Source/errors/BluetoothSdkError.swift +19 -0
  458. package/ios/Source/events/BluetoothEvents.swift +342 -0
  459. package/ios/Source/internal/BleTraceLogger.swift +192 -0
  460. package/ios/Source/internal/BluetoothAvailability.swift +78 -0
  461. package/ios/Source/internal/BluetoothSdkAnalytics.swift +199 -0
  462. package/ios/Source/internal/ValueParsing.swift +99 -0
  463. package/ios/Source/requests/DisplayRequests.swift +82 -0
  464. package/ios/Source/services/PhoneMic.swift +662 -0
  465. package/ios/Source/sgcs/Ar99.swift +2451 -0
  466. package/ios/Source/sgcs/G1.swift +2554 -0
  467. package/ios/Source/sgcs/G2.swift +7142 -0
  468. package/ios/Source/sgcs/G2CfwClassification.swift +43 -0
  469. package/ios/Source/sgcs/G2CfwRenderer.swift +1295 -0
  470. package/ios/Source/sgcs/G2CfwTextureCache.swift +233 -0
  471. package/ios/Source/sgcs/G2FlashProtocol.swift +312 -0
  472. package/ios/Source/sgcs/G2Flasher.swift +773 -0
  473. package/ios/Source/sgcs/Mach1.swift +541 -0
  474. package/ios/Source/sgcs/MentraLive.swift +7011 -0
  475. package/ios/Source/sgcs/MentraLiveL2capChannel.swift +183 -0
  476. package/ios/Source/sgcs/MentraLivePairingAdvertisement.swift +64 -0
  477. package/ios/Source/sgcs/MentraNex.swift +3220 -0
  478. package/ios/Source/sgcs/Nimo.swift +1886 -0
  479. package/ios/Source/sgcs/SGCManager.swift +621 -0
  480. package/ios/Source/sgcs/Simulated.swift +274 -0
  481. package/ios/Source/sgcs/ar99/ota/Ar99OtaManager.swift +637 -0
  482. package/ios/Source/sgcs/glassly_ble.pb.swift +4354 -0
  483. package/ios/Source/speakerid/SpeakerIdEngine.swift +573 -0
  484. package/ios/Source/status/DeviceStatus.swift +981 -0
  485. package/ios/Source/status/RuntimeState.swift +359 -0
  486. package/ios/Source/status/WifiHotspotStatus.swift +345 -0
  487. package/ios/Source/streaming/StreamModels.swift +693 -0
  488. package/ios/Source/stt/STTTools.swift +191 -0
  489. package/ios/Source/stt/SherpaOnnxTranscriber.swift +466 -0
  490. package/ios/Source/tts/TTSTools.swift +167 -0
  491. package/ios/Source/types/DeviceModels.swift +177 -0
  492. package/ios/Source/utils/AudioSessionMonitor.swift +283 -0
  493. package/ios/Source/utils/BinaryCodec.swift +61 -0
  494. package/ios/Source/utils/BleJsonCompact.swift +405 -0
  495. package/ios/Source/utils/BleWireProtocol.swift +92 -0
  496. package/ios/Source/utils/Constants.swift +78 -0
  497. package/ios/Source/utils/Enums.swift +95 -0
  498. package/ios/Source/utils/G1Text.swift +2096 -0
  499. package/ios/Source/utils/G2NotifyFile.swift +116 -0
  500. package/ios/Source/utils/JSCExperiment.swift +241 -0
  501. package/ios/Source/utils/MemoryMonitor.swift +44 -0
  502. package/ios/Source/utils/MessageChunkReassembler.swift +190 -0
  503. package/ios/Source/utils/MessageChunker.swift +294 -0
  504. package/ios/Source/utils/Models.swift +135 -0
  505. package/ios/Source/utils/PhoneAudioMonitor.swift +230 -0
  506. package/ios/Source/utils/TarBz2Extractor.swift +257 -0
  507. package/ios/Tests/BluetoothSDKTests/G2CfwClassificationTests.swift +78 -0
  508. package/ios/Tests/BluetoothSDKTests/G2CfwRendererTests.swift +372 -0
  509. package/ios/Tests/BluetoothSDKTests/G2CfwTextureCacheTests.swift +162 -0
  510. package/ios/Tests/BluetoothSDKTests/G2FlashProtocolTests.swift +182 -0
  511. package/ios/Tests/BluetoothSDKTests/G2NotifyFileTests.swift +91 -0
  512. package/ios/Tests/MentraLivePairingAdvertisementTests.swift +160 -0
  513. package/ios/Tests/ReleaseChangelogTests.swift +13 -0
  514. package/package.json +129 -0
  515. package/plugin/build/index.d.ts +10 -0
  516. package/plugin/build/index.js +12 -0
  517. package/plugin/build/withAndroid.d.ts +3 -0
  518. package/plugin/build/withAndroid.js +190 -0
  519. package/plugin/build/withIos.d.ts +5 -0
  520. package/plugin/build/withIos.js +108 -0
  521. package/scripts/inject-ios-sdk-version.mjs +65 -0
  522. package/scripts/public-ota-api.test.mjs +37 -0
  523. package/scripts/verify-release-package.mjs +46 -0
  524. package/scripts/write-release-metadata.mjs +154 -0
  525. package/scripts/write-release-metadata.test.mjs +37 -0
  526. package/src/BluetoothSdk.types.ts +1659 -0
  527. package/src/_internal.ts +16 -0
  528. package/src/_private/BluetoothSdkModule.ts +683 -0
  529. package/src/_private/LocalNetworkModule.ts +50 -0
  530. package/src/_private/cameraRequestPayload.ts +34 -0
  531. package/src/_private/photoRequestPayload.ts +90 -0
  532. package/src/_private/sdkOtaManifest.ts +18 -0
  533. package/src/changelogs.ts +46 -0
  534. package/src/debug.ts +9 -0
  535. package/src/generated/changelogCatalog.ts +17 -0
  536. package/src/generated/releaseMetadata.ts +20 -0
  537. package/src/index.ts +320 -0
  538. package/src/ota-server/OtaServer.types.ts +10 -0
  539. package/src/ota-server/OtaServerModule.ts +23 -0
  540. package/src/ota-server/OtaServerModule.web.ts +17 -0
  541. package/src/ota-server/index.ts +2 -0
  542. package/src/ota-transport/index.ts +116 -0
  543. package/src/photo-receiver/PhotoReceiver.types.ts +20 -0
  544. package/src/photo-receiver/PhotoReceiverModule.ts +11 -0
  545. package/src/photo-receiver/PhotoReceiverModule.web.ts +17 -0
  546. package/src/photo-receiver/index.ts +2 -0
  547. package/src/react/index.ts +21 -0
  548. package/src/react/useBluetooth.ts +309 -0
  549. package/src/react/useBluetoothEvent.ts +35 -0
  550. package/src/react/useBluetoothScan.ts +173 -0
  551. package/src/react/useBluetoothStatus.ts +180 -0
  552. package/src/react/useGlassesConnection.ts +202 -0
  553. package/src/types/index.ts +12 -0
@@ -0,0 +1,1267 @@
1
+ package com.glassly.bluetoothsdk.sgcs
2
+
3
+ import android.content.Context
4
+ import android.content.res.Resources
5
+ import android.graphics.Bitmap
6
+ import android.graphics.BitmapFactory
7
+ import android.graphics.drawable.Drawable
8
+ import android.os.Handler
9
+ import android.os.Looper
10
+ import android.util.Log
11
+
12
+ import androidx.lifecycle.LiveData
13
+ import androidx.lifecycle.Observer
14
+
15
+ // Glassly
16
+ import com.glassly.bluetoothsdk.DeviceManager
17
+ import com.glassly.bluetoothsdk.Bridge
18
+ import com.glassly.bluetoothsdk.PhotoRequest
19
+ import com.glassly.bluetoothsdk.utils.DeviceTypes
20
+ import com.glassly.bluetoothsdk.utils.ConnTypes
21
+ import com.glassly.bluetoothsdk.utils.BitmapJavaUtils
22
+ import com.glassly.bluetoothsdk.utils.SmartGlassesConnectionState
23
+ import com.glassly.bluetoothsdk.utils.K900ProtocolUtils
24
+ import com.glassly.bluetoothsdk.utils.MessageChunker
25
+ import com.glassly.bluetoothsdk.utils.audio.Lc3Player
26
+ import com.glassly.bluetoothsdk.utils.BlePhotoUploadService
27
+ import com.glassly.bluetoothsdk.DeviceStore
28
+ import com.squareup.picasso.Picasso
29
+ import com.squareup.picasso.Target
30
+ import com.vuzix.ultralite.Anchor
31
+ import com.vuzix.ultralite.BatteryStatus
32
+ import com.vuzix.ultralite.EventListener
33
+ import com.vuzix.ultralite.Layout
34
+ import com.vuzix.ultralite.TextAlignment
35
+ import com.vuzix.ultralite.TextWrapMode
36
+ import com.vuzix.ultralite.UltraliteColor
37
+ import com.vuzix.ultralite.UltraliteSDK
38
+
39
+
40
+ import java.util.ArrayList
41
+ import java.util.Arrays
42
+ import java.util.Collections
43
+
44
+
45
+ //communicate with ActiveLook smart glasses
46
+ class Mach1 : SGCManager() {
47
+
48
+ companion object {
49
+ private const val TAG = "WearableAi_UltraliteSGC"
50
+ const val cardLingerTime = 15
51
+
52
+ private const val TAP_DEBOUNCE_TIME = 80L // milliseconds
53
+
54
+ @JvmStatic
55
+ fun maybeReverseRTLString(text: String): String {
56
+ val result = StringBuilder()
57
+ val rtlBuffer = StringBuilder()
58
+
59
+ for (c in text.toCharArray()) {
60
+ if (isRTLCharacter(c)) {
61
+ rtlBuffer.append(c) // Append RTL characters to a buffer
62
+ } else {
63
+ if (rtlBuffer.length > 0) {
64
+ result.append(rtlBuffer.reverse()) // Reverse and append RTL text when a non-RTL character is found
65
+ rtlBuffer.setLength(0) // Clear the buffer
66
+ }
67
+ result.append(c) // Append non-RTL characters directly to the result
68
+ }
69
+ }
70
+
71
+ if (rtlBuffer.length > 0) {
72
+ result.append(rtlBuffer.reverse()) // Append any remaining RTL text in reverse
73
+ }
74
+
75
+ return result.toString()
76
+ }
77
+
78
+ private fun isRTLCharacter(c: Char): Boolean {
79
+ val block = Character.UnicodeBlock.of(c)
80
+ return block == Character.UnicodeBlock.ARABIC ||
81
+ block == Character.UnicodeBlock.HEBREW ||
82
+ block == Character.UnicodeBlock.SYRIAC ||
83
+ block == Character.UnicodeBlock.ARABIC_SUPPLEMENT ||
84
+ block == Character.UnicodeBlock.THAANA ||
85
+ block == Character.UnicodeBlock.NKO ||
86
+ block == Character.UnicodeBlock.SAMARITAN ||
87
+ block == Character.UnicodeBlock.MANDAIC ||
88
+ block == Character.UnicodeBlock.ARABIC_EXTENDED_A
89
+ // Add other RTL blocks as needed
90
+ }
91
+ }
92
+
93
+ var ultraliteSdk: UltraliteSDK? = null
94
+ var ultraliteCanvas: UltraliteSDK.Canvas? = null
95
+ var ultraliteListener: UltraliteListener? = null
96
+ var currentUltraliteLayout: Layout? = null
97
+ var screenToggleOff = false //should we keep the screen off?
98
+ var context: Context? = null
99
+
100
+ private var rowTextsLiveNow: ArrayList<Int>? = null
101
+
102
+ //ultralite pixel buffer on left side of screen
103
+ var ultraliteLeftSidePixelBuffer = 40
104
+
105
+ //handler to turn off screen
106
+ var goHomeHandler: Handler? = null
107
+ var goHomeRunnable: Runnable? = null
108
+
109
+ //handler to turn off screen/toggle
110
+ var screenOffHandler: Handler? = null
111
+ var screenOffRunnable: Runnable? = null
112
+
113
+ //handler to check battery life
114
+ var batteryHandler: Handler? = null
115
+ var batteryRunnable: Runnable? = null
116
+
117
+ //handler to disconnect
118
+ var killHandler: Handler? = null
119
+
120
+ var hasUltraliteControl = false
121
+ var screenIsClear = false
122
+ var isHeadUp = false // Dashboard state toggled by taps
123
+ // SmartGlassesDevice smartGlassesDevice;
124
+ private var lastTapTime = 0L
125
+ private var totalDashboardsIdk = 0
126
+
127
+ private fun hasBattery(): Boolean {
128
+ val level = DeviceStore.get("glasses", "batteryLevel")
129
+ return level is Number && level.toInt() != -1
130
+ }
131
+
132
+ private fun updateConnectionState(state: String) {
133
+ val isEqual = state == connectionState
134
+ if (isEqual) {
135
+ return
136
+ }
137
+
138
+ // Update the connection state
139
+ DeviceStore.apply("glasses", "connectionState", state)
140
+
141
+ if (state == ConnTypes.CONNECTED) {
142
+ // Match iOS: only declare fully booted once we have battery info too
143
+ if (hasBattery()) {
144
+ DeviceStore.apply("glasses", "connected", true)
145
+ DeviceStore.apply("glasses", "fullyBooted", true)
146
+ }
147
+ } else if (state == ConnTypes.DISCONNECTED) {
148
+ DeviceStore.apply("glasses", "fullyBooted", false)
149
+ DeviceStore.apply("glasses", "connected", false)
150
+ }
151
+ }
152
+
153
+ override fun setMicEnabled(enabled: Boolean) {
154
+ }
155
+
156
+ override fun sortMicRanking(list: MutableList<String>): MutableList<String> {
157
+ return list
158
+ }
159
+
160
+ override fun requestPhoto(request: PhotoRequest) {
161
+
162
+ }
163
+
164
+ override fun startStream(message: MutableMap<String, Any>) {
165
+
166
+ }
167
+
168
+ override fun stopStream() {
169
+
170
+ }
171
+
172
+ override fun sendStreamKeepAlive(message: MutableMap<String, Any>) {
173
+
174
+ }
175
+
176
+ override fun startVideoRecording(requestId: String, save: Boolean, sound: Boolean) {
177
+
178
+ }
179
+
180
+ override fun stopVideoRecording(requestId: String) {
181
+
182
+ }
183
+
184
+ override fun sendButtonPhotoSettings() {
185
+
186
+ }
187
+
188
+ override fun sendButtonVideoRecordingSettings() {
189
+
190
+ }
191
+
192
+ override fun sendButtonMaxRecordingTime() {
193
+
194
+ }
195
+
196
+ override fun sendCameraFovSetting() {
197
+ }
198
+
199
+ override fun setBrightness(level: Int, autoMode: Boolean) {
200
+ Bridge.log("Mach1: setBrightness() - level: " + level + "%, autoMode: " + autoMode)
201
+ updateGlassesBrightness(level)
202
+ updateGlassesAutoBrightness(autoMode)
203
+ }
204
+
205
+ override fun clearDisplay() {
206
+ Bridge.log("Mach1: clearDisplay()")
207
+ blankScreen()
208
+ }
209
+
210
+ override fun sendText(text: String) {
211
+ Bridge.log("Mach1: sendText() - text: " + text)
212
+ displayTextWall(text)
213
+ }
214
+
215
+ override fun sendTextWall(text: String) {
216
+ Bridge.log("Mach1: sendTextWall()")
217
+ displayTextWall(text)
218
+ }
219
+
220
+ override fun sendDoubleTextWall(top: String, bottom: String) {
221
+ Bridge.log("Mach1: sendDoubleTextWall()")
222
+ displayDoubleTextWall(top, bottom)
223
+ }
224
+
225
+ override fun displayBitmap(base64ImageData: String, x: Int?, y: Int?, width: Int?, height: Int?): Boolean {
226
+ try {
227
+ Bridge.log("Mach1: displayBitmap() - decoding base64")
228
+ // Decode base64 to byte array
229
+ val bmpData = android.util.Base64.decode(base64ImageData, android.util.Base64.DEFAULT)
230
+
231
+ if (bmpData == null || bmpData.isEmpty()) {
232
+ Log.e(TAG, "Failed to decode base64 image data")
233
+ return false
234
+ }
235
+
236
+ // Convert byte array to Bitmap
237
+ val bitmap = BitmapFactory.decodeByteArray(bmpData, 0, bmpData.size)
238
+
239
+ if (bitmap == null) {
240
+ Log.e(TAG, "Failed to decode bitmap from byte array")
241
+ return false
242
+ }
243
+
244
+ // Call internal implementation
245
+ displayBitmap(bitmap)
246
+ return true
247
+ } catch (e: Exception) {
248
+ Log.e(TAG, "Error displaying bitmap from base64", e)
249
+ return false
250
+ }
251
+ }
252
+
253
+ override fun showDashboard() {
254
+
255
+ }
256
+
257
+ override fun ping() {
258
+ }
259
+
260
+ override fun dbg1() {}
261
+
262
+ override fun dbg2() {}
263
+
264
+ override fun setDashboardPosition(height: Int, depth: Int) {
265
+
266
+ }
267
+
268
+ override fun setHeadUpAngle(angle: Int) {
269
+
270
+ }
271
+
272
+ override fun getBatteryStatus() {
273
+
274
+ }
275
+
276
+ override fun setSilentMode(enabled: Boolean) {
277
+
278
+ }
279
+
280
+ override fun exit() {
281
+
282
+ }
283
+
284
+ override fun sendShutdown() {
285
+ Bridge.log("sendShutdown - not supported on Mach1")
286
+ }
287
+
288
+ override fun sendReboot() {
289
+ Bridge.log("sendReboot - not supported on Mach1")
290
+ }
291
+
292
+ override fun sendRgbLedControl(requestId: String, packageName: String?, action: String, color: String?, onDurationMs: Int, offDurationMs: Int, count: Int) {
293
+ Bridge.log("sendRgbLedControl - not supported on Mach1")
294
+ Bridge.sendRgbLedControlResponse(requestId, false, "device_not_supported")
295
+ }
296
+
297
+ override fun disconnect() {
298
+ Bridge.log("Mach1: disconnect()")
299
+ if (ultraliteSdk != null) {
300
+ ultraliteSdk!!.releaseControl()
301
+ updateConnectionState(ConnTypes.DISCONNECTED)
302
+ }
303
+ }
304
+
305
+ override fun forget() {
306
+ Bridge.log("Mach1: forget()")
307
+ // Release control and clean up
308
+ destroy()
309
+ }
310
+
311
+ override fun findCompatibleDevices() {
312
+ Bridge.log("Mach1: findCompatibleDevices()")
313
+ findCompatibleDeviceNames()
314
+ }
315
+
316
+ override fun stopScan() {
317
+ Bridge.log("Mach1: stopScan() - no active BLE scanner owned by Mach1")
318
+ }
319
+
320
+ override fun connectById(id: String) {
321
+ Bridge.log("Mach1: connectById() - id: " + id)
322
+ // The Mach1 uses UltraliteSDK which handles connection internally
323
+ // We just need to trigger the connection process
324
+ connectToSmartGlasses()
325
+ }
326
+
327
+ override fun getConnectedBluetoothName(): String {
328
+ // Mach1/Ultralite SDK doesn't expose the peripheral name directly
329
+ // Return device type if connected
330
+ if (ultraliteSdk != null) {
331
+ val connected = ultraliteSdk!!.getConnected()
332
+ if (connected != null && java.lang.Boolean.TRUE == connected.value) {
333
+ return "Vuzix Ultralite"
334
+ }
335
+ }
336
+ return ""
337
+ }
338
+
339
+ override fun cleanup() {
340
+ destroy()
341
+ }
342
+
343
+ override fun requestWifiScan(scanId: String?) {
344
+
345
+ }
346
+
347
+ override fun sendWifiCredentials(ssid: String, password: String) {
348
+
349
+ }
350
+
351
+ override fun forgetWifiNetwork(ssid: String) {
352
+ // Mach1 doesn't support WiFi
353
+ }
354
+
355
+ override fun sendHotspotState(enabled: Boolean) {
356
+ // Mach1 doesn't support hotspot
357
+ }
358
+
359
+ override fun sendUserEmailToGlasses(email: String) {
360
+ // Mach1 doesn't support user email (no ASG client)
361
+ }
362
+
363
+ override fun sendIncidentId(incidentId: String, apiBaseUrl: String?) {
364
+ // Mach1 doesn't support incident reporting (no ASG client)
365
+ }
366
+
367
+ override fun queryGalleryStatus() {
368
+
369
+ }
370
+
371
+ override fun sendGalleryMode() {
372
+ // Mach1 doesn't have a built-in camera/gallery system
373
+ Bridge.log("Mach1: sendGalleryModeActive - not supported on Mach1")
374
+ }
375
+
376
+ override fun requestVersionInfo() {
377
+ // Mach1 doesn't support version info requests
378
+ Bridge.log("Mach1: requestVersionInfo - not supported on Mach1")
379
+ }
380
+
381
+ inner class UltraliteListener : EventListener {
382
+ override fun onTap(tapCount: Int) {
383
+ val currentTime = System.currentTimeMillis()
384
+ if (currentTime - lastTapTime < TAP_DEBOUNCE_TIME) {
385
+ Log.d(TAG, "Ignoring duplicate tap event")
386
+ return
387
+ }
388
+ totalDashboardsIdk++
389
+ Log.d(TAG, "TOTAL NUMBER OF DASHBOARD TOGGLEZ: " + totalDashboardsIdk)
390
+
391
+ lastTapTime = currentTime
392
+ Log.d(TAG, "Ultralite go tap n times: " + tapCount)
393
+
394
+ // Toggle dashboard on 2+ taps (same as iOS implementation)
395
+ if (tapCount >= 2) {
396
+ isHeadUp = !isHeadUp
397
+ // Notify DeviceManager of head up state change (same as G1 does with IMU)
398
+ DeviceStore.apply("glasses", "headUp", isHeadUp)
399
+ Log.d(TAG, "Mach1: Dashboard toggled via tap, isHeadUp: " + isHeadUp)
400
+
401
+ // Auto turn off the dashboard after 15 seconds
402
+ if (isHeadUp) {
403
+ goHomeHandler!!.postDelayed({
404
+ if (isHeadUp) {
405
+ isHeadUp = false
406
+ DeviceStore.apply("glasses", "headUp", false)
407
+ Log.d(TAG, "Mach1: Auto-disabling dashboard after 15 seconds")
408
+ }
409
+ }, 15000L)
410
+ }
411
+ }
412
+ }
413
+
414
+ override fun onDisplayTimeout() {
415
+ Log.d(TAG, "Ultralite display timeout.")
416
+ }
417
+
418
+ override fun onPowerButtonPress(turningOn: Boolean) {
419
+ //since we implement our own state for the power turn on/off, we ignore what the ultralite thinks ('turningOn') and use our own state
420
+ Log.d(TAG, "Ultralites power button pressed: " + turningOn)
421
+
422
+ //flip value of screen toggle
423
+ screenToggleOff = !screenToggleOff
424
+
425
+ if (!screenToggleOff) {
426
+ Log.d(TAG, "screen toggle off NOT on, showing turn ON message")
427
+ } else {
428
+ Log.d(TAG, "screen toggle off IS on")
429
+ }
430
+ }
431
+ }
432
+
433
+ private var ultraliteConnectedLive: LiveData<Boolean>? = null
434
+ private var ultraliteControlled: LiveData<Boolean>? = null
435
+ private var batteryStatusObserver: LiveData<BatteryStatus>? = null
436
+
437
+ // Observer references for cleanup
438
+ private var connectedObserver: Observer<Boolean>? = null
439
+ private var controlledObserver: Observer<Boolean>? = null
440
+ private var batteryObserver: Observer<BatteryStatus?>? = null
441
+
442
+ init {
443
+ this.type = DeviceTypes.MACH1
444
+ Log.d(TAG, "Mach1 constructor started")
445
+
446
+ try {
447
+ // Get context from Bridge (like G1 does)
448
+ this.context = Bridge.getContext()
449
+ Log.d(TAG, "Mach1: Got context from Bridge")
450
+
451
+ hasUltraliteControl = false
452
+ screenIsClear = true
453
+ goHomeHandler = Handler(Looper.getMainLooper())
454
+ screenOffHandler = Handler(Looper.getMainLooper())
455
+ killHandler = Handler(Looper.getMainLooper())
456
+ Log.d(TAG, "Mach1: Handlers created")
457
+
458
+ rowTextsLiveNow = ArrayList<Int>()
459
+
460
+ // Initialize UltraliteSDK with valid context
461
+ Log.d(TAG, "Mach1: About to initialize UltraliteSDK")
462
+ ultraliteSdk = UltraliteSDK.get(context)
463
+ Log.d(TAG, "Mach1: UltraliteSDK initialized")
464
+
465
+ ultraliteListener = UltraliteListener()
466
+ ultraliteSdk!!.addEventListener(ultraliteListener)
467
+ Log.d(TAG, "Mach1: Event listener added")
468
+
469
+ // Set up LiveData observers using observeForever (no LifecycleOwner needed)
470
+ ultraliteConnectedLive = ultraliteSdk!!.getConnected()
471
+ ultraliteControlled = ultraliteSdk!!.getControlledByMe()
472
+ batteryStatusObserver = ultraliteSdk!!.getBatteryStatus()
473
+ Log.d(TAG, "Mach1: LiveData references obtained")
474
+
475
+ // Create observers
476
+ connectedObserver = Observer { isConnected ->
477
+ onUltraliteConnectedChange(isConnected)
478
+ }
479
+
480
+ controlledObserver = Observer { isControlled ->
481
+ onUltraliteControlChanged(isControlled)
482
+ }
483
+
484
+ batteryObserver = Observer { batteryStatus ->
485
+ onUltraliteBatteryChanged(batteryStatus)
486
+ }
487
+
488
+ // Register observers on main thread (observeForever requires main thread)
489
+ Handler(Looper.getMainLooper()).post {
490
+ try {
491
+ ultraliteConnectedLive!!.observeForever(connectedObserver!!)
492
+ Log.d(TAG, "Mach1: Connected observer registered")
493
+
494
+ ultraliteControlled!!.observeForever(controlledObserver!!)
495
+ Log.d(TAG, "Mach1: Controlled observer registered")
496
+
497
+ batteryStatusObserver!!.observeForever(batteryObserver!!)
498
+ Log.d(TAG, "Mach1: Battery observer registered")
499
+
500
+ Log.d(TAG, "Mach1: All observers registered on main thread")
501
+ } catch (e: Exception) {
502
+ Log.e(TAG, "Mach1: Failed to register observers: " + e.message, e)
503
+ }
504
+ }
505
+
506
+ Log.d(TAG, "Mach1 initialized with context and observers")
507
+ } catch (e: Exception) {
508
+ Log.e(TAG, "Mach1 constructor FAILED with exception: " + e.message, e)
509
+ Bridge.log("Mach1 constructor FAILED: " + e.message)
510
+ }
511
+ }
512
+
513
+ fun updateGlassesBrightness(brightness: Int) {
514
+ // TODO: Implement this method
515
+ }
516
+
517
+ fun updateGlassesAutoBrightness(autoBrightness: Boolean) {
518
+ // TODO: Implement this method
519
+ }
520
+
521
+ private fun onUltraliteConnectedChange(isConnected: Boolean) {
522
+ Log.d(TAG, "Ultralite CONNECT changed to: " + isConnected)
523
+ if (isConnected) {
524
+ Log.d(TAG, "Ultralite requesting control...")
525
+ val isControlled = ultraliteSdk!!.requestControl()
526
+ if (isControlled) {
527
+ // setupUltraliteCanvas();
528
+ // changeUltraliteLayout(Layout.CANVAS);
529
+ showHomeScreen()
530
+ } else {
531
+ return
532
+ }
533
+ Log.d(TAG, "Ultralite RESULT control request: " + isControlled)
534
+ updateConnectionState(ConnTypes.CONNECTED)
535
+ // connectionEvent(SmartGlassesConnectionState.CONNECTED);
536
+ } else {
537
+ Log.d(TAG, "Ultralite not connected.")
538
+ updateConnectionState(ConnTypes.DISCONNECTED)
539
+ // connectionEvent(SmartGlassesConnectionState.DISCONNECTED);
540
+ }
541
+ }
542
+
543
+ private fun onUltraliteControlChanged(isControlledByMe: Boolean) {
544
+ Log.d(TAG, "Ultralite CONTROL changed to: " + isControlledByMe)
545
+ if (isControlledByMe) {
546
+ hasUltraliteControl = true
547
+ // connectionEvent(SmartGlassesConnectionState.CONNECTED);
548
+ updateConnectionState(ConnTypes.CONNECTED)
549
+ } else {
550
+ hasUltraliteControl = false
551
+ }
552
+ }
553
+
554
+ private fun onUltraliteBatteryChanged(batteryStatus: BatteryStatus?) {
555
+ // Guard against null batteryStatus which can occur during connection/disconnection
556
+ // See: GLASSLY-OS-154
557
+ if (batteryStatus == null) {
558
+ Log.d(TAG, "Ultralite battery status is null, ignoring")
559
+ return
560
+ }
561
+ Log.d(TAG, "Ultralite new battery status: " + batteryStatus.level)
562
+ DeviceStore.apply("glasses", "batteryLevel", batteryStatus.level)
563
+
564
+ // Match iOS: if we're already connected but weren't fully booted yet (waiting
565
+ // for battery), now that we have battery info we can declare fully booted.
566
+ if (connectionState == ConnTypes.CONNECTED && !fullyBooted) {
567
+ DeviceStore.apply("glasses", "connected", true)
568
+ DeviceStore.apply("glasses", "fullyBooted", true)
569
+ }
570
+ }
571
+
572
+
573
+ protected fun setFontSizes() {
574
+ }
575
+
576
+ fun findCompatibleDeviceNames() {
577
+ Bridge.sendDiscoveredDevice(this.type, "NOTREQUIREDSKIP") // Use this.type to support both Mach1 and Z100
578
+ }
579
+
580
+ fun connectToSmartGlasses() {
581
+ Log.d(TAG, "connectToSmartGlasses running...")
582
+ // int mCount = 10;
583
+ // while ((mConnectState != 2) && (!hasUltraliteControl) && (mCount > 0)){
584
+ // mCount--;
585
+ // try {
586
+ // Log.d(TAG, "Don't have Ultralite yet, let's wait for it...");
587
+ // Thread.sleep(200);
588
+ // } catch (InterruptedException e) {
589
+ // e.printStackTrace();
590
+ // }
591
+ // }
592
+ // Log.d(TAG, "Connected to Ultralites.");
593
+ // Log.d(TAG, "mCOnnectestate: " + mConnectState);
594
+ // Log.d(TAG, "mCOunt: " + mCount);
595
+ // displayReferenceCardSimple("Connected to AugmentOS", "");
596
+ // connectionEvent(mConnectState);
597
+ Log.d(TAG, "connectToSmartGlasses finished")
598
+ }
599
+
600
+ fun displayTextLine(text: String) {
601
+ displayReferenceCardSimple("", text)
602
+ }
603
+
604
+ /**
605
+ * Display pre-wrapped text on the glasses.
606
+ *
607
+ * Text wrapping and processing is handled by DisplayProcessor in React Native.
608
+ * This method is a "dumb pipe" - it just sends the text to the Vuzix SDK.
609
+ */
610
+ fun displayTextWall(text: String) {
611
+ if (screenToggleOff) {
612
+ return
613
+ }
614
+
615
+ goHomeHandler!!.removeCallbacksAndMessages(null)
616
+ goHomeHandler!!.removeCallbacksAndMessages(goHomeRunnable)
617
+
618
+ // Text is already wrapped by DisplayProcessor - just send it
619
+ changeUltraliteLayout(Layout.TEXT_BOTTOM_LEFT_ALIGN)
620
+ ultraliteSdk!!.sendText(text)
621
+
622
+ if (ultraliteCanvas != null) {
623
+ ultraliteCanvas!!.commit()
624
+ }
625
+ screenIsClear = false
626
+ }
627
+
628
+ /**
629
+ * Display pre-composed double text wall (two columns) on the glasses.
630
+ *
631
+ * NOTE: DisplayProcessor now composes double_text_wall into a single text_wall
632
+ * with pixel-precise column alignment using ColumnComposer. This method may
633
+ * not be called anymore, but is kept for backwards compatibility.
634
+ *
635
+ * Column composition is handled by DisplayProcessor in React Native.
636
+ * This method is a "dumb pipe" - it just sends the text to the Vuzix SDK.
637
+ */
638
+ fun displayDoubleTextWall(textTop: String, textBottom: String) {
639
+ if (screenToggleOff) {
640
+ return
641
+ }
642
+
643
+ goHomeHandler!!.removeCallbacksAndMessages(null)
644
+ goHomeHandler!!.removeCallbacksAndMessages(goHomeRunnable)
645
+
646
+ // Text is already composed by DisplayProcessor's ColumnComposer
647
+ // Just combine and send - no custom logic needed
648
+ val combinedText = textTop + "\n\n\n" + textBottom
649
+
650
+ changeUltraliteLayout(Layout.TEXT_BOTTOM_LEFT_ALIGN)
651
+ ultraliteSdk!!.sendText(combinedText)
652
+
653
+ if (ultraliteCanvas != null) {
654
+ ultraliteCanvas!!.commit()
655
+ }
656
+ screenIsClear = false
657
+ }
658
+
659
+ fun displayCustomContent(json: String) {
660
+ displayReferenceCardSimple("CustomDisplayNotImplemented", json)
661
+ }
662
+
663
+
664
+ fun showNaturalLanguageCommandScreen(prompt: String, naturalLanguageInput: String) {
665
+ // int boxDelta = 3;
666
+ //
667
+ // if (connectedGlasses != null) {
668
+ // connectedGlasses.clear();
669
+ // showPromptCircle();
670
+ //
671
+ // //show the prompt
672
+ // lastLocNaturalLanguageArgsTextView = displayText(new TextLineSG(prompt, SMALL_FONT), new Point(0, 11), true);
673
+ // lastLocNaturalLanguageArgsTextView = new Point(lastLocNaturalLanguageArgsTextView.x, lastLocNaturalLanguageArgsTextView.y + boxDelta); //margin down a tad
674
+ //
675
+ // //show the final "finish command" prompt
676
+ // int finishY = 90;
677
+ // displayLine(new Point(0, finishY), new Point(100, finishY));
678
+ // displayText(new TextLineSG(finishNaturalLanguageString, SMALL_FONT), new Point(0, finishY + 2), true);
679
+ //
680
+ // //show the natural language args in a scroll box
681
+ //// ArrayList<TextLineSG> nli = new ArrayList<>();
682
+ //// nli.add(new TextLineSG(naturalLanguageInput, SMALL_FONT));
683
+ //// lastLocNaturalLanguageArgsTextView = scrollTextShow(nli, startScrollBoxY.y + boxDelta, finishY - boxDelta);
684
+ // }
685
+ }
686
+
687
+ fun updateNaturalLanguageCommandScreen(naturalLanguageArgs: String) {
688
+ // Log.d(TAG, "Displaynig: " + naturalLanguageArgs);
689
+ // displayText(new TextLineSG(naturalLanguageArgs, SMALL_FONT), new Point(0, lastLocNaturalLanguageArgsTextView.y));
690
+ }
691
+
692
+ fun blankScreen() {
693
+ // if (connectedGlasses != null){
694
+ // connectedGlasses.clear();
695
+ // }
696
+ }
697
+
698
+ fun destroy() {
699
+ try {
700
+ // Remove LiveData observers (using observeForever, so use removeObserver)
701
+ if (ultraliteConnectedLive != null && connectedObserver != null) {
702
+ ultraliteConnectedLive!!.removeObserver(connectedObserver!!)
703
+ }
704
+ if (ultraliteControlled != null && controlledObserver != null) {
705
+ ultraliteControlled!!.removeObserver(controlledObserver!!)
706
+ }
707
+ if (batteryStatusObserver != null && batteryObserver != null) {
708
+ batteryStatusObserver!!.removeObserver(batteryObserver!!)
709
+ }
710
+
711
+ if (ultraliteSdk != null) {
712
+ // Remove event listeners and release control
713
+ ultraliteSdk!!.removeEventListener(ultraliteListener)
714
+ ultraliteSdk!!.releaseControl()
715
+ ultraliteSdk = null // Nullify reference
716
+ }
717
+
718
+ // Cancel all pending handlers and callbacks
719
+ if (goHomeHandler != null) {
720
+ goHomeHandler!!.removeCallbacksAndMessages(null)
721
+ }
722
+ if (screenOffHandler != null) {
723
+ screenOffHandler!!.removeCallbacksAndMessages(null)
724
+ }
725
+ if (killHandler != null) {
726
+ killHandler!!.removeCallbacksAndMessages(null)
727
+ }
728
+
729
+ // Clear canvas and other resources
730
+ if (ultraliteCanvas != null) {
731
+ ultraliteCanvas!!.clear()
732
+ ultraliteCanvas!!.commit()
733
+ ultraliteCanvas = null
734
+ }
735
+
736
+ // Reset state variables
737
+ rowTextsLiveNow!!.clear()
738
+ screenToggleOff = false
739
+ screenIsClear = true
740
+ lastTapTime = 0
741
+ totalDashboardsIdk = 0
742
+ currentUltraliteLayout = null
743
+
744
+ // Free up references
745
+ this.context = null
746
+ connectedObserver = null
747
+ controlledObserver = null
748
+ batteryObserver = null
749
+
750
+ Log.d(TAG, "UltraliteSGC destroyed successfully.")
751
+ } catch (e: Exception) {
752
+ Log.e(TAG, "Error during destroy: ", e)
753
+ }
754
+ }
755
+
756
+
757
+ fun showHomeScreen() {
758
+ Log.d(TAG, "SHOW HOME SCREEN")
759
+ ultraliteSdk!!.screenOff()
760
+ screenIsClear = true
761
+ }
762
+
763
+ fun setupUltraliteCanvas() {
764
+ Log.d(TAG, "Setting up ultralite canvas")
765
+ if (ultraliteSdk != null) {
766
+ ultraliteCanvas = ultraliteSdk!!.getCanvas()
767
+ }
768
+ }
769
+
770
+ fun changeUltraliteLayout(chosenLayout: Layout) {
771
+ //don't update layout if it's already setup
772
+ if (currentUltraliteLayout != null && currentUltraliteLayout == chosenLayout) {
773
+ return
774
+ }
775
+
776
+ ultraliteSdk!!.screenOn()
777
+
778
+ currentUltraliteLayout = chosenLayout
779
+ ultraliteSdk!!.setLayout(chosenLayout, 0, true, false, 2)
780
+
781
+ if (chosenLayout == Layout.CANVAS) {
782
+ if (ultraliteCanvas == null) {
783
+ setupUltraliteCanvas()
784
+ }
785
+ }
786
+ }
787
+
788
+ // public void startScrollingTextViewMode(String title){
789
+ // super.startScrollingTextViewMode(title);
790
+
791
+ // if (ultraliteSdk == null) {
792
+ // return;
793
+ // }
794
+
795
+ // //clear the screen
796
+ // ultraliteCanvas.clear();
797
+ // drawTextOnUltralite(title);
798
+ // }
799
+
800
+
801
+ /**
802
+ * Draw text on Ultralite canvas.
803
+ * Text is expected to be pre-wrapped by DisplayProcessor.
804
+ */
805
+ fun drawTextOnUltralite(text: String) {
806
+ val ultraliteColor = UltraliteColor.WHITE
807
+ val ultraliteAnchor = Anchor.TOP_LEFT
808
+ val ultraliteAlignment = TextAlignment.LEFT
809
+ changeUltraliteLayout(Layout.CANVAS)
810
+ ultraliteCanvas!!.clear()
811
+ ultraliteCanvas!!.clearBackground(UltraliteColor.DIM)
812
+ ultraliteCanvas!!.createText(text, ultraliteAlignment, ultraliteColor, ultraliteAnchor, true)
813
+ ultraliteCanvas!!.commit()
814
+ screenIsClear = false
815
+ }
816
+
817
+ // public Bitmap getBitmapFromDrawable(Resources res) {
818
+ // return BitmapFactory.decodeResource(res, R.drawable.vuzix_shield);
819
+ // }
820
+
821
+ // public void displayReferenceCardSimple(String title, String body, int lingerTime){
822
+ // if (!isConnected()) {
823
+ // Log.d(TAG, "Not showing reference card because not connected to Ultralites...");
824
+ // return;
825
+ // }
826
+ //
827
+ //// String [] bulletPoints = {"first one", "second one", "dogs and cats"};
828
+ //// displayBulletList("Cool Bullets:", bulletPoints, 15);
829
+ //
830
+ // Log.d(TAG, "Sending text to Ultralite SDK: \n" + body);
831
+ //// ultraliteSdk.sendText("hello world"); //this is BROKEN in Vuzix ultralite 0.4.2 SDK - crashes Vuzix OEM Platform android app
832
+ //
833
+ // //edit the text to add new lines to it because ultralite wrapping doesn't work
834
+ //// String titleWrapped = addNewlineEveryNWords(title, 6);
835
+ //// String bodyWrapped = addNewlineEveryNWords(body, 6);
836
+ //
837
+ // //display the title at the top of the screen
838
+ // UltraliteColor ultraliteColor = UltraliteColor.WHITE;
839
+ // Anchor ultraliteAnchor = Anchor.TOP_LEFT;
840
+ // TextAlignment ultraliteAlignment = TextAlignment.LEFT;
841
+ // changeUltraliteLayout(Layout.CANVAS);
842
+ // ultraliteCanvas.clear();
843
+ // ultraliteCanvas.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, ultraliteLeftSidePixelBuffer, 120, 640 - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true);
844
+ // ultraliteCanvas.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.MIDDLE_LEFT, ultraliteLeftSidePixelBuffer, 0, 640 - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true);
845
+ // ultraliteCanvas.commit();
846
+ // screenIsClear = false;
847
+ //
848
+ // homeScreenInNSeconds(lingerTime);
849
+ // }
850
+
851
+ // public void setFontSize(SmartGlassesFontSize fontSize){
852
+ // int textSize;
853
+ // switch (fontSize){
854
+ // case SMALL:
855
+ // textSize = 24;
856
+ // maxLines = 14;
857
+ // maxCharsPerLine = 42;
858
+ // break;
859
+ // case MEDIUM:
860
+ // textSize = 29;
861
+ // maxLines = 12; // Adjusted from 11.5 for practical use
862
+ // maxCharsPerLine = 38; // Assuming max 27 characters fit per line on your display
863
+ // break;
864
+ // case LARGE:
865
+ // textSize = 40;
866
+ // maxLines = 7;
867
+ // maxCharsPerLine = 28;
868
+ // break;
869
+ // default:
870
+ // throw new IllegalArgumentException("Unknown font size: " + fontSize);
871
+ // }
872
+ // ultraliteSdk.setFont(null, 0, textSize);
873
+ // }
874
+
875
+ fun displayReferenceCardSimple(titleStr: String, bodyStr: String) {
876
+ if (screenToggleOff) {
877
+ return
878
+ }
879
+
880
+ val title = maybeReverseRTLString(titleStr)
881
+ val body = maybeReverseRTLString(bodyStr)
882
+ if (connectionState != ConnTypes.CONNECTED) {
883
+ Log.d(TAG, "Not showing reference card because not connected to Ultralites...")
884
+ return
885
+ }
886
+
887
+ changeUltraliteLayout(Layout.CANVAS)
888
+ ultraliteCanvas!!.clear()
889
+
890
+ // String [] bulletPoints = {"first one", "second one", "dogs and cats"};
891
+ // displayBulletList("Cool Bullets:", bulletPoints, 15);
892
+
893
+ Log.d(TAG, "Sending text to Ultralite SDK: \n" + body)
894
+ // ultraliteSdk.sendText("hello world"); //this is BROKEN in Vuzix ultralite 0.4.2 SDK - crashes Vuzix OEM Platform android app
895
+
896
+ //edit the text to add new lines to it because ultralite wrapping doesn't work
897
+ // String titleWrapped = addNewlineEveryNWords(title, 6);
898
+ // String bodyWrapped = addNewlineEveryNWords(body, 6);
899
+
900
+ //display title top of scren adn text middle of screen
901
+ // UltraliteColor ultraliteColor = UltraliteColor.WHITE;
902
+ // Anchor ultraliteAnchor = Anchor.TOP_LEFT;
903
+ // TextAlignment ultraliteAlignment = TextAlignment.LEFT;
904
+ // ultraliteCanvas.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, ultraliteLeftSidePixelBuffer, 120, 640 - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true);
905
+ // ultraliteCanvas.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.MIDDLE_LEFT, ultraliteLeftSidePixelBuffer, 0, 640 - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true);
906
+
907
+ //concat body and title, put text on top right of screen (to not block main view)
908
+ val ultraliteColor = UltraliteColor.WHITE
909
+ val ultraliteAnchor = Anchor.TOP_CENTER
910
+ val ultraliteAlignment = TextAlignment.LEFT
911
+ //ultraliteCanvas.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, (640 / 2) - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true);
912
+ if (!title.isEmpty() && title != "") {
913
+ ultraliteCanvas!!.createText(title + ": " + body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, 640 / 2, -1, TextWrapMode.WRAP, true)
914
+ } else {
915
+ ultraliteCanvas!!.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, 640 / 2, -1, TextWrapMode.WRAP, true)
916
+ }
917
+
918
+ //NOTE:
919
+ // int createText(@NonNull
920
+ // String text,
921
+ // @NonNull
922
+ // TextAlignment alignment,
923
+ // @NonNull
924
+ // UltraliteColor color,
925
+ // @NonNull
926
+ // Anchor anchor,
927
+ // int offsetX,
928
+ // int offsetY,
929
+ // int width,
930
+ // int height,
931
+ // @Nullable
932
+ // TextWrapMode wrap,
933
+ // boolean visible)
934
+
935
+ ultraliteCanvas!!.commit()
936
+ screenIsClear = false
937
+ }
938
+
939
+
940
+ fun displayBulletList(title: String, bullets: Array<String>) {
941
+ displayBulletList(title, bullets, 14)
942
+ }
943
+
944
+ fun displayRowsCard(rowStrings: Array<String>) {
945
+ displayRowsCard(rowStrings, cardLingerTime)
946
+ }
947
+
948
+ fun displayRowsCard(rowStringList: Array<String>, lingerTime: Int) {
949
+ if (screenToggleOff) {
950
+ return
951
+ }
952
+
953
+ val rowStrings = maybeReverseRTLStringList(rowStringList)
954
+ if (connectionState != ConnTypes.CONNECTED) {
955
+ Log.d(TAG, "Not showing rows card because not connected to Ultralites...")
956
+ return
957
+ }
958
+
959
+ // changeUltraliteLayout(Layout.CANVAS);
960
+ // ultraliteCanvas.clear();
961
+
962
+ //make lines to draw on screen to delineate rows
963
+ val line_thickness = 3
964
+ var y = 120
965
+ while (y < 480) {
966
+ ultraliteCanvas!!.clearBackgroundRect(0, y, 640, line_thickness, UltraliteColor.DIM)
967
+ y += 120
968
+ }
969
+
970
+ //clear old text
971
+ for (i in 0 until rowTextsLiveNow!!.size) {
972
+ ultraliteCanvas!!.removeText(i)
973
+ }
974
+ //old way to clear old text - vuzix ultralite sdk bug that clear background doesn't clear text?
975
+ // for (int y = 0; y < 480; y += 120) {
976
+ // //clear previous text
977
+ // ultraliteCanvas.clearBackgroundRect(0, y + line_thickness, 640, 120 - line_thickness, UltraliteColor.DIM);
978
+ // ultraliteCanvas.clearBackgroundRect(0, y + line_thickness, 640, 120 - line_thickness, UltraliteColor.BLACK);
979
+ // }
980
+ // ultraliteCanvas.commit();
981
+
982
+ //display the title at the top of the screen
983
+ val ultraliteColor = UltraliteColor.WHITE
984
+ val ultraliteAnchor = Anchor.TOP_LEFT
985
+ val ultraliteAlignment = TextAlignment.LEFT
986
+
987
+ //if no input, just show the lines
988
+ if (rowStrings.isEmpty()) {
989
+ ultraliteCanvas!!.commit()
990
+ screenIsClear = false
991
+ return
992
+ }
993
+
994
+ //go throw rows, draw the text, don't do more than 4
995
+ val y_start_height = 55
996
+ // Reverse rowStrings array
997
+ rowStrings.reverse()
998
+ val numRows = 4
999
+ val actualRows = Math.min(rowStrings.size, numRows)
1000
+ for (i in 0 until actualRows) {
1001
+ // Calculate the offset to start from the bottom for 1, 2, or 3 values
1002
+ val yOffset = (numRows - actualRows) * 112
1003
+ val textId = ultraliteCanvas!!.createText(rowStrings[i], TextAlignment.CENTER, UltraliteColor.WHITE, Anchor.TOP_LEFT, ultraliteLeftSidePixelBuffer, y_start_height + yOffset + (i * 112), 640 - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true)
1004
+ rowTextsLiveNow!!.add(textId)
1005
+ }
1006
+
1007
+ ultraliteCanvas!!.commit()
1008
+ screenIsClear = false
1009
+ }
1010
+
1011
+ fun displayBulletList(title: String, bulletList: Array<String>, lingerTime: Int) {
1012
+ if (screenToggleOff) {
1013
+ return
1014
+ }
1015
+
1016
+ val bullets = maybeReverseRTLStringList(bulletList)
1017
+ if (connectionState != ConnTypes.CONNECTED) {
1018
+ Log.d(TAG, "Not showing bullet point list because not connected to Ultralites...")
1019
+ return
1020
+ }
1021
+
1022
+ Log.d(TAG, "Sending bullets to Ultralite SDK: " + title)
1023
+
1024
+ //display the title at the top of the screen
1025
+ val ultraliteColor = UltraliteColor.WHITE
1026
+ val ultraliteAnchor = Anchor.TOP_LEFT
1027
+ val ultraliteAlignment = TextAlignment.LEFT
1028
+ changeUltraliteLayout(Layout.CANVAS)
1029
+ ultraliteCanvas!!.clear()
1030
+
1031
+ ultraliteCanvas!!.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true)
1032
+ var displaceY = 25
1033
+ val displaceX = 25
1034
+ for (bullet in bullets) {
1035
+ ultraliteCanvas!!.createText("⬤ " + bullet, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, displaceX, displaceY, 640 - displaceX, -1, TextWrapMode.WRAP, true)
1036
+ displaceY += 125
1037
+ }
1038
+
1039
+ ultraliteCanvas!!.commit()
1040
+ screenIsClear = false
1041
+ }
1042
+
1043
+ // public void homeScreenInNSeconds(int n){
1044
+ // if (n == -1){
1045
+ // return;
1046
+ // }
1047
+ //
1048
+ // //disconnect after slight delay, so our above text gets a chance to show up
1049
+ // goHomeHandler.removeCallbacksAndMessages(null);
1050
+ // goHomeHandler.removeCallbacksAndMessages(goHomeRunnable);
1051
+ // goHomeRunnable = new Runnable() {
1052
+ // @Override
1053
+ // public void run() {
1054
+ // showHomeScreen();
1055
+ // }};
1056
+ // goHomeHandler.postDelayed(goHomeRunnable, n * 1000);
1057
+ // }
1058
+
1059
+ fun displayBitmap(bmp: Bitmap) {
1060
+ val resizedBmp = Bitmap.createScaledBitmap(bmp, 620, 460, true) // 640 x 480
1061
+
1062
+ changeUltraliteLayout(Layout.CANVAS)
1063
+ screenIsClear = false
1064
+
1065
+ Log.d(TAG, "Sending bitmap to Ultralite")
1066
+ ultraliteCanvas!!.drawBackground(resizedBmp, 50, 80)
1067
+ ultraliteCanvas!!.commit()
1068
+ }
1069
+
1070
+ //don't show images on activelook (screen is too low res)
1071
+ fun displayReferenceCardImage(title: String, body: String, imgUrl: String) {
1072
+ if (screenToggleOff) {
1073
+ return
1074
+ }
1075
+
1076
+ changeUltraliteLayout(Layout.CANVAS)
1077
+ ultraliteCanvas!!.clear()
1078
+
1079
+ //make image
1080
+ //below works, but only for very, very low res/size images
1081
+ val ultraliteImageAnchor = Anchor.CENTER
1082
+ Picasso.get()
1083
+ .load(imgUrl)
1084
+ .into(object : Target {
1085
+ override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
1086
+ // Use the bitmap
1087
+ // LVGLImage ultraliteImage = LVGLImage.fromBitmap(getBitmapFromDrawable(context.getResources()), CF_INDEXED_2_BIT);
1088
+ // LVGLImage ultraliteImage = LVGLImage.fromBitmap(bitmap, CF_INDEXED_2_BIT);
1089
+ changeUltraliteLayout(Layout.CANVAS)
1090
+
1091
+ //send text first, cuz this is fast
1092
+ ultraliteCanvas!!.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true)
1093
+ ultraliteCanvas!!.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.BOTTOM_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true)
1094
+ ultraliteCanvas!!.commit()
1095
+ screenIsClear = false
1096
+
1097
+ Log.d(TAG, "Sending image to Ultralite")
1098
+ // ultraliteCanvas.createImage(ultraliteImage, ultraliteImageAnchor, 0, 0, true);
1099
+ ultraliteCanvas!!.drawBackground(bitmap!!, 0, 0)
1100
+
1101
+ //sending text again to ultralite in case image overwrote it
1102
+ // ultraliteCanvas.createText(title + "2", TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.BOTTOM_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true);
1103
+ // ultraliteCanvas.createText(body + "2", TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.MIDDLE_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true);
1104
+ // ultraliteCanvas.commit();
1105
+
1106
+ // //display the title at the top of the screen
1107
+ // UltraliteColor ultraliteColor = UltraliteColor.WHITE;
1108
+ // TextAlignment ultraliteAlignment = TextAlignment.LEFT;
1109
+ // // ultraliteCanvas.clearBackground(UltraliteColor.DIM);
1110
+ // ultraliteCanvas.createText(titleWrapped, ultraliteAlignment, ultraliteColor, Anchor.TOP_LEFT, true); //, 0, 0, -1, -1, TextWrapMode.WRAP, true);
1111
+ // ultraliteCanvas.createText(bodyWrapped, ultraliteAlignment, ultraliteColor, Anchor.BOTTOM_LEFT, true); //, 0, 0, -1, -1, TextWrapMode.WRAP, true);
1112
+ // ultraliteCanvas.commit();
1113
+ }
1114
+
1115
+ override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {
1116
+ // Handle the error
1117
+ Log.d(TAG, "Bitmap failed")
1118
+ e!!.printStackTrace()
1119
+ }
1120
+
1121
+ override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
1122
+ // Called before the image is loaded. You can set a placeholder if needed.
1123
+ }
1124
+ })
1125
+
1126
+ //edit the text to add new lines to it because ultralite wrapping doesn't work
1127
+ // String titleWrapped = addNewlineEveryNWords(title, 6);
1128
+ // String bodyWrapped = addNewlineEveryNWords(body, 6);
1129
+ //
1130
+ // //display the title at the top of the screen
1131
+ // UltraliteColor ultraliteColor = UltraliteColor.WHITE;
1132
+ // TextAlignment ultraliteAlignment = TextAlignment.LEFT;
1133
+ // //ultraliteCanvas.clearBackground(UltraliteColor.DIM);
1134
+ // ultraliteCanvas.createText(titleWrapped, ultraliteAlignment, ultraliteColor, Anchor.TOP_LEFT, true); //, 0, 0, -1, -1, TextWrapMode.WRAP, true);
1135
+ // ultraliteCanvas.createText(bodyWrapped, ultraliteAlignment, ultraliteColor, Anchor.BOTTOM_LEFT, true); //, 0, 0, -1, -1, TextWrapMode.WRAP, true);
1136
+ // ultraliteCanvas.commit();
1137
+ // screenIsClear = false;
1138
+ }
1139
+
1140
+ //handles text wrapping, returns final position of last line printed
1141
+ // private Point displayText(TextLineSG textLine, Point percentLoc, boolean centered){
1142
+ // if (!isConnected()){
1143
+ // return null;
1144
+ // }
1145
+ //
1146
+ // //get info about the wrapping
1147
+ // Pair wrapInfo = computeStringWrapInfo(textLine);
1148
+ // int numWraps = (int)wrapInfo.first;
1149
+ // int wrapLenNumChars = (int)wrapInfo.second;
1150
+ //
1151
+ // //loop through the text, writing out individual lines to the glasses
1152
+ // ArrayList<String> chunkedText = new ArrayList<>();
1153
+ // Point textPoint = percentLoc;
1154
+ // int textMarginY = computeMarginPercent(textLine.getFontSizeCode()); //(fontToSize.get(textLine.getFontSize()) * 1.3)
1155
+ // for (int i = 0; i <= numWraps; i++){
1156
+ // int startIdx = wrapLenNumChars * i;
1157
+ // int endIdx = Math.min(startIdx + wrapLenNumChars, textLine.getText().length());
1158
+ // String subText = textLine.getText().substring(startIdx, endIdx).trim();
1159
+ // chunkedText.add(subText);
1160
+ // TextLineSG thisTextLine = new TextLineSG(subText, textLine.getFontSizeCode());
1161
+ // if (!centered) {
1162
+ // sendTextToGlasses(thisTextLine, textPoint);
1163
+ // } else {
1164
+ // int xPercentLoc = computeStringCenterInfo(thisTextLine);
1165
+ // sendTextToGlasses(thisTextLine, new Point(xPercentLoc, textPoint.y));
1166
+ // }
1167
+ // textPoint = new Point(textPoint.x, textPoint.y + pixelToPercent(displayHeightPixels, fontToSize.get(textLine.getFontSizeCode())) + textMarginY); //lower our text for the next loop
1168
+ // }
1169
+ //
1170
+ // return textPoint;
1171
+ // }
1172
+
1173
+ fun stopScrollingTextViewMode() {
1174
+ // if (connectedGlasses == null) {
1175
+ // return;
1176
+ // }
1177
+ //
1178
+ // //clear the screen
1179
+ // connectedGlasses.clear();
1180
+ }
1181
+
1182
+ fun scrollingTextViewIntermediateText(text: String) {
1183
+ }
1184
+
1185
+ fun scrollingTextViewFinalText(text: String) {
1186
+ if (connectionState != ConnTypes.CONNECTED) {
1187
+ return
1188
+ }
1189
+
1190
+ // //save to our saved list of final scrolling text strings
1191
+ // finalScrollingTextStrings.add(text);
1192
+ //
1193
+ // //get the max number of wraps allows
1194
+ // float allowedTextRows = computeAllowedTextRows(fontToSize.get(scrollingTextTitleFontSize), fontToSize.get(scrollingTextTextFontSize), percentToPixel(displayHeightPixels, computeMarginPercent(scrollingTextTextFontSize)));
1195
+ //
1196
+ // //figure out the maximum we can display
1197
+ // int totalRows = 0;
1198
+ // ArrayList<String> finalTextToDisplay = new ArrayList<>();
1199
+ // boolean hitBottom = false;
1200
+ // for (int i = finalScrollingTextStrings.toArray().length - 1; i >= 0; i--){
1201
+ // String finalText = finalScrollingTextStrings.get(i);
1202
+ // //convert to a TextLine type with small font
1203
+ // TextLineSG tlString = new TextLineSG(finalText, SMALL_FONT);
1204
+ // //get info about the wrapping of this string
1205
+ // Pair wrapInfo = computeStringWrapInfo(tlString);
1206
+ // int numWraps = (int)wrapInfo.first;
1207
+ // int wrapLenNumChars = (int)wrapInfo.second;
1208
+ // totalRows += numWraps + 1;
1209
+ //
1210
+ // if (totalRows > allowedTextRows){
1211
+ // finalScrollingTextStrings = finalTextToDisplay;
1212
+ // lastLocScrollingTextView = belowTitleLocScrollingTextView;
1213
+ // //clear the glasses as we hit our limit and need to redraw
1214
+ // connectedGlasses.color((byte)0x00);
1215
+ // connectedGlasses.rectf(percentScreenToPixelsLocation(belowTitleLocScrollingTextView.x, belowTitleLocScrollingTextView.y), percentScreenToPixelsLocation(100, 100));
1216
+ // //stop looping, as we've ran out of room
1217
+ // hitBottom = true;
1218
+ // } else {
1219
+ // finalTextToDisplay.add(0, finalText);
1220
+ // }
1221
+ // }
1222
+ //
1223
+ // //display all of the text that we can
1224
+ // if (hitBottom) { //if we ran out of room, we need to redraw all the text
1225
+ // for (String finalString : finalTextToDisplay) {
1226
+ // TextLineSG tlString = new TextLineSG(finalString, scrollingTextTextFontSize);
1227
+ // //write this text at the last location + margin
1228
+ // Log.d(TAG, "Writing string: " + tlString.getText() + finalTextToDisplay.size());
1229
+ // lastLocScrollingTextView = displayText(tlString, new Point(0, lastLocScrollingTextView.y));
1230
+ // }
1231
+ // } else { //if we didn't hit the bottom, and there's room, we can just display the next line
1232
+ // TextLineSG tlString = new TextLineSG(text, scrollingTextTextFontSize);
1233
+ // lastLocScrollingTextView = displayText(tlString, new Point(0, lastLocScrollingTextView.y));
1234
+ // }
1235
+
1236
+ }
1237
+
1238
+ fun maybeReverseRTLStringList(input: Array<String>): Array<String> {
1239
+ val out = arrayOfNulls<String>(input.size)
1240
+ for (i in 0 until input.size)
1241
+ out[i] = maybeReverseRTLString(input[i])
1242
+ @Suppress("UNCHECKED_CAST")
1243
+ return out as Array<String>
1244
+ }
1245
+
1246
+ fun displayPromptView(prompt: String, options: Array<String>?) {
1247
+ if (connectionState != ConnTypes.CONNECTED) {
1248
+ return
1249
+ }
1250
+
1251
+ // ultraliteCanvas.clear();
1252
+ // connectedGlasses.clear();
1253
+ // showPromptCircle();
1254
+ //
1255
+ // //show the prompt and options, if any
1256
+ // ArrayList<Object> promptPageElements = new ArrayList<>();
1257
+ // promptPageElements.add(new TextLineSG(prompt, LARGE_FONT));
1258
+ // if (options != null) {
1259
+ // //make an array list of options
1260
+ // for (String s : options){
1261
+ // promptPageElements.add(new TextLineSG(s, SMALL_FONT));
1262
+ // }
1263
+ // }
1264
+ // displayLinearStuff(promptPageElements, new Point(0, 11), true);
1265
+ }
1266
+
1267
+ }