@mentra/bluetooth-sdk 0.1.12 → 0.1.13

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 (65) hide show
  1. package/README.md +16 -9
  2. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +51 -3
  3. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +73 -21
  4. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +1 -1
  5. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +190 -26
  6. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdkDebug.kt +14 -0
  7. package/android/src/main/java/com/mentra/bluetoothsdk/ObservableStore.kt +20 -0
  8. package/android/src/main/java/com/mentra/bluetoothsdk/OtaManifest.kt +153 -0
  9. package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +78 -10
  10. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +3 -14
  11. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +3 -6
  12. package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +90 -4
  13. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.kt +3835 -0
  14. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +20 -23
  15. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/{Mach1.java → Mach1.kt} +517 -560
  16. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +8712 -0
  17. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +11 -1
  18. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +3 -13
  19. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +7 -14
  20. package/build/BluetoothSdk.types.d.ts +39 -9
  21. package/build/BluetoothSdk.types.d.ts.map +1 -1
  22. package/build/BluetoothSdk.types.js.map +1 -1
  23. package/build/_private/BluetoothSdkModule.d.ts +8 -6
  24. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  25. package/build/_private/BluetoothSdkModule.js +0 -2
  26. package/build/_private/BluetoothSdkModule.js.map +1 -1
  27. package/build/_private/photoRequestPayload.d.ts +3 -1
  28. package/build/_private/photoRequestPayload.d.ts.map +1 -1
  29. package/build/_private/photoRequestPayload.js +43 -1
  30. package/build/_private/photoRequestPayload.js.map +1 -1
  31. package/build/debug.d.ts +3 -0
  32. package/build/debug.d.ts.map +1 -0
  33. package/build/debug.js +8 -0
  34. package/build/debug.js.map +1 -0
  35. package/build/index.d.ts +1 -1
  36. package/build/index.d.ts.map +1 -1
  37. package/build/index.js +14 -5
  38. package/build/index.js.map +1 -1
  39. package/ios/BluetoothSdkModule.swift +38 -57
  40. package/ios/Source/BluetoothSdkDefaults.swift +23 -3
  41. package/ios/Source/DeviceManager.swift +37 -26
  42. package/ios/Source/DeviceStore.swift +5 -1
  43. package/ios/Source/MentraBluetoothSDK.swift +197 -26
  44. package/ios/Source/MentraBluetoothSDKDebug.swift +12 -0
  45. package/ios/Source/ObservableStore.swift +11 -0
  46. package/ios/Source/OtaManifest.swift +170 -0
  47. package/ios/Source/camera/CameraModels.swift +218 -8
  48. package/ios/Source/controllers/ControllerManager.swift +2 -5
  49. package/ios/Source/controllers/R1.swift +2 -5
  50. package/ios/Source/sgcs/G1.swift +6 -5
  51. package/ios/Source/sgcs/G2.swift +20 -18
  52. package/ios/Source/sgcs/Mach1.swift +6 -5
  53. package/ios/Source/sgcs/MentraLive.swift +129 -33
  54. package/ios/Source/sgcs/MentraNex.swift +6 -5
  55. package/ios/Source/sgcs/SGCManager.swift +3 -5
  56. package/ios/Source/sgcs/Simulated.swift +7 -3
  57. package/ios/Source/status/DeviceStatus.swift +1 -1
  58. package/package.json +6 -1
  59. package/src/BluetoothSdk.types.ts +40 -9
  60. package/src/_private/BluetoothSdkModule.ts +8 -9
  61. package/src/_private/photoRequestPayload.ts +45 -2
  62. package/src/debug.ts +9 -0
  63. package/src/index.ts +23 -6
  64. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +0 -3974
  65. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +0 -7434
@@ -1,608 +1,601 @@
1
- package com.mentra.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.annotation.NonNull;
13
- import androidx.annotation.Nullable;
14
- import androidx.lifecycle.LiveData;
15
- import androidx.lifecycle.Observer;
1
+ package com.mentra.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
16
14
 
17
15
  // Mentra
18
- import com.mentra.bluetoothsdk.sgcs.SGCManager;
19
- import com.mentra.bluetoothsdk.DeviceManager;
20
- import com.mentra.bluetoothsdk.Bridge;
21
- import com.mentra.bluetoothsdk.utils.DeviceTypes;
22
- import com.mentra.bluetoothsdk.utils.ConnTypes;
23
- import com.mentra.bluetoothsdk.utils.BitmapJavaUtils;
24
- import com.mentra.bluetoothsdk.utils.SmartGlassesConnectionState;
25
- import com.mentra.bluetoothsdk.utils.K900ProtocolUtils;
26
- import com.mentra.bluetoothsdk.utils.MessageChunker;
27
- import com.mentra.bluetoothsdk.utils.audio.Lc3Player;
28
- import com.mentra.bluetoothsdk.utils.BlePhotoUploadService;
29
- import com.mentra.bluetoothsdk.DeviceStore;
16
+ import com.mentra.bluetoothsdk.DeviceManager
17
+ import com.mentra.bluetoothsdk.Bridge
18
+ import com.mentra.bluetoothsdk.PhotoRequest
19
+ import com.mentra.bluetoothsdk.utils.DeviceTypes
20
+ import com.mentra.bluetoothsdk.utils.ConnTypes
21
+ import com.mentra.bluetoothsdk.utils.BitmapJavaUtils
22
+ import com.mentra.bluetoothsdk.utils.SmartGlassesConnectionState
23
+ import com.mentra.bluetoothsdk.utils.K900ProtocolUtils
24
+ import com.mentra.bluetoothsdk.utils.MessageChunker
25
+ import com.mentra.bluetoothsdk.utils.audio.Lc3Player
26
+ import com.mentra.bluetoothsdk.utils.BlePhotoUploadService
27
+ import com.mentra.bluetoothsdk.DeviceStore
30
28
 
31
29
  // import com.augmentos.augmentos_core.R;
32
30
  // import com.augmentos.augmentos_core.smarterglassesmanager.smartglassescommunicators.SmartGlassesCommunicator;
33
31
  // import com.augmentos.augmentos_core.smarterglassesmanager.smartglassescommunicators.SmartGlassesFontSize;
34
32
  // import com.augmentos.augmentos_core.smarterglassesmanager.utils.SmartGlassesConnectionState;
35
- import com.squareup.picasso.Picasso;
36
- import com.squareup.picasso.Target;
33
+ import com.squareup.picasso.Picasso
34
+ import com.squareup.picasso.Target
37
35
  // import com.augmentos.augmentos_core.smarterglassesmanager.eventbusmessages.BatteryLevelEvent;
38
36
  // import com.augmentos.augmentos_core.smarterglassesmanager.eventbusmessages.GlassesBluetoothSearchDiscoverEvent;
39
37
  // import com.augmentos.augmentos_core.smarterglassesmanager.eventbusmessages.GlassesDisplayPowerEvent;
40
38
  // import com.augmentos.augmentos_core.smarterglassesmanager.supportedglasses.SmartGlassesDevice;
41
- import com.vuzix.ultralite.Anchor;
42
- import com.vuzix.ultralite.BatteryStatus;
43
- import com.vuzix.ultralite.EventListener;
44
- import com.vuzix.ultralite.Layout;
45
- import com.vuzix.ultralite.TextAlignment;
46
- import com.vuzix.ultralite.TextWrapMode;
47
- import com.vuzix.ultralite.UltraliteColor;
48
- import com.vuzix.ultralite.UltraliteSDK;
39
+ import com.vuzix.ultralite.Anchor
40
+ import com.vuzix.ultralite.BatteryStatus
41
+ import com.vuzix.ultralite.EventListener
42
+ import com.vuzix.ultralite.Layout
43
+ import com.vuzix.ultralite.TextAlignment
44
+ import com.vuzix.ultralite.TextWrapMode
45
+ import com.vuzix.ultralite.UltraliteColor
46
+ import com.vuzix.ultralite.UltraliteSDK
49
47
 
50
- import org.greenrobot.eventbus.EventBus;
48
+ import org.greenrobot.eventbus.EventBus
51
49
 
52
- import java.util.ArrayList;
53
- import java.util.Arrays;
54
- import java.util.Collections;
55
- import java.util.List;
56
- import java.util.Map;
50
+ import java.util.ArrayList
51
+ import java.util.Arrays
52
+ import java.util.Collections
57
53
 
58
54
 
59
55
  //communicate with ActiveLook smart glasses
60
- public class Mach1 extends SGCManager {
61
- private static final String TAG = "WearableAi_UltraliteSGC";
56
+ class Mach1 : SGCManager() {
57
+
58
+ companion object {
59
+ private const val TAG = "WearableAi_UltraliteSGC"
60
+ const val cardLingerTime = 15
61
+
62
+ private const val TAP_DEBOUNCE_TIME = 80L // milliseconds
63
+
64
+ @JvmStatic
65
+ fun maybeReverseRTLString(text: String): String {
66
+ val result = StringBuilder()
67
+ val rtlBuffer = StringBuilder()
68
+
69
+ for (c in text.toCharArray()) {
70
+ if (isRTLCharacter(c)) {
71
+ rtlBuffer.append(c) // Append RTL characters to a buffer
72
+ } else {
73
+ if (rtlBuffer.length > 0) {
74
+ result.append(rtlBuffer.reverse()) // Reverse and append RTL text when a non-RTL character is found
75
+ rtlBuffer.setLength(0) // Clear the buffer
76
+ }
77
+ result.append(c) // Append non-RTL characters directly to the result
78
+ }
79
+ }
62
80
 
63
- UltraliteSDK ultraliteSdk;
64
- UltraliteSDK.Canvas ultraliteCanvas;
65
- UltraliteListener ultraliteListener;
66
- Layout currentUltraliteLayout;
67
- boolean screenToggleOff = false; //should we keep the screen off?
68
- Context context;
69
- public static final int cardLingerTime = 15;
81
+ if (rtlBuffer.length > 0) {
82
+ result.append(rtlBuffer.reverse()) // Append any remaining RTL text in reverse
83
+ }
70
84
 
71
- private ArrayList rowTextsLiveNow;
85
+ return result.toString()
86
+ }
87
+
88
+ private fun isRTLCharacter(c: Char): Boolean {
89
+ val block = Character.UnicodeBlock.of(c)
90
+ return block == Character.UnicodeBlock.ARABIC ||
91
+ block == Character.UnicodeBlock.HEBREW ||
92
+ block == Character.UnicodeBlock.SYRIAC ||
93
+ block == Character.UnicodeBlock.ARABIC_SUPPLEMENT ||
94
+ block == Character.UnicodeBlock.THAANA ||
95
+ block == Character.UnicodeBlock.NKO ||
96
+ block == Character.UnicodeBlock.SAMARITAN ||
97
+ block == Character.UnicodeBlock.MANDAIC ||
98
+ block == Character.UnicodeBlock.ARABIC_EXTENDED_A
99
+ // Add other RTL blocks as needed
100
+ }
101
+ }
102
+
103
+ var ultraliteSdk: UltraliteSDK? = null
104
+ var ultraliteCanvas: UltraliteSDK.Canvas? = null
105
+ var ultraliteListener: UltraliteListener? = null
106
+ var currentUltraliteLayout: Layout? = null
107
+ var screenToggleOff = false //should we keep the screen off?
108
+ var context: Context? = null
109
+
110
+ private var rowTextsLiveNow: ArrayList<Int>? = null
72
111
 
73
112
  //ultralite pixel buffer on left side of screen
74
- int ultraliteLeftSidePixelBuffer = 40;
113
+ var ultraliteLeftSidePixelBuffer = 40
75
114
 
76
115
  //handler to turn off screen
77
- Handler goHomeHandler;
78
- Runnable goHomeRunnable;
116
+ var goHomeHandler: Handler? = null
117
+ var goHomeRunnable: Runnable? = null
79
118
 
80
119
  //handler to turn off screen/toggle
81
- Handler screenOffHandler;
82
- Runnable screenOffRunnable;
120
+ var screenOffHandler: Handler? = null
121
+ var screenOffRunnable: Runnable? = null
83
122
 
84
123
  //handler to check battery life
85
- Handler batteryHandler;
86
- Runnable batteryRunnable;
124
+ var batteryHandler: Handler? = null
125
+ var batteryRunnable: Runnable? = null
87
126
 
88
127
  //handler to disconnect
89
- Handler killHandler;
128
+ var killHandler: Handler? = null
90
129
 
91
- boolean hasUltraliteControl;
92
- boolean screenIsClear;
93
- boolean isHeadUp = false; // Dashboard state toggled by taps
130
+ var hasUltraliteControl = false
131
+ var screenIsClear = false
132
+ var isHeadUp = false // Dashboard state toggled by taps
94
133
  // SmartGlassesDevice smartGlassesDevice;
95
- private static final long TAP_DEBOUNCE_TIME = 80; // milliseconds
96
- private long lastTapTime = 0;
97
- private int totalDashboardsIdk = 0;
134
+ private var lastTapTime = 0L
135
+ private var totalDashboardsIdk = 0
98
136
 
99
- private boolean hasBattery() {
100
- Object level = DeviceStore.INSTANCE.get("glasses", "batteryLevel");
101
- return level instanceof Number && ((Number) level).intValue() != -1;
137
+ private fun hasBattery(): Boolean {
138
+ val level = DeviceStore.get("glasses", "batteryLevel")
139
+ return level is Number && level.toInt() != -1
102
140
  }
103
141
 
104
- private void updateConnectionState(String state) {
105
- boolean isEqual = state.equals(getConnectionState());
142
+ private fun updateConnectionState(state: String) {
143
+ val isEqual = state == connectionState
106
144
  if (isEqual) {
107
- return;
145
+ return
108
146
  }
109
147
 
110
148
  // Update the connection state
111
- DeviceStore.INSTANCE.apply("glasses", "connectionState", state);
149
+ DeviceStore.apply("glasses", "connectionState", state)
112
150
 
113
- if (state.equals(ConnTypes.CONNECTED)) {
151
+ if (state == ConnTypes.CONNECTED) {
114
152
  // Match iOS: only declare fully booted once we have battery info too
115
153
  if (hasBattery()) {
116
- DeviceStore.INSTANCE.apply("glasses", "connected", true);
117
- DeviceStore.INSTANCE.apply("glasses", "fullyBooted", true);
154
+ DeviceStore.apply("glasses", "connected", true)
155
+ DeviceStore.apply("glasses", "fullyBooted", true)
118
156
  }
119
- } else if (state.equals(ConnTypes.DISCONNECTED)) {
120
- DeviceStore.INSTANCE.apply("glasses", "fullyBooted", false);
121
- DeviceStore.INSTANCE.apply("glasses", "connected", false);
157
+ } else if (state == ConnTypes.DISCONNECTED) {
158
+ DeviceStore.apply("glasses", "fullyBooted", false)
159
+ DeviceStore.apply("glasses", "connected", false)
122
160
  }
123
161
  }
124
162
 
125
- @Override
126
- public void setMicEnabled(boolean enabled) {
163
+ override fun setMicEnabled(enabled: Boolean) {
127
164
  }
128
165
 
129
- @Override
130
- public List<String> sortMicRanking(List<String> list) {
131
- return list;
166
+ override fun sortMicRanking(list: MutableList<String>): MutableList<String> {
167
+ return list
132
168
  }
133
169
 
134
- @Override
135
- public void requestPhoto(@NonNull String requestId, @NonNull String appId, @NonNull String size, @Nullable String webhookUrl, @Nullable String authToken, @Nullable String compress, boolean flash, boolean save, boolean sound, @Nullable Long exposureTimeNs, @Nullable Integer iso) {
170
+ override fun requestPhoto(request: PhotoRequest) {
136
171
 
137
172
  }
138
173
 
139
- @Override
140
- public void startStream(@NonNull Map<String, Object> message) {
174
+ override fun startStream(message: MutableMap<String, Any>) {
141
175
 
142
176
  }
143
177
 
144
- @Override
145
- public void stopStream() {
178
+ override fun stopStream() {
146
179
 
147
180
  }
148
181
 
149
- @Override
150
- public void sendStreamKeepAlive(@NonNull Map<String, Object> message) {
182
+ override fun sendStreamKeepAlive(message: MutableMap<String, Any>) {
151
183
 
152
184
  }
153
185
 
154
- @Override
155
- public void startVideoRecording(@NonNull String requestId, boolean save, boolean flash, boolean sound) {
186
+ override fun startVideoRecording(requestId: String, save: Boolean, flash: Boolean, sound: Boolean) {
156
187
 
157
188
  }
158
189
 
159
- @Override
160
- public void stopVideoRecording(@NonNull String requestId) {
190
+ override fun stopVideoRecording(requestId: String) {
161
191
 
162
192
  }
163
193
 
164
- @Override
165
- public void sendButtonPhotoSettings() {
194
+ override fun sendButtonPhotoSettings() {
166
195
 
167
196
  }
168
197
 
169
- @Override
170
- public void sendButtonVideoRecordingSettings() {
198
+ override fun sendButtonVideoRecordingSettings() {
171
199
 
172
200
  }
173
201
 
174
- @Override
175
- public void sendButtonMaxRecordingTime() {
202
+ override fun sendButtonMaxRecordingTime() {
176
203
 
177
204
  }
178
205
 
179
- @Override
180
- public void sendButtonCameraLedSetting() {
206
+ override fun sendButtonCameraLedSetting() {
207
+
208
+ }
181
209
 
210
+ override fun sendCameraFovSetting() {
182
211
  }
183
212
 
184
- @Override
185
- public void sendCameraFovSetting() {
213
+ override fun setBrightness(level: Int, autoMode: Boolean) {
214
+ Bridge.log("Mach1: setBrightness() - level: " + level + "%, autoMode: " + autoMode)
215
+ updateGlassesBrightness(level)
216
+ updateGlassesAutoBrightness(autoMode)
186
217
  }
187
218
 
188
- @Override
189
- public void setBrightness(int level, boolean autoMode) {
190
- Bridge.log("Mach1: setBrightness() - level: " + level + "%, autoMode: " + autoMode);
191
- updateGlassesBrightness(level);
192
- updateGlassesAutoBrightness(autoMode);
219
+ override fun clearDisplay() {
220
+ Bridge.log("Mach1: clearDisplay()")
221
+ blankScreen()
193
222
  }
194
223
 
195
- @Override
196
- public void clearDisplay() {
197
- Bridge.log("Mach1: clearDisplay()");
198
- blankScreen();
224
+ override fun sendText(text: String) {
225
+ Bridge.log("Mach1: sendText() - text: " + text)
226
+ displayTextWall(text)
199
227
  }
200
228
 
201
- @Override
202
- public void sendTextWall(@NonNull String text) {
203
- Bridge.log("Mach1: sendTextWall()");
204
- displayTextWall(text);
229
+ override fun sendTextWall(text: String) {
230
+ Bridge.log("Mach1: sendTextWall()")
231
+ displayTextWall(text)
205
232
  }
206
233
 
207
- @Override
208
- public void sendDoubleTextWall(@NonNull String top, @NonNull String bottom) {
209
- Bridge.log("Mach1: sendDoubleTextWall()");
210
- displayDoubleTextWall(top, bottom);
234
+ override fun sendDoubleTextWall(top: String, bottom: String) {
235
+ Bridge.log("Mach1: sendDoubleTextWall()")
236
+ displayDoubleTextWall(top, bottom)
211
237
  }
212
238
 
213
- @Override
214
- public boolean displayBitmap(@NonNull String base64ImageData, Integer x, Integer y, Integer width, Integer height) {
239
+ override fun displayBitmap(base64ImageData: String, x: Int?, y: Int?, width: Int?, height: Int?): Boolean {
215
240
  try {
216
- Bridge.log("Mach1: displayBitmap() - decoding base64");
241
+ Bridge.log("Mach1: displayBitmap() - decoding base64")
217
242
  // Decode base64 to byte array
218
- byte[] bmpData = android.util.Base64.decode(base64ImageData, android.util.Base64.DEFAULT);
243
+ val bmpData = android.util.Base64.decode(base64ImageData, android.util.Base64.DEFAULT)
219
244
 
220
- if (bmpData == null || bmpData.length == 0) {
221
- Log.e(TAG, "Failed to decode base64 image data");
222
- return false;
245
+ if (bmpData == null || bmpData.isEmpty()) {
246
+ Log.e(TAG, "Failed to decode base64 image data")
247
+ return false
223
248
  }
224
249
 
225
250
  // Convert byte array to Bitmap
226
- Bitmap bitmap = BitmapFactory.decodeByteArray(bmpData, 0, bmpData.length);
251
+ val bitmap = BitmapFactory.decodeByteArray(bmpData, 0, bmpData.size)
227
252
 
228
253
  if (bitmap == null) {
229
- Log.e(TAG, "Failed to decode bitmap from byte array");
230
- return false;
254
+ Log.e(TAG, "Failed to decode bitmap from byte array")
255
+ return false
231
256
  }
232
257
 
233
258
  // Call internal implementation
234
- displayBitmap(bitmap);
235
- return true;
236
- } catch (Exception e) {
237
- Log.e(TAG, "Error displaying bitmap from base64", e);
238
- return false;
259
+ displayBitmap(bitmap)
260
+ return true
261
+ } catch (e: Exception) {
262
+ Log.e(TAG, "Error displaying bitmap from base64", e)
263
+ return false
239
264
  }
240
265
  }
241
266
 
242
- @Override
243
- public void showDashboard() {
267
+ override fun showDashboard() {
244
268
 
245
269
  }
246
270
 
247
- @Override
248
- public void ping() {
271
+ override fun ping() {
249
272
  }
250
273
 
251
- @Override
252
- public void dbg1() {}
274
+ override fun dbg1() {}
253
275
 
254
- @Override
255
- public void dbg2() {}
276
+ override fun dbg2() {}
256
277
 
257
- @Override
258
- public void setDashboardPosition(int height, int depth) {
278
+ override fun setDashboardPosition(height: Int, depth: Int) {
259
279
 
260
280
  }
261
281
 
262
- @Override
263
- public void setHeadUpAngle(int angle) {
282
+ override fun setHeadUpAngle(angle: Int) {
264
283
 
265
284
  }
266
285
 
267
- @Override
268
- public void getBatteryStatus() {
286
+ override fun getBatteryStatus() {
269
287
 
270
288
  }
271
289
 
272
- @Override
273
- public void setSilentMode(boolean enabled) {
290
+ override fun setSilentMode(enabled: Boolean) {
274
291
 
275
292
  }
276
293
 
277
- @Override
278
- public void exit() {
294
+ override fun exit() {
279
295
 
280
296
  }
281
297
 
282
- @Override
283
- public void sendShutdown() {
284
- Bridge.log("sendShutdown - not supported on Mach1");
298
+ override fun sendShutdown() {
299
+ Bridge.log("sendShutdown - not supported on Mach1")
285
300
  }
286
301
 
287
- @Override
288
- public void sendReboot() {
289
- Bridge.log("sendReboot - not supported on Mach1");
302
+ override fun sendReboot() {
303
+ Bridge.log("sendReboot - not supported on Mach1")
290
304
  }
291
305
 
292
- @Override
293
- public void sendRgbLedControl(String requestId, String packageName, String action, String color, int onDurationMs, int offDurationMs, int count) {
294
- Bridge.log("sendRgbLedControl - not supported on Mach1");
295
- Bridge.sendRgbLedControlResponse(requestId, false, "device_not_supported");
306
+ override fun sendRgbLedControl(requestId: String, packageName: String?, action: String, color: String?, onDurationMs: Int, offDurationMs: Int, count: Int) {
307
+ Bridge.log("sendRgbLedControl - not supported on Mach1")
308
+ Bridge.sendRgbLedControlResponse(requestId, false, "device_not_supported")
296
309
  }
297
310
 
298
- @Override
299
- public void disconnect() {
300
- Bridge.log("Mach1: disconnect()");
311
+ override fun disconnect() {
312
+ Bridge.log("Mach1: disconnect()")
301
313
  if (ultraliteSdk != null) {
302
- ultraliteSdk.releaseControl();
303
- updateConnectionState(ConnTypes.DISCONNECTED);
314
+ ultraliteSdk!!.releaseControl()
315
+ updateConnectionState(ConnTypes.DISCONNECTED)
304
316
  }
305
317
  }
306
318
 
307
- @Override
308
- public void forget() {
309
- Bridge.log("Mach1: forget()");
319
+ override fun forget() {
320
+ Bridge.log("Mach1: forget()")
310
321
  // Release control and clean up
311
- destroy();
322
+ destroy()
312
323
  }
313
324
 
314
- @Override
315
- public void findCompatibleDevices() {
316
- Bridge.log("Mach1: findCompatibleDevices()");
317
- findCompatibleDeviceNames();
325
+ override fun findCompatibleDevices() {
326
+ Bridge.log("Mach1: findCompatibleDevices()")
327
+ findCompatibleDeviceNames()
318
328
  }
319
329
 
320
- @Override
321
- public void stopScan() {
322
- Bridge.log("Mach1: stopScan() - no active BLE scanner owned by Mach1");
330
+ override fun stopScan() {
331
+ Bridge.log("Mach1: stopScan() - no active BLE scanner owned by Mach1")
323
332
  }
324
333
 
325
- @Override
326
- public void connectById(@NonNull String id) {
327
- Bridge.log("Mach1: connectById() - id: " + id);
334
+ override fun connectById(id: String) {
335
+ Bridge.log("Mach1: connectById() - id: " + id)
328
336
  // The Mach1 uses UltraliteSDK which handles connection internally
329
337
  // We just need to trigger the connection process
330
- connectToSmartGlasses();
338
+ connectToSmartGlasses()
331
339
  }
332
340
 
333
- @NonNull
334
- @Override
335
- public String getConnectedBluetoothName() {
341
+ override fun getConnectedBluetoothName(): String {
336
342
  // Mach1/Ultralite SDK doesn't expose the peripheral name directly
337
343
  // Return device type if connected
338
344
  if (ultraliteSdk != null) {
339
- LiveData<Boolean> connected = ultraliteSdk.getConnected();
340
- if (connected != null && Boolean.TRUE.equals(connected.getValue())) {
341
- return "Vuzix Ultralite";
345
+ val connected = ultraliteSdk!!.getConnected()
346
+ if (connected != null && java.lang.Boolean.TRUE == connected.value) {
347
+ return "Vuzix Ultralite"
342
348
  }
343
349
  }
344
- return "";
350
+ return ""
345
351
  }
346
352
 
347
- @Override
348
- public void cleanup() {
349
- destroy();
353
+ override fun cleanup() {
354
+ destroy()
350
355
  }
351
356
 
352
- @Override
353
- public void requestWifiScan() {
357
+ override fun requestWifiScan() {
354
358
 
355
359
  }
356
360
 
357
- @Override
358
- public void sendWifiCredentials(@NonNull String ssid, @NonNull String password) {
361
+ override fun sendWifiCredentials(ssid: String, password: String) {
359
362
 
360
363
  }
361
364
 
362
- @Override
363
- public void forgetWifiNetwork(String ssid) {
365
+ override fun forgetWifiNetwork(ssid: String) {
364
366
  // Mach1 doesn't support WiFi
365
367
  }
366
368
 
367
- @Override
368
- public void sendHotspotState(boolean enabled) {
369
+ override fun sendHotspotState(enabled: Boolean) {
369
370
  // Mach1 doesn't support hotspot
370
371
  }
371
372
 
372
- @Override
373
- public void sendUserEmailToGlasses(String email) {
373
+ override fun sendUserEmailToGlasses(email: String) {
374
374
  // Mach1 doesn't support user email (no ASG client)
375
375
  }
376
376
 
377
- @Override
378
- public void sendIncidentId(String incidentId, String apiBaseUrl) {
377
+ override fun sendIncidentId(incidentId: String, apiBaseUrl: String?) {
379
378
  // Mach1 doesn't support incident reporting (no ASG client)
380
379
  }
381
380
 
382
- @Override
383
- public void queryGalleryStatus() {
381
+ override fun queryGalleryStatus() {
384
382
 
385
383
  }
386
384
 
387
- @Override
388
- public void sendGalleryMode() {
385
+ override fun sendGalleryMode() {
389
386
  // Mach1 doesn't have a built-in camera/gallery system
390
- Bridge.log("Mach1: sendGalleryModeActive - not supported on Mach1");
387
+ Bridge.log("Mach1: sendGalleryModeActive - not supported on Mach1")
391
388
  }
392
389
 
393
- @Override
394
- public void requestVersionInfo() {
390
+ override fun requestVersionInfo() {
395
391
  // Mach1 doesn't support version info requests
396
- Bridge.log("Mach1: requestVersionInfo - not supported on Mach1");
392
+ Bridge.log("Mach1: requestVersionInfo - not supported on Mach1")
397
393
  }
398
394
 
399
- public class UltraliteListener implements EventListener{
400
- @Override
401
- public void onTap(int tapCount) {
402
- long currentTime = System.currentTimeMillis();
395
+ inner class UltraliteListener : EventListener {
396
+ override fun onTap(tapCount: Int) {
397
+ val currentTime = System.currentTimeMillis()
403
398
  if (currentTime - lastTapTime < TAP_DEBOUNCE_TIME) {
404
- Log.d(TAG, "Ignoring duplicate tap event");
405
- return;
399
+ Log.d(TAG, "Ignoring duplicate tap event")
400
+ return
406
401
  }
407
- totalDashboardsIdk++;
408
- Log.d(TAG, "TOTAL NUMBER OF DASHBOARD TOGGLEZ: " + totalDashboardsIdk);
402
+ totalDashboardsIdk++
403
+ Log.d(TAG, "TOTAL NUMBER OF DASHBOARD TOGGLEZ: " + totalDashboardsIdk)
409
404
 
410
- lastTapTime = currentTime;
411
- Log.d(TAG, "Ultralite go tap n times: " + tapCount);
405
+ lastTapTime = currentTime
406
+ Log.d(TAG, "Ultralite go tap n times: " + tapCount)
412
407
 
413
408
  // Toggle dashboard on 2+ taps (same as iOS implementation)
414
409
  if (tapCount >= 2) {
415
- isHeadUp = !isHeadUp;
410
+ isHeadUp = !isHeadUp
416
411
  // Notify DeviceManager of head up state change (same as G1 does with IMU)
417
- DeviceStore.INSTANCE.apply("glasses", "headUp", isHeadUp);
418
- Log.d(TAG, "Mach1: Dashboard toggled via tap, isHeadUp: " + isHeadUp);
412
+ DeviceStore.apply("glasses", "headUp", isHeadUp)
413
+ Log.d(TAG, "Mach1: Dashboard toggled via tap, isHeadUp: " + isHeadUp)
419
414
 
420
415
  // Auto turn off the dashboard after 15 seconds
421
416
  if (isHeadUp) {
422
- goHomeHandler.postDelayed(() -> {
417
+ goHomeHandler!!.postDelayed({
423
418
  if (isHeadUp) {
424
- isHeadUp = false;
425
- DeviceStore.INSTANCE.apply("glasses", "headUp", false);
426
- Log.d(TAG, "Mach1: Auto-disabling dashboard after 15 seconds");
419
+ isHeadUp = false
420
+ DeviceStore.apply("glasses", "headUp", false)
421
+ Log.d(TAG, "Mach1: Auto-disabling dashboard after 15 seconds")
427
422
  }
428
- }, 15000);
423
+ }, 15000L)
429
424
  }
430
425
  }
431
426
  }
432
427
 
433
- @Override
434
- public void onDisplayTimeout() {
435
- Log.d(TAG, "Ultralite display timeout.");
428
+ override fun onDisplayTimeout() {
429
+ Log.d(TAG, "Ultralite display timeout.")
436
430
  }
437
431
 
438
- @Override
439
- public void onPowerButtonPress(boolean turningOn) {
432
+ override fun onPowerButtonPress(turningOn: Boolean) {
440
433
  //since we implement our own state for the power turn on/off, we ignore what the ultralite thinks ('turningOn') and use our own state
441
- Log.d(TAG, "Ultralites power button pressed: " + turningOn);
434
+ Log.d(TAG, "Ultralites power button pressed: " + turningOn)
442
435
 
443
436
  //flip value of screen toggle
444
- screenToggleOff = !screenToggleOff;
437
+ screenToggleOff = !screenToggleOff
445
438
 
446
439
  if (!screenToggleOff) {
447
- Log.d(TAG, "screen toggle off NOT on, showing turn ON message");
440
+ Log.d(TAG, "screen toggle off NOT on, showing turn ON message")
448
441
  // EventBus.getDefault().post(new GlassesDisplayPowerEvent(screenToggleOff));
449
442
  } else {
450
- Log.d(TAG, "screen toggle off IS on");
443
+ Log.d(TAG, "screen toggle off IS on")
451
444
  }
452
445
  }
453
446
  }
454
- private LiveData<Boolean> ultraliteConnectedLive;
455
- private LiveData<Boolean> ultraliteControlled;
456
- private LiveData<BatteryStatus> batteryStatusObserver;
447
+
448
+ private var ultraliteConnectedLive: LiveData<Boolean>? = null
449
+ private var ultraliteControlled: LiveData<Boolean>? = null
450
+ private var batteryStatusObserver: LiveData<BatteryStatus>? = null
457
451
 
458
452
  // Observer references for cleanup
459
- private Observer<Boolean> connectedObserver;
460
- private Observer<Boolean> controlledObserver;
461
- private Observer<BatteryStatus> batteryObserver;
453
+ private var connectedObserver: Observer<Boolean>? = null
454
+ private var controlledObserver: Observer<Boolean>? = null
455
+ private var batteryObserver: Observer<BatteryStatus?>? = null
462
456
 
463
- public Mach1() {
464
- super();
465
- this.type = DeviceTypes.MACH1;
466
- Log.d(TAG, "Mach1 constructor started");
457
+ init {
458
+ this.type = DeviceTypes.MACH1
459
+ Log.d(TAG, "Mach1 constructor started")
467
460
 
468
461
  try {
469
462
  // Get context from Bridge (like G1 does)
470
- this.context = Bridge.getContext();
471
- Log.d(TAG, "Mach1: Got context from Bridge");
463
+ this.context = Bridge.getContext()
464
+ Log.d(TAG, "Mach1: Got context from Bridge")
472
465
 
473
- hasUltraliteControl = false;
474
- screenIsClear = true;
475
- goHomeHandler = new Handler(Looper.getMainLooper());
476
- screenOffHandler = new Handler(Looper.getMainLooper());
477
- killHandler = new Handler(Looper.getMainLooper());
478
- Log.d(TAG, "Mach1: Handlers created");
466
+ hasUltraliteControl = false
467
+ screenIsClear = true
468
+ goHomeHandler = Handler(Looper.getMainLooper())
469
+ screenOffHandler = Handler(Looper.getMainLooper())
470
+ killHandler = Handler(Looper.getMainLooper())
471
+ Log.d(TAG, "Mach1: Handlers created")
479
472
 
480
- rowTextsLiveNow = new ArrayList<Integer>();
473
+ rowTextsLiveNow = ArrayList<Int>()
481
474
 
482
475
  // Initialize UltraliteSDK with valid context
483
- Log.d(TAG, "Mach1: About to initialize UltraliteSDK");
484
- ultraliteSdk = UltraliteSDK.get(context);
485
- Log.d(TAG, "Mach1: UltraliteSDK initialized");
476
+ Log.d(TAG, "Mach1: About to initialize UltraliteSDK")
477
+ ultraliteSdk = UltraliteSDK.get(context)
478
+ Log.d(TAG, "Mach1: UltraliteSDK initialized")
486
479
 
487
- ultraliteListener = new UltraliteListener();
488
- ultraliteSdk.addEventListener(ultraliteListener);
489
- Log.d(TAG, "Mach1: Event listener added");
480
+ ultraliteListener = UltraliteListener()
481
+ ultraliteSdk!!.addEventListener(ultraliteListener)
482
+ Log.d(TAG, "Mach1: Event listener added")
490
483
 
491
484
  // Set up LiveData observers using observeForever (no LifecycleOwner needed)
492
- ultraliteConnectedLive = ultraliteSdk.getConnected();
493
- ultraliteControlled = ultraliteSdk.getControlledByMe();
494
- batteryStatusObserver = ultraliteSdk.getBatteryStatus();
495
- Log.d(TAG, "Mach1: LiveData references obtained");
485
+ ultraliteConnectedLive = ultraliteSdk!!.getConnected()
486
+ ultraliteControlled = ultraliteSdk!!.getControlledByMe()
487
+ batteryStatusObserver = ultraliteSdk!!.getBatteryStatus()
488
+ Log.d(TAG, "Mach1: LiveData references obtained")
496
489
 
497
490
  // Create observers
498
- connectedObserver = isConnected -> {
499
- onUltraliteConnectedChange(isConnected);
500
- };
491
+ connectedObserver = Observer { isConnected ->
492
+ onUltraliteConnectedChange(isConnected)
493
+ }
501
494
 
502
- controlledObserver = isControlled -> {
503
- onUltraliteControlChanged(isControlled);
504
- };
495
+ controlledObserver = Observer { isControlled ->
496
+ onUltraliteControlChanged(isControlled)
497
+ }
505
498
 
506
- batteryObserver = batteryStatus -> {
507
- onUltraliteBatteryChanged(batteryStatus);
508
- };
499
+ batteryObserver = Observer { batteryStatus ->
500
+ onUltraliteBatteryChanged(batteryStatus)
501
+ }
509
502
 
510
503
  // Register observers on main thread (observeForever requires main thread)
511
- new Handler(Looper.getMainLooper()).post(() -> {
504
+ Handler(Looper.getMainLooper()).post {
512
505
  try {
513
- ultraliteConnectedLive.observeForever(connectedObserver);
514
- Log.d(TAG, "Mach1: Connected observer registered");
506
+ ultraliteConnectedLive!!.observeForever(connectedObserver!!)
507
+ Log.d(TAG, "Mach1: Connected observer registered")
515
508
 
516
- ultraliteControlled.observeForever(controlledObserver);
517
- Log.d(TAG, "Mach1: Controlled observer registered");
509
+ ultraliteControlled!!.observeForever(controlledObserver!!)
510
+ Log.d(TAG, "Mach1: Controlled observer registered")
518
511
 
519
- batteryStatusObserver.observeForever(batteryObserver);
520
- Log.d(TAG, "Mach1: Battery observer registered");
512
+ batteryStatusObserver!!.observeForever(batteryObserver!!)
513
+ Log.d(TAG, "Mach1: Battery observer registered")
521
514
 
522
- Log.d(TAG, "Mach1: All observers registered on main thread");
523
- } catch (Exception e) {
524
- Log.e(TAG, "Mach1: Failed to register observers: " + e.getMessage(), e);
515
+ Log.d(TAG, "Mach1: All observers registered on main thread")
516
+ } catch (e: Exception) {
517
+ Log.e(TAG, "Mach1: Failed to register observers: " + e.message, e)
525
518
  }
526
- });
519
+ }
527
520
 
528
- Log.d(TAG, "Mach1 initialized with context and observers");
529
- } catch (Exception e) {
530
- Log.e(TAG, "Mach1 constructor FAILED with exception: " + e.getMessage(), e);
531
- Bridge.log("Mach1 constructor FAILED: " + e.getMessage());
521
+ Log.d(TAG, "Mach1 initialized with context and observers")
522
+ } catch (e: Exception) {
523
+ Log.e(TAG, "Mach1 constructor FAILED with exception: " + e.message, e)
524
+ Bridge.log("Mach1 constructor FAILED: " + e.message)
532
525
  }
533
526
  }
534
527
 
535
- public void updateGlassesBrightness(int brightness) {
528
+ fun updateGlassesBrightness(brightness: Int) {
536
529
  // TODO: Implement this method
537
530
  }
538
531
 
539
- public void updateGlassesAutoBrightness(boolean autoBrightness) {
532
+ fun updateGlassesAutoBrightness(autoBrightness: Boolean) {
540
533
  // TODO: Implement this method
541
534
  }
542
535
 
543
- private void onUltraliteConnectedChange(boolean isConnected) {
544
- Log.d(TAG, "Ultralite CONNECT changed to: " + isConnected);
536
+ private fun onUltraliteConnectedChange(isConnected: Boolean) {
537
+ Log.d(TAG, "Ultralite CONNECT changed to: " + isConnected)
545
538
  if (isConnected) {
546
- Log.d(TAG, "Ultralite requesting control...");
547
- boolean isControlled = ultraliteSdk.requestControl();
548
- if (isControlled){
539
+ Log.d(TAG, "Ultralite requesting control...")
540
+ val isControlled = ultraliteSdk!!.requestControl()
541
+ if (isControlled) {
549
542
  // setupUltraliteCanvas();
550
543
  // changeUltraliteLayout(Layout.CANVAS);
551
- showHomeScreen();
544
+ showHomeScreen()
552
545
  } else {
553
- return;
546
+ return
554
547
  }
555
- Log.d(TAG, "Ultralite RESULT control request: " + isControlled);
556
- updateConnectionState(ConnTypes.CONNECTED);
548
+ Log.d(TAG, "Ultralite RESULT control request: " + isControlled)
549
+ updateConnectionState(ConnTypes.CONNECTED)
557
550
  // connectionEvent(SmartGlassesConnectionState.CONNECTED);
558
551
  } else {
559
- Log.d(TAG, "Ultralite not connected.");
560
- updateConnectionState(ConnTypes.DISCONNECTED);
552
+ Log.d(TAG, "Ultralite not connected.")
553
+ updateConnectionState(ConnTypes.DISCONNECTED)
561
554
  // connectionEvent(SmartGlassesConnectionState.DISCONNECTED);
562
555
  }
563
556
  }
564
557
 
565
- private void onUltraliteControlChanged(boolean isControlledByMe) {
566
- Log.d(TAG, "Ultralite CONTROL changed to: " + isControlledByMe);
567
- if(isControlledByMe) {
568
- hasUltraliteControl = true;
558
+ private fun onUltraliteControlChanged(isControlledByMe: Boolean) {
559
+ Log.d(TAG, "Ultralite CONTROL changed to: " + isControlledByMe)
560
+ if (isControlledByMe) {
561
+ hasUltraliteControl = true
569
562
  // connectionEvent(SmartGlassesConnectionState.CONNECTED);
570
- updateConnectionState(ConnTypes.CONNECTED);
563
+ updateConnectionState(ConnTypes.CONNECTED)
571
564
  } else {
572
- hasUltraliteControl = false;
565
+ hasUltraliteControl = false
573
566
  }
574
567
  }
575
568
 
576
- private void onUltraliteBatteryChanged(BatteryStatus batteryStatus) {
569
+ private fun onUltraliteBatteryChanged(batteryStatus: BatteryStatus?) {
577
570
  // Guard against null batteryStatus which can occur during connection/disconnection
578
571
  // See: MENTRA-OS-154
579
572
  if (batteryStatus == null) {
580
- Log.d(TAG, "Ultralite battery status is null, ignoring");
581
- return;
573
+ Log.d(TAG, "Ultralite battery status is null, ignoring")
574
+ return
582
575
  }
583
- Log.d(TAG, "Ultralite new battery status: " + batteryStatus.getLevel());
584
- DeviceStore.INSTANCE.apply("glasses", "batteryLevel", batteryStatus.getLevel());
576
+ Log.d(TAG, "Ultralite new battery status: " + batteryStatus.level)
577
+ DeviceStore.apply("glasses", "batteryLevel", batteryStatus.level)
585
578
 
586
579
  // Match iOS: if we're already connected but weren't fully booted yet (waiting
587
580
  // for battery), now that we have battery info we can declare fully booted.
588
- if (getConnectionState().equals(ConnTypes.CONNECTED) && !getFullyBooted()) {
589
- DeviceStore.INSTANCE.apply("glasses", "connected", true);
590
- DeviceStore.INSTANCE.apply("glasses", "fullyBooted", true);
581
+ if (connectionState == ConnTypes.CONNECTED && !fullyBooted) {
582
+ DeviceStore.apply("glasses", "connected", true)
583
+ DeviceStore.apply("glasses", "fullyBooted", true)
591
584
  }
592
585
  }
593
586
 
594
587
 
595
- protected void setFontSizes(){
588
+ protected fun setFontSizes() {
596
589
  }
597
590
 
598
- public void findCompatibleDeviceNames() {
591
+ fun findCompatibleDeviceNames() {
599
592
  // EventBus.getDefault().post(new GlassesBluetoothSearchDiscoverEvent(smartGlassesDevice.deviceModelName, "NOTREQUIREDSKIP"));
600
- Bridge.sendDiscoveredDevice(this.type, "NOTREQUIREDSKIP"); // Use this.type to support both Mach1 and Z100
593
+ Bridge.sendDiscoveredDevice(this.type, "NOTREQUIREDSKIP") // Use this.type to support both Mach1 and Z100
601
594
  //this.destroy();
602
595
  }
603
596
 
604
- public void connectToSmartGlasses(){
605
- Log.d(TAG, "connectToSmartGlasses running...");
597
+ fun connectToSmartGlasses() {
598
+ Log.d(TAG, "connectToSmartGlasses running...")
606
599
  // int mCount = 10;
607
600
  // while ((mConnectState != 2) && (!hasUltraliteControl) && (mCount > 0)){
608
601
  // mCount--;
@@ -618,11 +611,11 @@ public class Mach1 extends SGCManager {
618
611
  // Log.d(TAG, "mCOunt: " + mCount);
619
612
  // displayReferenceCardSimple("Connected to AugmentOS", "");
620
613
  // connectionEvent(mConnectState);
621
- Log.d(TAG, "connectToSmartGlasses finished");
614
+ Log.d(TAG, "connectToSmartGlasses finished")
622
615
  }
623
616
 
624
- public void displayTextLine(String text){
625
- displayReferenceCardSimple("", text);
617
+ fun displayTextLine(text: String) {
618
+ displayReferenceCardSimple("", text)
626
619
  }
627
620
 
628
621
  /**
@@ -631,22 +624,22 @@ public class Mach1 extends SGCManager {
631
624
  * Text wrapping and processing is handled by DisplayProcessor in React Native.
632
625
  * This method is a "dumb pipe" - it just sends the text to the Vuzix SDK.
633
626
  */
634
- public void displayTextWall(String text) {
627
+ fun displayTextWall(text: String) {
635
628
  if (screenToggleOff) {
636
- return;
629
+ return
637
630
  }
638
631
 
639
- goHomeHandler.removeCallbacksAndMessages(null);
640
- goHomeHandler.removeCallbacksAndMessages(goHomeRunnable);
632
+ goHomeHandler!!.removeCallbacksAndMessages(null)
633
+ goHomeHandler!!.removeCallbacksAndMessages(goHomeRunnable)
641
634
 
642
635
  // Text is already wrapped by DisplayProcessor - just send it
643
- changeUltraliteLayout(Layout.TEXT_BOTTOM_LEFT_ALIGN);
644
- ultraliteSdk.sendText(text);
636
+ changeUltraliteLayout(Layout.TEXT_BOTTOM_LEFT_ALIGN)
637
+ ultraliteSdk!!.sendText(text)
645
638
 
646
639
  if (ultraliteCanvas != null) {
647
- ultraliteCanvas.commit();
640
+ ultraliteCanvas!!.commit()
648
641
  }
649
- screenIsClear = false;
642
+ screenIsClear = false
650
643
  }
651
644
 
652
645
  /**
@@ -659,33 +652,33 @@ public class Mach1 extends SGCManager {
659
652
  * Column composition is handled by DisplayProcessor in React Native.
660
653
  * This method is a "dumb pipe" - it just sends the text to the Vuzix SDK.
661
654
  */
662
- public void displayDoubleTextWall(String textTop, String textBottom) {
655
+ fun displayDoubleTextWall(textTop: String, textBottom: String) {
663
656
  if (screenToggleOff) {
664
- return;
657
+ return
665
658
  }
666
659
 
667
- goHomeHandler.removeCallbacksAndMessages(null);
668
- goHomeHandler.removeCallbacksAndMessages(goHomeRunnable);
660
+ goHomeHandler!!.removeCallbacksAndMessages(null)
661
+ goHomeHandler!!.removeCallbacksAndMessages(goHomeRunnable)
669
662
 
670
663
  // Text is already composed by DisplayProcessor's ColumnComposer
671
664
  // Just combine and send - no custom logic needed
672
- String combinedText = textTop + "\n\n\n" + textBottom;
665
+ val combinedText = textTop + "\n\n\n" + textBottom
673
666
 
674
- changeUltraliteLayout(Layout.TEXT_BOTTOM_LEFT_ALIGN);
675
- ultraliteSdk.sendText(combinedText);
667
+ changeUltraliteLayout(Layout.TEXT_BOTTOM_LEFT_ALIGN)
668
+ ultraliteSdk!!.sendText(combinedText)
676
669
 
677
670
  if (ultraliteCanvas != null) {
678
- ultraliteCanvas.commit();
671
+ ultraliteCanvas!!.commit()
679
672
  }
680
- screenIsClear = false;
673
+ screenIsClear = false
681
674
  }
682
675
 
683
- public void displayCustomContent(String json) {
684
- displayReferenceCardSimple("CustomDisplayNotImplemented", json);
676
+ fun displayCustomContent(json: String) {
677
+ displayReferenceCardSimple("CustomDisplayNotImplemented", json)
685
678
  }
686
679
 
687
680
 
688
- public void showNaturalLanguageCommandScreen(String prompt, String naturalLanguageInput){
681
+ fun showNaturalLanguageCommandScreen(prompt: String, naturalLanguageInput: String) {
689
682
  // int boxDelta = 3;
690
683
  //
691
684
  // if (connectedGlasses != null) {
@@ -708,103 +701,103 @@ public class Mach1 extends SGCManager {
708
701
  // }
709
702
  }
710
703
 
711
- public void updateNaturalLanguageCommandScreen(String naturalLanguageArgs){
704
+ fun updateNaturalLanguageCommandScreen(naturalLanguageArgs: String) {
712
705
  // Log.d(TAG, "Displaynig: " + naturalLanguageArgs);
713
706
  // displayText(new TextLineSG(naturalLanguageArgs, SMALL_FONT), new Point(0, lastLocNaturalLanguageArgsTextView.y));
714
707
  }
715
708
 
716
- public void blankScreen(){
709
+ fun blankScreen() {
717
710
  // if (connectedGlasses != null){
718
711
  // connectedGlasses.clear();
719
712
  // }
720
713
  }
721
714
 
722
- public void destroy() {
715
+ fun destroy() {
723
716
  try {
724
717
  // Remove LiveData observers (using observeForever, so use removeObserver)
725
718
  if (ultraliteConnectedLive != null && connectedObserver != null) {
726
- ultraliteConnectedLive.removeObserver(connectedObserver);
719
+ ultraliteConnectedLive!!.removeObserver(connectedObserver!!)
727
720
  }
728
721
  if (ultraliteControlled != null && controlledObserver != null) {
729
- ultraliteControlled.removeObserver(controlledObserver);
722
+ ultraliteControlled!!.removeObserver(controlledObserver!!)
730
723
  }
731
724
  if (batteryStatusObserver != null && batteryObserver != null) {
732
- batteryStatusObserver.removeObserver(batteryObserver);
725
+ batteryStatusObserver!!.removeObserver(batteryObserver!!)
733
726
  }
734
727
 
735
728
  if (ultraliteSdk != null) {
736
729
  // Remove event listeners and release control
737
- ultraliteSdk.removeEventListener(ultraliteListener);
738
- ultraliteSdk.releaseControl();
739
- ultraliteSdk = null; // Nullify reference
730
+ ultraliteSdk!!.removeEventListener(ultraliteListener)
731
+ ultraliteSdk!!.releaseControl()
732
+ ultraliteSdk = null // Nullify reference
740
733
  }
741
734
 
742
735
  // Cancel all pending handlers and callbacks
743
736
  if (goHomeHandler != null) {
744
- goHomeHandler.removeCallbacksAndMessages(null);
737
+ goHomeHandler!!.removeCallbacksAndMessages(null)
745
738
  }
746
739
  if (screenOffHandler != null) {
747
- screenOffHandler.removeCallbacksAndMessages(null);
740
+ screenOffHandler!!.removeCallbacksAndMessages(null)
748
741
  }
749
742
  if (killHandler != null) {
750
- killHandler.removeCallbacksAndMessages(null);
743
+ killHandler!!.removeCallbacksAndMessages(null)
751
744
  }
752
745
 
753
746
  // Clear canvas and other resources
754
747
  if (ultraliteCanvas != null) {
755
- ultraliteCanvas.clear();
756
- ultraliteCanvas.commit();
757
- ultraliteCanvas = null;
748
+ ultraliteCanvas!!.clear()
749
+ ultraliteCanvas!!.commit()
750
+ ultraliteCanvas = null
758
751
  }
759
752
 
760
753
  // Reset state variables
761
- rowTextsLiveNow.clear();
762
- screenToggleOff = false;
763
- screenIsClear = true;
764
- lastTapTime = 0;
765
- totalDashboardsIdk = 0;
766
- currentUltraliteLayout = null;
754
+ rowTextsLiveNow!!.clear()
755
+ screenToggleOff = false
756
+ screenIsClear = true
757
+ lastTapTime = 0
758
+ totalDashboardsIdk = 0
759
+ currentUltraliteLayout = null
767
760
 
768
761
  // Free up references
769
- this.context = null;
770
- connectedObserver = null;
771
- controlledObserver = null;
772
- batteryObserver = null;
773
-
774
- Log.d(TAG, "UltraliteSGC destroyed successfully.");
775
- } catch (Exception e) {
776
- Log.e(TAG, "Error during destroy: ", e);
762
+ this.context = null
763
+ connectedObserver = null
764
+ controlledObserver = null
765
+ batteryObserver = null
766
+
767
+ Log.d(TAG, "UltraliteSGC destroyed successfully.")
768
+ } catch (e: Exception) {
769
+ Log.e(TAG, "Error during destroy: ", e)
777
770
  }
778
771
  }
779
772
 
780
773
 
781
- public void showHomeScreen() {
782
- Log.d(TAG, "SHOW HOME SCREEN");
783
- ultraliteSdk.screenOff();
784
- screenIsClear = true;
774
+ fun showHomeScreen() {
775
+ Log.d(TAG, "SHOW HOME SCREEN")
776
+ ultraliteSdk!!.screenOff()
777
+ screenIsClear = true
785
778
  }
786
779
 
787
- public void setupUltraliteCanvas(){
788
- Log.d(TAG, "Setting up ultralite canvas");
780
+ fun setupUltraliteCanvas() {
781
+ Log.d(TAG, "Setting up ultralite canvas")
789
782
  if (ultraliteSdk != null) {
790
- ultraliteCanvas = ultraliteSdk.getCanvas();
783
+ ultraliteCanvas = ultraliteSdk!!.getCanvas()
791
784
  }
792
785
  }
793
786
 
794
- public void changeUltraliteLayout(Layout chosenLayout) {
787
+ fun changeUltraliteLayout(chosenLayout: Layout) {
795
788
  //don't update layout if it's already setup
796
- if (currentUltraliteLayout != null && currentUltraliteLayout == chosenLayout){
797
- return;
789
+ if (currentUltraliteLayout != null && currentUltraliteLayout == chosenLayout) {
790
+ return
798
791
  }
799
792
 
800
- ultraliteSdk.screenOn();
793
+ ultraliteSdk!!.screenOn()
801
794
 
802
- currentUltraliteLayout = chosenLayout;
803
- ultraliteSdk.setLayout(chosenLayout, 0, true, false, 2);
795
+ currentUltraliteLayout = chosenLayout
796
+ ultraliteSdk!!.setLayout(chosenLayout, 0, true, false, 2)
804
797
 
805
- if (chosenLayout.equals(Layout.CANVAS)){
806
- if (ultraliteCanvas == null){
807
- setupUltraliteCanvas();
798
+ if (chosenLayout == Layout.CANVAS) {
799
+ if (ultraliteCanvas == null) {
800
+ setupUltraliteCanvas()
808
801
  }
809
802
  }
810
803
  }
@@ -826,16 +819,16 @@ public class Mach1 extends SGCManager {
826
819
  * Draw text on Ultralite canvas.
827
820
  * Text is expected to be pre-wrapped by DisplayProcessor.
828
821
  */
829
- public void drawTextOnUltralite(String text){
830
- UltraliteColor ultraliteColor = UltraliteColor.WHITE;
831
- Anchor ultraliteAnchor = Anchor.TOP_LEFT;
832
- TextAlignment ultraliteAlignment = TextAlignment.LEFT;
833
- changeUltraliteLayout(Layout.CANVAS);
834
- ultraliteCanvas.clear();
835
- ultraliteCanvas.clearBackground(UltraliteColor.DIM);
836
- ultraliteCanvas.createText(text, ultraliteAlignment, ultraliteColor, ultraliteAnchor, true);
837
- ultraliteCanvas.commit();
838
- screenIsClear = false;
822
+ fun drawTextOnUltralite(text: String) {
823
+ val ultraliteColor = UltraliteColor.WHITE
824
+ val ultraliteAnchor = Anchor.TOP_LEFT
825
+ val ultraliteAlignment = TextAlignment.LEFT
826
+ changeUltraliteLayout(Layout.CANVAS)
827
+ ultraliteCanvas!!.clear()
828
+ ultraliteCanvas!!.clearBackground(UltraliteColor.DIM)
829
+ ultraliteCanvas!!.createText(text, ultraliteAlignment, ultraliteColor, ultraliteAnchor, true)
830
+ ultraliteCanvas!!.commit()
831
+ screenIsClear = false
839
832
  }
840
833
 
841
834
  // public Bitmap getBitmapFromDrawable(Resources res) {
@@ -896,25 +889,25 @@ public class Mach1 extends SGCManager {
896
889
  // ultraliteSdk.setFont(null, 0, textSize);
897
890
  // }
898
891
 
899
- public void displayReferenceCardSimple(String titleStr, String bodyStr){
900
- if (screenToggleOff){
901
- return;
892
+ fun displayReferenceCardSimple(titleStr: String, bodyStr: String) {
893
+ if (screenToggleOff) {
894
+ return
902
895
  }
903
896
 
904
- String title = maybeReverseRTLString(titleStr);
905
- String body = maybeReverseRTLString(bodyStr);
906
- if (!getConnectionState().equals(ConnTypes.CONNECTED)) {
907
- Log.d(TAG, "Not showing reference card because not connected to Ultralites...");
908
- return;
897
+ val title = maybeReverseRTLString(titleStr)
898
+ val body = maybeReverseRTLString(bodyStr)
899
+ if (connectionState != ConnTypes.CONNECTED) {
900
+ Log.d(TAG, "Not showing reference card because not connected to Ultralites...")
901
+ return
909
902
  }
910
903
 
911
- changeUltraliteLayout(Layout.CANVAS);
912
- ultraliteCanvas.clear();
904
+ changeUltraliteLayout(Layout.CANVAS)
905
+ ultraliteCanvas!!.clear()
913
906
 
914
907
  // String [] bulletPoints = {"first one", "second one", "dogs and cats"};
915
908
  // displayBulletList("Cool Bullets:", bulletPoints, 15);
916
909
 
917
- Log.d(TAG, "Sending text to Ultralite SDK: \n" + body);
910
+ Log.d(TAG, "Sending text to Ultralite SDK: \n" + body)
918
911
  // ultraliteSdk.sendText("hello world"); //this is BROKEN in Vuzix ultralite 0.4.2 SDK - crashes Vuzix OEM Platform android app
919
912
 
920
913
  //edit the text to add new lines to it because ultralite wrapping doesn't work
@@ -929,14 +922,14 @@ public class Mach1 extends SGCManager {
929
922
  // ultraliteCanvas.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.MIDDLE_LEFT, ultraliteLeftSidePixelBuffer, 0, 640 - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true);
930
923
 
931
924
  //concat body and title, put text on top right of screen (to not block main view)
932
- UltraliteColor ultraliteColor = UltraliteColor.WHITE;
933
- Anchor ultraliteAnchor = Anchor.TOP_CENTER;
934
- TextAlignment ultraliteAlignment = TextAlignment.LEFT;
925
+ val ultraliteColor = UltraliteColor.WHITE
926
+ val ultraliteAnchor = Anchor.TOP_CENTER
927
+ val ultraliteAlignment = TextAlignment.LEFT
935
928
  //ultraliteCanvas.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, (640 / 2) - ultraliteLeftSidePixelBuffer, -1, TextWrapMode.WRAP, true);
936
- if (!title.isEmpty() && !title.equals("")){
937
- ultraliteCanvas.createText(title + ": " + body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, 640 / 2, -1, TextWrapMode.WRAP, true);
929
+ if (!title.isEmpty() && title != "") {
930
+ ultraliteCanvas!!.createText(title + ": " + body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, 640 / 2, -1, TextWrapMode.WRAP, true)
938
931
  } else {
939
- ultraliteCanvas.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, 640 / 2, -1, TextWrapMode.WRAP, true);
932
+ ultraliteCanvas!!.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_RIGHT, 0, 0, 640 / 2, -1, TextWrapMode.WRAP, true)
940
933
  }
941
934
 
942
935
  //NOTE:
@@ -956,42 +949,44 @@ public class Mach1 extends SGCManager {
956
949
  // TextWrapMode wrap,
957
950
  // boolean visible)
958
951
 
959
- ultraliteCanvas.commit();
960
- screenIsClear = false;
952
+ ultraliteCanvas!!.commit()
953
+ screenIsClear = false
961
954
  }
962
955
 
963
956
 
964
- public void displayBulletList(String title, String [] bullets){
965
- displayBulletList(title, bullets, 14);
957
+ fun displayBulletList(title: String, bullets: Array<String>) {
958
+ displayBulletList(title, bullets, 14)
966
959
  }
967
960
 
968
- public void displayRowsCard(String[] rowStrings){
969
- displayRowsCard(rowStrings, cardLingerTime);
961
+ fun displayRowsCard(rowStrings: Array<String>) {
962
+ displayRowsCard(rowStrings, cardLingerTime)
970
963
  }
971
964
 
972
- public void displayRowsCard(String[] rowStringList, int lingerTime){
973
- if (screenToggleOff){
974
- return;
965
+ fun displayRowsCard(rowStringList: Array<String>, lingerTime: Int) {
966
+ if (screenToggleOff) {
967
+ return
975
968
  }
976
969
 
977
- String[] rowStrings = maybeReverseRTLStringList(rowStringList);
978
- if (!getConnectionState().equals(ConnTypes.CONNECTED)) {
979
- Log.d(TAG, "Not showing rows card because not connected to Ultralites...");
980
- return;
970
+ val rowStrings = maybeReverseRTLStringList(rowStringList)
971
+ if (connectionState != ConnTypes.CONNECTED) {
972
+ Log.d(TAG, "Not showing rows card because not connected to Ultralites...")
973
+ return
981
974
  }
982
975
 
983
976
  // changeUltraliteLayout(Layout.CANVAS);
984
977
  // ultraliteCanvas.clear();
985
978
 
986
979
  //make lines to draw on screen to delineate rows
987
- int line_thickness = 3;
988
- for (int y = 120; y < 480; y += 120) {
989
- ultraliteCanvas.clearBackgroundRect(0, y, 640, line_thickness, UltraliteColor.DIM);
980
+ val line_thickness = 3
981
+ var y = 120
982
+ while (y < 480) {
983
+ ultraliteCanvas!!.clearBackgroundRect(0, y, 640, line_thickness, UltraliteColor.DIM)
984
+ y += 120
990
985
  }
991
986
 
992
987
  //clear old text
993
- for (int i = 0; i < rowTextsLiveNow.size(); i++){
994
- ultraliteCanvas.removeText(i);
988
+ for (i in 0 until rowTextsLiveNow!!.size) {
989
+ ultraliteCanvas!!.removeText(i)
995
990
  }
996
991
  //old way to clear old text - vuzix ultralite sdk bug that clear background doesn't clear text?
997
992
  // for (int y = 0; y < 480; y += 120) {
@@ -1002,64 +997,64 @@ public class Mach1 extends SGCManager {
1002
997
  // ultraliteCanvas.commit();
1003
998
 
1004
999
  //display the title at the top of the screen
1005
- UltraliteColor ultraliteColor = UltraliteColor.WHITE;
1006
- Anchor ultraliteAnchor = Anchor.TOP_LEFT;
1007
- TextAlignment ultraliteAlignment = TextAlignment.LEFT;
1000
+ val ultraliteColor = UltraliteColor.WHITE
1001
+ val ultraliteAnchor = Anchor.TOP_LEFT
1002
+ val ultraliteAlignment = TextAlignment.LEFT
1008
1003
 
1009
1004
  //if no input, just show the lines
1010
- if (rowStrings.length == 0){
1011
- ultraliteCanvas.commit();
1012
- screenIsClear = false;
1013
- return;
1005
+ if (rowStrings.isEmpty()) {
1006
+ ultraliteCanvas!!.commit()
1007
+ screenIsClear = false
1008
+ return
1014
1009
  }
1015
1010
 
1016
1011
  //go throw rows, draw the text, don't do more than 4
1017
- int y_start_height = 55;
1012
+ val y_start_height = 55
1018
1013
  // Reverse rowStrings array
1019
- Collections.reverse(Arrays.asList(rowStrings));
1020
- int numRows = 4;
1021
- int actualRows = Math.min(rowStrings.length, numRows);
1022
- for (int i = 0; i < actualRows; i++) {
1014
+ rowStrings.reverse()
1015
+ val numRows = 4
1016
+ val actualRows = Math.min(rowStrings.size, numRows)
1017
+ for (i in 0 until actualRows) {
1023
1018
  // Calculate the offset to start from the bottom for 1, 2, or 3 values
1024
- int yOffset = (numRows - actualRows) * 112;
1025
- int 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);
1026
- rowTextsLiveNow.add(textId);
1019
+ val yOffset = (numRows - actualRows) * 112
1020
+ 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)
1021
+ rowTextsLiveNow!!.add(textId)
1027
1022
  }
1028
1023
 
1029
- ultraliteCanvas.commit();
1030
- screenIsClear = false;
1024
+ ultraliteCanvas!!.commit()
1025
+ screenIsClear = false
1031
1026
  }
1032
1027
 
1033
- public void displayBulletList(String title, String [] bulletList, int lingerTime){
1034
- if (screenToggleOff){
1035
- return;
1028
+ fun displayBulletList(title: String, bulletList: Array<String>, lingerTime: Int) {
1029
+ if (screenToggleOff) {
1030
+ return
1036
1031
  }
1037
1032
 
1038
- String[] bullets = maybeReverseRTLStringList(bulletList);
1039
- if (!getConnectionState().equals(ConnTypes.CONNECTED)) {
1040
- Log.d(TAG, "Not showing bullet point list because not connected to Ultralites...");
1041
- return;
1033
+ val bullets = maybeReverseRTLStringList(bulletList)
1034
+ if (connectionState != ConnTypes.CONNECTED) {
1035
+ Log.d(TAG, "Not showing bullet point list because not connected to Ultralites...")
1036
+ return
1042
1037
  }
1043
1038
 
1044
- Log.d(TAG, "Sending bullets to Ultralite SDK: " + title);
1039
+ Log.d(TAG, "Sending bullets to Ultralite SDK: " + title)
1045
1040
 
1046
1041
  //display the title at the top of the screen
1047
- UltraliteColor ultraliteColor = UltraliteColor.WHITE;
1048
- Anchor ultraliteAnchor = Anchor.TOP_LEFT;
1049
- TextAlignment ultraliteAlignment = TextAlignment.LEFT;
1050
- changeUltraliteLayout(Layout.CANVAS);
1051
- ultraliteCanvas.clear();
1052
-
1053
- ultraliteCanvas.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true);
1054
- int displaceY = 25;
1055
- int displaceX = 25;
1056
- for (String bullet : bullets){
1057
- ultraliteCanvas.createText("⬤ " + bullet, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, displaceX, displaceY, 640 - displaceX, -1, TextWrapMode.WRAP, true);
1058
- displaceY += 125;
1042
+ val ultraliteColor = UltraliteColor.WHITE
1043
+ val ultraliteAnchor = Anchor.TOP_LEFT
1044
+ val ultraliteAlignment = TextAlignment.LEFT
1045
+ changeUltraliteLayout(Layout.CANVAS)
1046
+ ultraliteCanvas!!.clear()
1047
+
1048
+ ultraliteCanvas!!.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true)
1049
+ var displaceY = 25
1050
+ val displaceX = 25
1051
+ for (bullet in bullets) {
1052
+ ultraliteCanvas!!.createText("⬤ " + bullet, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, displaceX, displaceY, 640 - displaceX, -1, TextWrapMode.WRAP, true)
1053
+ displaceY += 125
1059
1054
  }
1060
1055
 
1061
- ultraliteCanvas.commit();
1062
- screenIsClear = false;
1056
+ ultraliteCanvas!!.commit()
1057
+ screenIsClear = false
1063
1058
  }
1064
1059
 
1065
1060
  // public void homeScreenInNSeconds(int n){
@@ -1078,48 +1073,47 @@ public class Mach1 extends SGCManager {
1078
1073
  // goHomeHandler.postDelayed(goHomeRunnable, n * 1000);
1079
1074
  // }
1080
1075
 
1081
- public void displayBitmap(Bitmap bmp) {
1082
- Bitmap resizedBmp = Bitmap.createScaledBitmap(bmp, 620, 460, true); // 640 x 480
1076
+ fun displayBitmap(bmp: Bitmap) {
1077
+ val resizedBmp = Bitmap.createScaledBitmap(bmp, 620, 460, true) // 640 x 480
1083
1078
 
1084
- changeUltraliteLayout(Layout.CANVAS);
1085
- screenIsClear = false;
1079
+ changeUltraliteLayout(Layout.CANVAS)
1080
+ screenIsClear = false
1086
1081
 
1087
- Log.d(TAG, "Sending bitmap to Ultralite");
1088
- ultraliteCanvas.drawBackground(resizedBmp, 50, 80);
1089
- ultraliteCanvas.commit();
1082
+ Log.d(TAG, "Sending bitmap to Ultralite")
1083
+ ultraliteCanvas!!.drawBackground(resizedBmp, 50, 80)
1084
+ ultraliteCanvas!!.commit()
1090
1085
  }
1091
1086
 
1092
1087
  //don't show images on activelook (screen is too low res)
1093
- public void displayReferenceCardImage(String title, String body, String imgUrl){
1094
- if (screenToggleOff){
1095
- return;
1088
+ fun displayReferenceCardImage(title: String, body: String, imgUrl: String) {
1089
+ if (screenToggleOff) {
1090
+ return
1096
1091
  }
1097
1092
 
1098
- changeUltraliteLayout(Layout.CANVAS);
1099
- ultraliteCanvas.clear();
1093
+ changeUltraliteLayout(Layout.CANVAS)
1094
+ ultraliteCanvas!!.clear()
1100
1095
 
1101
1096
  //make image
1102
1097
  //below works, but only for very, very low res/size images
1103
- Anchor ultraliteImageAnchor = Anchor.CENTER;
1098
+ val ultraliteImageAnchor = Anchor.CENTER
1104
1099
  Picasso.get()
1105
1100
  .load(imgUrl)
1106
- .into(new Target() {
1107
- @Override
1108
- public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
1101
+ .into(object : Target {
1102
+ override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
1109
1103
  // Use the bitmap
1110
1104
  // LVGLImage ultraliteImage = LVGLImage.fromBitmap(getBitmapFromDrawable(context.getResources()), CF_INDEXED_2_BIT);
1111
1105
  // LVGLImage ultraliteImage = LVGLImage.fromBitmap(bitmap, CF_INDEXED_2_BIT);
1112
- changeUltraliteLayout(Layout.CANVAS);
1106
+ changeUltraliteLayout(Layout.CANVAS)
1113
1107
 
1114
1108
  //send text first, cuz this is fast
1115
- ultraliteCanvas.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true);
1116
- ultraliteCanvas.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.BOTTOM_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true);
1117
- ultraliteCanvas.commit();
1118
- screenIsClear = false;
1109
+ ultraliteCanvas!!.createText(title, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.TOP_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true)
1110
+ ultraliteCanvas!!.createText(body, TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.BOTTOM_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true)
1111
+ ultraliteCanvas!!.commit()
1112
+ screenIsClear = false
1119
1113
 
1120
- Log.d(TAG, "Sending image to Ultralite");
1114
+ Log.d(TAG, "Sending image to Ultralite")
1121
1115
  // ultraliteCanvas.createImage(ultraliteImage, ultraliteImageAnchor, 0, 0, true);
1122
- ultraliteCanvas.drawBackground(bitmap, 0, 0);
1116
+ ultraliteCanvas!!.drawBackground(bitmap!!, 0, 0)
1123
1117
 
1124
1118
  //sending text again to ultralite in case image overwrote it
1125
1119
  // ultraliteCanvas.createText(title + "2", TextAlignment.AUTO, UltraliteColor.WHITE, Anchor.BOTTOM_LEFT, 0, 0, 640, -1, TextWrapMode.WRAP, true);
@@ -1135,18 +1129,16 @@ public class Mach1 extends SGCManager {
1135
1129
  // ultraliteCanvas.commit();
1136
1130
  }
1137
1131
 
1138
- @Override
1139
- public void onBitmapFailed(Exception e, Drawable errorDrawable) {
1132
+ override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {
1140
1133
  // Handle the error
1141
- Log.d(TAG, "Bitmap failed");
1142
- e.printStackTrace();
1134
+ Log.d(TAG, "Bitmap failed")
1135
+ e!!.printStackTrace()
1143
1136
  }
1144
1137
 
1145
- @Override
1146
- public void onPrepareLoad(Drawable placeHolderDrawable) {
1138
+ override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
1147
1139
  // Called before the image is loaded. You can set a placeholder if needed.
1148
1140
  }
1149
- });
1141
+ })
1150
1142
 
1151
1143
  //edit the text to add new lines to it because ultralite wrapping doesn't work
1152
1144
  // String titleWrapped = addNewlineEveryNWords(title, 6);
@@ -1195,7 +1187,7 @@ public class Mach1 extends SGCManager {
1195
1187
  // return textPoint;
1196
1188
  // }
1197
1189
 
1198
- public void stopScrollingTextViewMode() {
1190
+ fun stopScrollingTextViewMode() {
1199
1191
  // if (connectedGlasses == null) {
1200
1192
  // return;
1201
1193
  // }
@@ -1204,12 +1196,12 @@ public class Mach1 extends SGCManager {
1204
1196
  // connectedGlasses.clear();
1205
1197
  }
1206
1198
 
1207
- public void scrollingTextViewIntermediateText(String text){
1199
+ fun scrollingTextViewIntermediateText(text: String) {
1208
1200
  }
1209
1201
 
1210
- public void scrollingTextViewFinalText(String text){
1211
- if (!getConnectionState().equals(ConnTypes.CONNECTED)) {
1212
- return;
1202
+ fun scrollingTextViewFinalText(text: String) {
1203
+ if (connectionState != ConnTypes.CONNECTED) {
1204
+ return
1213
1205
  }
1214
1206
 
1215
1207
  // //save to our saved list of final scrolling text strings
@@ -1260,52 +1252,17 @@ public class Mach1 extends SGCManager {
1260
1252
 
1261
1253
  }
1262
1254
 
1263
- public static String maybeReverseRTLString(String text) {
1264
- StringBuilder result = new StringBuilder();
1265
- StringBuilder rtlBuffer = new StringBuilder();
1266
-
1267
- for (char c : text.toCharArray()) {
1268
- if (isRTLCharacter(c)) {
1269
- rtlBuffer.append(c); // Append RTL characters to a buffer
1270
- } else {
1271
- if (rtlBuffer.length() > 0) {
1272
- result.append(rtlBuffer.reverse()); // Reverse and append RTL text when a non-RTL character is found
1273
- rtlBuffer.setLength(0); // Clear the buffer
1274
- }
1275
- result.append(c); // Append non-RTL characters directly to the result
1276
- }
1277
- }
1278
-
1279
- if (rtlBuffer.length() > 0) {
1280
- result.append(rtlBuffer.reverse()); // Append any remaining RTL text in reverse
1281
- }
1282
-
1283
- return result.toString();
1284
- }
1285
-
1286
- private static boolean isRTLCharacter(char c) {
1287
- Character.UnicodeBlock block = Character.UnicodeBlock.of(c);
1288
- return block == Character.UnicodeBlock.ARABIC ||
1289
- block == Character.UnicodeBlock.HEBREW ||
1290
- block == Character.UnicodeBlock.SYRIAC ||
1291
- block == Character.UnicodeBlock.ARABIC_SUPPLEMENT ||
1292
- block == Character.UnicodeBlock.THAANA ||
1293
- block == Character.UnicodeBlock.NKO ||
1294
- block == Character.UnicodeBlock.SAMARITAN ||
1295
- block == Character.UnicodeBlock.MANDAIC ||
1296
- block == Character.UnicodeBlock.ARABIC_EXTENDED_A;
1297
- // Add other RTL blocks as needed
1298
- }
1299
- public String[] maybeReverseRTLStringList(String[] in){
1300
- String[] out = new String[in.length];
1301
- for(int i = 0; i < in.length; i++)
1302
- out[i] = maybeReverseRTLString(in[i]);
1303
- return out;
1255
+ fun maybeReverseRTLStringList(input: Array<String>): Array<String> {
1256
+ val out = arrayOfNulls<String>(input.size)
1257
+ for (i in 0 until input.size)
1258
+ out[i] = maybeReverseRTLString(input[i])
1259
+ @Suppress("UNCHECKED_CAST")
1260
+ return out as Array<String>
1304
1261
  }
1305
1262
 
1306
- public void displayPromptView(String prompt, String [] options){
1307
- if (!getConnectionState().equals(ConnTypes.CONNECTED)) {
1308
- return;
1263
+ fun displayPromptView(prompt: String, options: Array<String>?) {
1264
+ if (connectionState != ConnTypes.CONNECTED) {
1265
+ return
1309
1266
  }
1310
1267
 
1311
1268
  // ultraliteCanvas.clear();