@glassly/bluetooth-sdk 0.1.0-dev.89 → 0.1.0-dev.96
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.
- package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedChangelogCatalog.kt +1 -0
- package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedReleaseMetadata.kt +3 -3
- package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G1.kt +8 -49
- package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2.kt +3 -2
- package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Mach1.kt +0 -13
- package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLive.kt +11 -86
- package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraNex.kt +1 -4
- package/android/src/main/java/com/glassly/bluetoothsdk/stt/VadGateSpeechPolicy.kt +0 -2
- package/build/generated/changelogCatalog.d.ts +3 -0
- package/build/generated/changelogCatalog.d.ts.map +1 -1
- package/build/generated/changelogCatalog.js +4 -0
- package/build/generated/changelogCatalog.js.map +1 -1
- package/build/generated/releaseMetadata.js +3 -3
- package/build/generated/releaseMetadata.js.map +1 -1
- package/ios/Source/BluetoothSdkDefaults.swift +1 -1
- package/ios/Source/DeviceManager.swift +5 -7
- package/ios/Source/GeneratedChangelogCatalog.swift +1 -0
- package/ios/Source/GeneratedReleaseMetadata.swift +3 -3
- package/ios/Source/sgcs/G2.swift +3 -10
- package/ios/Source/sgcs/MentraLive.swift +4 -4
- package/ios/Source/sgcs/MentraNex.swift +43 -44
- package/ios/Source/tts/TTSTools.swift +0 -4
- package/package.json +1 -1
- package/src/generated/changelogCatalog.ts +4 -0
- package/src/generated/releaseMetadata.ts +3 -3
- package/ios/Source/sgcs/Frame.swift +0 -649
|
@@ -3,6 +3,7 @@ package com.glassly.bluetoothsdk
|
|
|
3
3
|
/** Generated from /changelogs. Do not edit directly. */
|
|
4
4
|
internal val GENERATED_RELEASE_CHANGELOGS: List<ReleaseChangelog> =
|
|
5
5
|
listOf(
|
|
6
|
+
ReleaseChangelog(version = "3.2.0", markdown = "This release is under active development. User-facing changes will be documented as they land."),
|
|
6
7
|
ReleaseChangelog(version = "3.1.0", markdown = "Software updates are more reliable, with clearer progress and recovery when the glasses restart.\n\n- GlasslyOS, Glassly Engine, the Bluetooth SDK, and the glasses client now share one coordinated release version.\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic."),
|
|
7
8
|
ReleaseChangelog(version = "0.1.0", markdown = "First coordinated Glassly release: the app, Glassly Engine, and the Bluetooth SDK now ship one shared release version.\n\n- The Glassly App, Glassly Engine, and the Bluetooth SDK are versioned and published together.\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic."),
|
|
8
9
|
)
|
|
@@ -3,9 +3,9 @@ package com.glassly.bluetoothsdk
|
|
|
3
3
|
/** Generated by release CI. Do not edit in a release checkout. */
|
|
4
4
|
internal object GeneratedReleaseMetadata {
|
|
5
5
|
const val FAMILY_BASE_VERSION: String = "0.1.0"
|
|
6
|
-
const val RELEASE_IDENTITY: String = "0.1.0-dev.
|
|
7
|
-
const val RELEASE_SET_ID: String = "glassly-0.1.0-dev.
|
|
8
|
-
const val SOURCE_COMMIT: String = "
|
|
6
|
+
const val RELEASE_IDENTITY: String = "0.1.0-dev.96"
|
|
7
|
+
const val RELEASE_SET_ID: String = "glassly-0.1.0-dev.96"
|
|
8
|
+
const val SOURCE_COMMIT: String = "440518cf281588df779cd13d78922782db027ad4"
|
|
9
9
|
const val OTA_MANIFEST_URL: String = ""
|
|
10
10
|
const val OTA_MANIFEST_SHA256: String = ""
|
|
11
11
|
}
|
|
@@ -41,7 +41,6 @@ import java.nio.ByteBuffer
|
|
|
41
41
|
|
|
42
42
|
import com.google.gson.Gson
|
|
43
43
|
|
|
44
|
-
import org.greenrobot.eventbus.EventBus
|
|
45
44
|
import org.json.JSONArray
|
|
46
45
|
import org.json.JSONException
|
|
47
46
|
import org.json.JSONObject
|
|
@@ -222,11 +221,10 @@ class G1 : SGCManager() {
|
|
|
222
221
|
private var rightTxChar: BluetoothGattCharacteristic? = null
|
|
223
222
|
private var leftRxChar: BluetoothGattCharacteristic? = null
|
|
224
223
|
private var rightRxChar: BluetoothGattCharacteristic? = null
|
|
225
|
-
//
|
|
226
|
-
//
|
|
224
|
+
// Not named connectionState: Kotlin can't shadow SGCManager's public val
|
|
225
|
+
// connectionState with a private field of another type.
|
|
227
226
|
private var g1ConnectionState = SmartGlassesConnectionState.DISCONNECTED
|
|
228
|
-
//
|
|
229
|
-
// constructor body can assign it; in G1.java this field lived in the BMP section)
|
|
227
|
+
// Declared before init so the constructor body can assign it.
|
|
230
228
|
private var bitmapExecutor: ExecutorService? = null
|
|
231
229
|
private val handler = Handler(Looper.getMainLooper())
|
|
232
230
|
private val queryBatteryStatusHandler = Handler(Looper.getMainLooper())
|
|
@@ -319,12 +317,9 @@ class G1 : SGCManager() {
|
|
|
319
317
|
private var shouldUseGlassesMic = false
|
|
320
318
|
private var lastThingDisplayedWasAnImage = false
|
|
321
319
|
|
|
322
|
-
//
|
|
323
|
-
//
|
|
324
|
-
// never read or written; in Kotlin they would clash with SGCManager's val properties,
|
|
325
|
-
// so they are omitted.
|
|
320
|
+
// serialNumber/style/color come from SGCManager's val properties; do not
|
|
321
|
+
// redeclare them here.
|
|
326
322
|
|
|
327
|
-
// lock writing until the last write is successful
|
|
328
323
|
// fonts in G1
|
|
329
324
|
private var g1Text: G1Text? = null
|
|
330
325
|
|
|
@@ -658,16 +653,9 @@ class G1 : SGCManager() {
|
|
|
658
653
|
DeviceStore.apply("glasses", "headUp", false)
|
|
659
654
|
}
|
|
660
655
|
}
|
|
661
|
-
//
|
|
662
|
-
//
|
|
663
|
-
//
|
|
664
|
-
// else if (data.length > 1 && (data[0] & 0xFF) == 0xF5 && ((data[1] & 0xFF) ==
|
|
665
|
-
// 0x20) || ((data[1] & 0xFF) == 0x00)) {
|
|
666
|
-
// boolean isRight = deviceName.contains("R_");
|
|
667
|
-
// Bridge.log("G1: GOT DOUBLE TAP from isRight?: " + isRight);
|
|
668
|
-
// EventBus.getDefault().post(new GlassesTapOutputEvent(2, isRight,
|
|
669
|
-
// System.currentTimeMillis()));
|
|
670
|
-
// }
|
|
656
|
+
// Double tap (0xF5 0x20 / 0x00) is deliberately unhandled: on this
|
|
657
|
+
// firmware it clears the screen. Don't surface the touchpads until
|
|
658
|
+
// that is fixed.
|
|
671
659
|
// BATTERY RESPONSE
|
|
672
660
|
else if (data.size > 2 && data[0] == 0x2C.toByte() && data[1] == 0x66.toByte()) {
|
|
673
661
|
if (deviceName.contains("L_")) {
|
|
@@ -680,8 +668,6 @@ class G1 : SGCManager() {
|
|
|
680
668
|
|
|
681
669
|
if (batteryLeft != -1 && batteryRight != -1) {
|
|
682
670
|
val minBatt = Math.min(batteryLeft, batteryRight)
|
|
683
|
-
// Bridge.log("G1: Minimum Battery Level: " + minBatt);
|
|
684
|
-
// EventBus.getDefault().post(new BatteryLevelEvent(minBatt, false));
|
|
685
671
|
DeviceStore.apply("glasses", "batteryLevel", minBatt)
|
|
686
672
|
}
|
|
687
673
|
}
|
|
@@ -695,28 +681,20 @@ class G1 : SGCManager() {
|
|
|
695
681
|
else if (data.size > 1 && (data[0].toInt() and 0xFF) == 0xF5 && (data[1].toInt() and 0xFF) == 0x08) {
|
|
696
682
|
DeviceStore.apply("glasses", "caseOpen", true)
|
|
697
683
|
DeviceStore.apply("glasses", "caseRemoved", false)
|
|
698
|
-
// EventBus.getDefault()
|
|
699
|
-
// .post(new CaseEvent(caseBatteryLevel, caseCharging, caseOpen, caseRemoved));
|
|
700
684
|
}
|
|
701
685
|
// CASE CLOSED
|
|
702
686
|
else if (data.size > 1 && (data[0].toInt() and 0xFF) == 0xF5 && (data[1].toInt() and 0xFF) == 0x0B) {
|
|
703
687
|
DeviceStore.apply("glasses", "caseOpen", false)
|
|
704
688
|
DeviceStore.apply("glasses", "caseRemoved", false)
|
|
705
|
-
// EventBus.getDefault()
|
|
706
|
-
// .post(new CaseEvent(caseBatteryLevel, caseCharging, caseOpen, caseRemoved));
|
|
707
689
|
}
|
|
708
690
|
// CASE CHARGING STATUS
|
|
709
691
|
else if (data.size > 3 && (data[0].toInt() and 0xFF) == 0xF5 && (data[1].toInt() and 0xFF) == 0x0E) {
|
|
710
692
|
DeviceStore.apply("glasses", "caseCharging", (data[2].toInt() and 0xFF) == 0x01)// TODO: verify this is correct
|
|
711
|
-
// EventBus.getDefault()
|
|
712
|
-
// .post(new CaseEvent(caseBatteryLevel, caseCharging, caseOpen, caseRemoved));
|
|
713
693
|
}
|
|
714
694
|
// CASE CHARGING INFO
|
|
715
695
|
else if (data.size > 3 && (data[0].toInt() and 0xFF) == 0xF5 && (data[1].toInt() and 0xFF) == 0x0F) {
|
|
716
696
|
val newCaseBatteryLevel = (data[2].toInt() and 0xFF)// TODO: verify this is correct
|
|
717
697
|
DeviceStore.apply("glasses", "caseBatteryLevel", newCaseBatteryLevel)
|
|
718
|
-
// EventBus.getDefault()
|
|
719
|
-
// .post(new CaseEvent(caseBatteryLevel, caseCharging, caseOpen, caseRemoved));
|
|
720
698
|
}
|
|
721
699
|
// HEARTBEAT RESPONSE
|
|
722
700
|
else if (data.isNotEmpty() && data[0] == 0x25.toByte()) {
|
|
@@ -785,8 +763,6 @@ class G1 : SGCManager() {
|
|
|
785
763
|
if ("Left" == side) {
|
|
786
764
|
isLeftConnected = true
|
|
787
765
|
Bridge.log("G1: PROC_QUEUE - left side setup complete")
|
|
788
|
-
|
|
789
|
-
// Manufacturer data decoding moved to connection start
|
|
790
766
|
} else {
|
|
791
767
|
isRightConnected = true
|
|
792
768
|
// Bridge.log("G1: PROC_QUEUE - right side setup complete");
|
|
@@ -810,11 +786,8 @@ class G1 : SGCManager() {
|
|
|
810
786
|
// Bridge.log("G1: Sending debug 0xF4 Command");
|
|
811
787
|
// sendDataSequentially(new byte[]{(byte) 0xF4, (byte) 0x01});
|
|
812
788
|
|
|
813
|
-
// no longer need to be staggered as we fixed the sender
|
|
814
|
-
// do first battery status query
|
|
815
789
|
queryBatteryStatusHandler.postDelayed({ queryBatteryStatus() }, 10L)
|
|
816
790
|
|
|
817
|
-
// setup brightness
|
|
818
791
|
val brightnessValue = (DeviceStore.get("bluetooth", "brightness") as Number).toInt()
|
|
819
792
|
val shouldUseAutoBrightness = DeviceStore.get("bluetooth", "auto_brightness") as Boolean
|
|
820
793
|
sendBrightnessCommandHandler
|
|
@@ -2556,11 +2529,6 @@ class G1 : SGCManager() {
|
|
|
2556
2529
|
scanner.stopScan(bleScanCallback)
|
|
2557
2530
|
isScanningForCompatibleDevices = false
|
|
2558
2531
|
Bridge.log("G1: Stopped scanning for smart glasses.")
|
|
2559
|
-
// EventBus.getDefault().post(
|
|
2560
|
-
// new GlassesBluetoothSearchStopEvent(
|
|
2561
|
-
// smartGlassesDevice.deviceModelName
|
|
2562
|
-
// )
|
|
2563
|
-
// );
|
|
2564
2532
|
}, 10000L)
|
|
2565
2533
|
}
|
|
2566
2534
|
|
|
@@ -2650,13 +2618,6 @@ class G1 : SGCManager() {
|
|
|
2650
2618
|
|
|
2651
2619
|
Bridge.log("G1: Sent auto light brightness command => Brightness: " + brightness + ", Auto Light: "
|
|
2652
2620
|
+ (if (autoLight) "Open" else "Close"))
|
|
2653
|
-
|
|
2654
|
-
// send to AugmentOS core
|
|
2655
|
-
// if (autoLight) {
|
|
2656
|
-
// EventBus.getDefault().post(new BrightnessLevelEvent(autoLight));
|
|
2657
|
-
// } else {
|
|
2658
|
-
// EventBus.getDefault().post(new BrightnessLevelEvent(brightness));
|
|
2659
|
-
// }
|
|
2660
2621
|
}
|
|
2661
2622
|
|
|
2662
2623
|
fun sendHeadUpAngleCommand(headUpAngle: Int) {
|
|
@@ -2677,7 +2638,6 @@ class G1 : SGCManager() {
|
|
|
2677
2638
|
sendDataSequentially(buffer.array(), false, 100)
|
|
2678
2639
|
|
|
2679
2640
|
Bridge.log("G1: Sent headUp angle command => Angle: " + headUpAngleValue)
|
|
2680
|
-
// EventBus.getDefault().post(new HeadUpAngleEvent(headUpAngle));
|
|
2681
2641
|
}
|
|
2682
2642
|
|
|
2683
2643
|
fun sendDashboardPositionCommand(height: Int, depth: Int) {
|
|
@@ -2700,7 +2660,6 @@ class G1 : SGCManager() {
|
|
|
2700
2660
|
sendDataSequentially(buffer.array(), false, 100)
|
|
2701
2661
|
|
|
2702
2662
|
Bridge.log("G1: Sent dashboard height/depth command => Height: " + heightValue + ", Depth: " + depthValue)
|
|
2703
|
-
// EventBus.getDefault().post(new DashboardPositionEvent(height, depth));
|
|
2704
2663
|
}
|
|
2705
2664
|
|
|
2706
2665
|
fun updateGlassesBrightness(brightness: Int) {
|
|
@@ -6091,8 +6091,9 @@ class G2 : SGCManager() {
|
|
|
6091
6091
|
setControllerFullyConnected()
|
|
6092
6092
|
}
|
|
6093
6093
|
|
|
6094
|
-
// Double-tap policy (dashboard vs head-up toggle)
|
|
6095
|
-
// DeviceEventRouter, which subscribes to the touch_event stream.
|
|
6094
|
+
// Double-tap policy (dashboard vs head-up toggle) belongs to the engine's
|
|
6095
|
+
// DeviceEventRouter, which subscribes to the touch_event stream. Do not
|
|
6096
|
+
// act on it here.
|
|
6096
6097
|
|
|
6097
6098
|
// System exit: the firmware killed our page (and the mic). ONLY mark state dead; do
|
|
6098
6099
|
// NOT rebuild here. systemExit is fired alongside the dashboard-close (08011A00) event
|
|
@@ -25,17 +25,8 @@ import com.glassly.bluetoothsdk.utils.MessageChunker
|
|
|
25
25
|
import com.glassly.bluetoothsdk.utils.audio.Lc3Player
|
|
26
26
|
import com.glassly.bluetoothsdk.utils.BlePhotoUploadService
|
|
27
27
|
import com.glassly.bluetoothsdk.DeviceStore
|
|
28
|
-
|
|
29
|
-
// import com.augmentos.augmentos_core.R;
|
|
30
|
-
// import com.augmentos.augmentos_core.smarterglassesmanager.smartglassescommunicators.SmartGlassesCommunicator;
|
|
31
|
-
// import com.augmentos.augmentos_core.smarterglassesmanager.smartglassescommunicators.SmartGlassesFontSize;
|
|
32
|
-
// import com.augmentos.augmentos_core.smarterglassesmanager.utils.SmartGlassesConnectionState;
|
|
33
28
|
import com.squareup.picasso.Picasso
|
|
34
29
|
import com.squareup.picasso.Target
|
|
35
|
-
// import com.augmentos.augmentos_core.smarterglassesmanager.eventbusmessages.BatteryLevelEvent;
|
|
36
|
-
// import com.augmentos.augmentos_core.smarterglassesmanager.eventbusmessages.GlassesBluetoothSearchDiscoverEvent;
|
|
37
|
-
// import com.augmentos.augmentos_core.smarterglassesmanager.eventbusmessages.GlassesDisplayPowerEvent;
|
|
38
|
-
// import com.augmentos.augmentos_core.smarterglassesmanager.supportedglasses.SmartGlassesDevice;
|
|
39
30
|
import com.vuzix.ultralite.Anchor
|
|
40
31
|
import com.vuzix.ultralite.BatteryStatus
|
|
41
32
|
import com.vuzix.ultralite.EventListener
|
|
@@ -45,7 +36,6 @@ import com.vuzix.ultralite.TextWrapMode
|
|
|
45
36
|
import com.vuzix.ultralite.UltraliteColor
|
|
46
37
|
import com.vuzix.ultralite.UltraliteSDK
|
|
47
38
|
|
|
48
|
-
import org.greenrobot.eventbus.EventBus
|
|
49
39
|
|
|
50
40
|
import java.util.ArrayList
|
|
51
41
|
import java.util.Arrays
|
|
@@ -434,7 +424,6 @@ class Mach1 : SGCManager() {
|
|
|
434
424
|
|
|
435
425
|
if (!screenToggleOff) {
|
|
436
426
|
Log.d(TAG, "screen toggle off NOT on, showing turn ON message")
|
|
437
|
-
// EventBus.getDefault().post(new GlassesDisplayPowerEvent(screenToggleOff));
|
|
438
427
|
} else {
|
|
439
428
|
Log.d(TAG, "screen toggle off IS on")
|
|
440
429
|
}
|
|
@@ -585,9 +574,7 @@ class Mach1 : SGCManager() {
|
|
|
585
574
|
}
|
|
586
575
|
|
|
587
576
|
fun findCompatibleDeviceNames() {
|
|
588
|
-
// EventBus.getDefault().post(new GlassesBluetoothSearchDiscoverEvent(smartGlassesDevice.deviceModelName, "NOTREQUIREDSKIP"));
|
|
589
577
|
Bridge.sendDiscoveredDevice(this.type, "NOTREQUIREDSKIP") // Use this.type to support both Mach1 and Z100
|
|
590
|
-
//this.destroy();
|
|
591
578
|
}
|
|
592
579
|
|
|
593
580
|
fun connectToSmartGlasses() {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
package com.glassly.bluetoothsdk.sgcs
|
|
2
2
|
|
|
3
|
-
// Glassly
|
|
4
|
-
// old augmentos imports:
|
|
5
3
|
import android.Manifest
|
|
6
4
|
import android.bluetooth.BluetoothA2dp
|
|
7
5
|
import android.bluetooth.BluetoothAdapter
|
|
@@ -2125,19 +2123,6 @@ class MentraLive : SGCManager() {
|
|
|
2125
2123
|
)
|
|
2126
2124
|
}
|
|
2127
2125
|
|
|
2128
|
-
// Save the connected device name for future reconnections
|
|
2129
|
-
// no longer needed as we now save it immediately in connectToDevice()
|
|
2130
|
-
// if (connectedDevice != null && connectedDevice.getName() != null) {
|
|
2131
|
-
// SharedPreferences prefs =
|
|
2132
|
-
// context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
|
|
2133
|
-
// prefs.edit().putString(PREF_DEVICE_NAME,
|
|
2134
|
-
// connectedDevice.getName()).apply();
|
|
2135
|
-
// Log.i(TAG, "🔌 💾 Saved device name for future reconnection: " +
|
|
2136
|
-
// connectedDevice.getName());
|
|
2137
|
-
// Bridge.log("LIVE: Saved device name for future reconnection: " +
|
|
2138
|
-
// connectedDevice.getName());
|
|
2139
|
-
// }
|
|
2140
|
-
|
|
2141
2126
|
// Register early so we don't miss bond broadcasts, but defer
|
|
2142
2127
|
// createBond / A2DP until BLE GATT setup finishes (see
|
|
2143
2128
|
// maybeInitiateCtkdAudioAfterBleReady).
|
|
@@ -4404,8 +4389,8 @@ class MentraLive : SGCManager() {
|
|
|
4404
4389
|
}
|
|
4405
4390
|
}
|
|
4406
4391
|
|
|
4407
|
-
//
|
|
4408
|
-
//
|
|
4392
|
+
// version_info_1 / version_info_2 fall through to the default case,
|
|
4393
|
+
// which prefix-matches every chunk variant.
|
|
4409
4394
|
|
|
4410
4395
|
"version_info" -> {
|
|
4411
4396
|
// Process version information from ASG client (legacy single-message format)
|
|
@@ -4490,51 +4475,21 @@ class MentraLive : SGCManager() {
|
|
|
4490
4475
|
else "")
|
|
4491
4476
|
)
|
|
4492
4477
|
|
|
4493
|
-
//
|
|
4478
|
+
// Status is validated only; progress is surfaced via the logs above.
|
|
4494
4479
|
try {
|
|
4495
|
-
// DownloadProgressEvent.DownloadStatus downloadEventStatus;
|
|
4496
|
-
// final DownloadProgressEvent event;
|
|
4497
4480
|
when (downloadStatus) {
|
|
4498
|
-
"STARTED" -> {
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
}
|
|
4502
|
-
"PROGRESS" -> {
|
|
4503
|
-
// downloadEventStatus = DownloadProgressEvent.DownloadStatus.PROGRESS;
|
|
4504
|
-
// event = new DownloadProgressEvent(downloadEventStatus,
|
|
4505
|
-
// downloadProgress, bytesDownloaded, totalBytes);
|
|
4506
|
-
}
|
|
4507
|
-
"FINISHED" -> {
|
|
4508
|
-
// downloadEventStatus = DownloadProgressEvent.DownloadStatus.FINISHED;
|
|
4509
|
-
// event = new DownloadProgressEvent(downloadEventStatus, totalBytes,
|
|
4510
|
-
// true);
|
|
4511
|
-
}
|
|
4512
|
-
"FAILED" -> {
|
|
4513
|
-
// downloadEventStatus = DownloadProgressEvent.DownloadStatus.FAILED;
|
|
4514
|
-
// event = new DownloadProgressEvent(downloadEventStatus,
|
|
4515
|
-
// downloadErrorMessage);
|
|
4516
|
-
}
|
|
4481
|
+
"STARTED" -> {}
|
|
4482
|
+
"PROGRESS" -> {}
|
|
4483
|
+
"FINISHED" -> {}
|
|
4484
|
+
"FAILED" -> {}
|
|
4517
4485
|
else -> {
|
|
4518
4486
|
Log.w(TAG, "Unknown download status: " + downloadStatus)
|
|
4519
4487
|
return
|
|
4520
4488
|
}
|
|
4521
4489
|
}
|
|
4522
|
-
|
|
4523
|
-
// Post event on main thread to ensure proper delivery
|
|
4524
|
-
handler.post {
|
|
4525
|
-
// Bridge.log("LIVE: 📡 Posting download progress event on main thread: " +
|
|
4526
|
-
// downloadEventStatus);
|
|
4527
|
-
// EventBus.getDefault().post(event);
|
|
4528
|
-
// Bridge.
|
|
4529
|
-
}
|
|
4530
4490
|
} catch (e: Exception) {
|
|
4531
4491
|
Log.e(TAG, "Error creating download progress event", e)
|
|
4532
4492
|
}
|
|
4533
|
-
|
|
4534
|
-
// Forward to data observable for cloud communication
|
|
4535
|
-
// if (dataObservable != null) {
|
|
4536
|
-
// dataObservable.onNext(json);
|
|
4537
|
-
// }
|
|
4538
4493
|
}
|
|
4539
4494
|
"ota_installation_progress" -> {
|
|
4540
4495
|
// Process OTA installation progress from ASG client
|
|
@@ -4559,49 +4514,19 @@ class MentraLive : SGCManager() {
|
|
|
4559
4514
|
else "")
|
|
4560
4515
|
)
|
|
4561
4516
|
|
|
4562
|
-
//
|
|
4517
|
+
// Status is validated only; progress is surfaced via the logs above.
|
|
4563
4518
|
try {
|
|
4564
|
-
// InstallationProgressEvent.InstallationStatus installationEventStatus;
|
|
4565
|
-
// final InstallationProgressEvent event;
|
|
4566
4519
|
when (installationStatus) {
|
|
4567
|
-
"STARTED" -> {
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
// event = new InstallationProgressEvent(installationEventStatus,
|
|
4571
|
-
// apkPath);
|
|
4572
|
-
}
|
|
4573
|
-
"FINISHED" -> {
|
|
4574
|
-
// installationEventStatus =
|
|
4575
|
-
// InstallationProgressEvent.InstallationStatus.FINISHED;
|
|
4576
|
-
// event = new InstallationProgressEvent(installationEventStatus,
|
|
4577
|
-
// apkPath);
|
|
4578
|
-
}
|
|
4579
|
-
"FAILED" -> {
|
|
4580
|
-
// installationEventStatus =
|
|
4581
|
-
// InstallationProgressEvent.InstallationStatus.FAILED;
|
|
4582
|
-
// event = new InstallationProgressEvent(installationEventStatus,
|
|
4583
|
-
// apkPath, installationErrorMessage);
|
|
4584
|
-
}
|
|
4520
|
+
"STARTED" -> {}
|
|
4521
|
+
"FINISHED" -> {}
|
|
4522
|
+
"FAILED" -> {}
|
|
4585
4523
|
else -> {
|
|
4586
|
-
// Log.w(TAG, "Unknown installation status: " + installationStatus);
|
|
4587
4524
|
return
|
|
4588
4525
|
}
|
|
4589
4526
|
}
|
|
4590
|
-
|
|
4591
|
-
// Post event on main thread to ensure proper delivery
|
|
4592
|
-
handler.post {
|
|
4593
|
-
// Bridge.log("LIVE: 📡 Posting installation progress event on main thread:
|
|
4594
|
-
// " + installationEventStatus);
|
|
4595
|
-
// EventBus.getDefault().post(event);
|
|
4596
|
-
}
|
|
4597
4527
|
} catch (e: Exception) {
|
|
4598
4528
|
Log.e(TAG, "Error creating installation progress event", e)
|
|
4599
4529
|
}
|
|
4600
|
-
|
|
4601
|
-
// Forward to data observable for cloud communication
|
|
4602
|
-
// if (dataObservable != null) {
|
|
4603
|
-
// dataObservable.onNext(json);
|
|
4604
|
-
// }
|
|
4605
4530
|
}
|
|
4606
4531
|
"mtk_update_complete" -> {
|
|
4607
4532
|
// Process MTK firmware update complete notification from ASG client
|
|
@@ -1069,8 +1069,7 @@ class MentraNex : SGCManager() {
|
|
|
1069
1069
|
queryBatteryStatus()
|
|
1070
1070
|
}
|
|
1071
1071
|
MAIN_TASK_HANDLER_CODE_HEART_BEAT -> {
|
|
1072
|
-
//
|
|
1073
|
-
// This case is kept for backward compatibility but no longer used
|
|
1072
|
+
// No-op: heartbeat is driven by the ping the glasses send us.
|
|
1074
1073
|
}
|
|
1075
1074
|
else -> { }
|
|
1076
1075
|
}
|
|
@@ -1613,8 +1612,6 @@ class MentraNex : SGCManager() {
|
|
|
1613
1612
|
lastConnectionTimestamp = System.currentTimeMillis()
|
|
1614
1613
|
DeviceStore.apply("glasses", "fullyBooted", true)
|
|
1615
1614
|
DeviceStore.apply("glasses", "connected", true)
|
|
1616
|
-
// Removed commented sleep code as it's not needed
|
|
1617
|
-
// connectionEvent(it)
|
|
1618
1615
|
} else {
|
|
1619
1616
|
DeviceStore.apply("glasses", "connectionState", ConnTypes.DISCONNECTED)
|
|
1620
1617
|
Bridge.log("Nex: No Main glasses connected")
|
|
@@ -18,8 +18,6 @@ import java.nio.ByteOrder
|
|
|
18
18
|
* - 8-second silence timeout before declaring "not speaking"
|
|
19
19
|
* - Bypass modes for debugging and PCM streaming
|
|
20
20
|
* - 512-sample frame size (matches Sherpa-ONNX requirements)
|
|
21
|
-
*
|
|
22
|
-
* Ported from android_core VadGateSpeechPolicy.java
|
|
23
21
|
*/
|
|
24
22
|
class VadGateSpeechPolicy(private val context: Context) {
|
|
25
23
|
companion object {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/** Generated from /changelogs. Do not edit directly. */
|
|
2
2
|
export declare const GENERATED_RELEASE_CHANGELOGS: readonly [{
|
|
3
|
+
readonly version: "3.2.0";
|
|
4
|
+
readonly markdown: "This release is under active development. User-facing changes will be documented as they land.";
|
|
5
|
+
}, {
|
|
3
6
|
readonly version: "3.1.0";
|
|
4
7
|
readonly markdown: "Software updates are more reliable, with clearer progress and recovery when the glasses restart.\n\n- GlasslyOS, Glassly Engine, the Bluetooth SDK, and the glasses client now share one coordinated release version.\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic.";
|
|
5
8
|
}, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelogCatalog.d.ts","sourceRoot":"","sources":["../../src/generated/changelogCatalog.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,eAAO,MAAM,4BAA4B
|
|
1
|
+
{"version":3,"file":"changelogCatalog.d.ts","sourceRoot":"","sources":["../../src/generated/changelogCatalog.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,eAAO,MAAM,4BAA4B;;;;;;;;;EAexC,CAAA"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/** Generated from /changelogs. Do not edit directly. */
|
|
2
2
|
export const GENERATED_RELEASE_CHANGELOGS = Object.freeze([
|
|
3
|
+
{
|
|
4
|
+
"version": "3.2.0",
|
|
5
|
+
"markdown": "This release is under active development. User-facing changes will be documented as they land."
|
|
6
|
+
},
|
|
3
7
|
{
|
|
4
8
|
"version": "3.1.0",
|
|
5
9
|
"markdown": "Software updates are more reliable, with clearer progress and recovery when the glasses restart.\n\n- GlasslyOS, Glassly Engine, the Bluetooth SDK, and the glasses client now share one coordinated release version.\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic."
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelogCatalog.js","sourceRoot":"","sources":["../../src/generated/changelogCatalog.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,CACzD;IACE;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,idAAid;KAC9d;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,odAAod;KACje;CACO,CACT,CAAA","sourcesContent":["/** Generated from /changelogs. Do not edit directly. */\nexport const GENERATED_RELEASE_CHANGELOGS = Object.freeze(\n[\n {\n \"version\": \"3.1.0\",\n \"markdown\": \"Software updates are more reliable, with clearer progress and recovery when the glasses restart.\\n\\n- GlasslyOS, Glassly Engine, the Bluetooth SDK, and the glasses client now share one coordinated release version.\\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic.\"\n },\n {\n \"version\": \"0.1.0\",\n \"markdown\": \"First coordinated Glassly release: the app, Glassly Engine, and the Bluetooth SDK now ship one shared release version.\\n\\n- The Glassly App, Glassly Engine, and the Bluetooth SDK are versioned and published together.\\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic.\"\n }\n] as const,\n)\n"]}
|
|
1
|
+
{"version":3,"file":"changelogCatalog.js","sourceRoot":"","sources":["../../src/generated/changelogCatalog.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,CACzD;IACE;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,gGAAgG;KAC7G;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,idAAid;KAC9d;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,odAAod;KACje;CACO,CACT,CAAA","sourcesContent":["/** Generated from /changelogs. Do not edit directly. */\nexport const GENERATED_RELEASE_CHANGELOGS = Object.freeze(\n[\n {\n \"version\": \"3.2.0\",\n \"markdown\": \"This release is under active development. User-facing changes will be documented as they land.\"\n },\n {\n \"version\": \"3.1.0\",\n \"markdown\": \"Software updates are more reliable, with clearer progress and recovery when the glasses restart.\\n\\n- GlasslyOS, Glassly Engine, the Bluetooth SDK, and the glasses client now share one coordinated release version.\\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic.\"\n },\n {\n \"version\": \"0.1.0\",\n \"markdown\": \"First coordinated Glassly release: the app, Glassly Engine, and the Bluetooth SDK now ship one shared release version.\\n\\n- The Glassly App, Glassly Engine, and the Bluetooth SDK are versioned and published together.\\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic.\"\n }\n] as const,\n)\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export const BLUETOOTH_SDK_RELEASE_METADATA = Object.freeze({
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"familyBaseVersion": "0.1.0",
|
|
4
|
-
"releaseIdentity": "0.1.0-dev.
|
|
5
|
-
"releaseSetId": "glassly-0.1.0-dev.
|
|
6
|
-
"sourceCommit": "
|
|
4
|
+
"releaseIdentity": "0.1.0-dev.96",
|
|
5
|
+
"releaseSetId": "glassly-0.1.0-dev.96",
|
|
6
|
+
"sourceCommit": "440518cf281588df779cd13d78922782db027ad4",
|
|
7
7
|
"otaManifestUrl": null,
|
|
8
8
|
"otaManifestSha256": null
|
|
9
9
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,8BAA8B,GAA0C,MAAM,CAAC,MAAM,CAAC;IACjG,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,cAAc;IACjC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface BluetoothSdkReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const BLUETOOTH_SDK_RELEASE_METADATA: Readonly<BluetoothSdkReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.1.0\",\n \"releaseIdentity\": \"0.1.0-dev.
|
|
1
|
+
{"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,8BAA8B,GAA0C,MAAM,CAAC,MAAM,CAAC;IACjG,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,cAAc;IACjC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,IAAI;IACtB,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface BluetoothSdkReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const BLUETOOTH_SDK_RELEASE_METADATA: Readonly<BluetoothSdkReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"0.1.0\",\n \"releaseIdentity\": \"0.1.0-dev.96\",\n \"releaseSetId\": \"glassly-0.1.0-dev.96\",\n \"sourceCommit\": \"440518cf281588df779cd13d78922782db027ad4\",\n \"otaManifestUrl\": null,\n \"otaManifestSha256\": null\n})\n"]}
|
|
@@ -11,7 +11,7 @@ enum BluetoothSdkDefaults {
|
|
|
11
11
|
static let voiceActivityDetectionEnabled = false
|
|
12
12
|
static let loudnessGateEnabled = true
|
|
13
13
|
private static let infoSdkVersionKey = "BluetoothSdkVersion"
|
|
14
|
-
private static let swiftPackageSdkVersion = "0.1.0-dev.
|
|
14
|
+
private static let swiftPackageSdkVersion = "0.1.0-dev.96"
|
|
15
15
|
private static let swiftPackageSdkVersionPlaceholder = "__GLASSLY" + "_BLUETOOTH_SDK_VERSION__"
|
|
16
16
|
|
|
17
17
|
private static func normalizedSdkVersion(_ value: String?) -> String? {
|
|
@@ -589,8 +589,8 @@ struct ViewState {
|
|
|
589
589
|
func setOnboardMicEnabled(_ isEnabled: Bool) {
|
|
590
590
|
Task {
|
|
591
591
|
if isEnabled {
|
|
592
|
-
//
|
|
593
|
-
//
|
|
592
|
+
// Check only; never request from Swift. The React Native UI flow
|
|
593
|
+
// owns the mic permission prompt.
|
|
594
594
|
if !(PhoneMic.shared.checkPermissions()) {
|
|
595
595
|
Bridge.log("Microphone permissions not granted. Cannot enable microphone.")
|
|
596
596
|
return
|
|
@@ -1293,11 +1293,9 @@ struct ViewState {
|
|
|
1293
1293
|
}
|
|
1294
1294
|
}
|
|
1295
1295
|
|
|
1296
|
-
//
|
|
1297
|
-
//
|
|
1298
|
-
//
|
|
1299
|
-
// clobbers anything. Legacy positioned_text now flows through the slot
|
|
1300
|
-
// like every other layout (matching Android).
|
|
1296
|
+
// positioned_text flows through the viewState slot like every other
|
|
1297
|
+
// layout (matching Android): multi-element frames arrive as ONE scene
|
|
1298
|
+
// event, so nothing clobbers anything.
|
|
1301
1299
|
|
|
1302
1300
|
let cS = viewState
|
|
1303
1301
|
let nS = newViewState
|
|
@@ -2,6 +2,7 @@ import Foundation
|
|
|
2
2
|
|
|
3
3
|
/// Generated from /changelogs. Do not edit directly.
|
|
4
4
|
let generatedReleaseChangelogs: [ReleaseChangelog] = [
|
|
5
|
+
ReleaseChangelog(version: "3.2.0", markdown: "This release is under active development. User-facing changes will be documented as they land."),
|
|
5
6
|
ReleaseChangelog(version: "3.1.0", markdown: "Software updates are more reliable, with clearer progress and recovery when the glasses restart.\n\n- GlasslyOS, Glassly Engine, the Bluetooth SDK, and the glasses client now share one coordinated release version.\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic."),
|
|
6
7
|
ReleaseChangelog(version: "0.1.0", markdown: "First coordinated Glassly release: the app, Glassly Engine, and the Bluetooth SDK now ship one shared release version.\n\n- The Glassly App, Glassly Engine, and the Bluetooth SDK are versioned and published together.\n- Mentra Live updates can continue across APK, system, and firmware restarts without asking the user to start the same update again.\n- Bluetooth photo capture and transfer diagnostics are more precise and less disruptive to normal glasses traffic."),
|
|
7
8
|
]
|
|
@@ -3,9 +3,9 @@ import Foundation
|
|
|
3
3
|
/// Generated by release CI. Do not edit in a release checkout.
|
|
4
4
|
enum GeneratedReleaseMetadata {
|
|
5
5
|
static let familyBaseVersion = "0.1.0"
|
|
6
|
-
static let releaseIdentity = "0.1.0-dev.
|
|
7
|
-
static let releaseSetId = "glassly-0.1.0-dev.
|
|
8
|
-
static let sourceCommit = "
|
|
6
|
+
static let releaseIdentity = "0.1.0-dev.96"
|
|
7
|
+
static let releaseSetId = "glassly-0.1.0-dev.96"
|
|
8
|
+
static let sourceCommit = "440518cf281588df779cd13d78922782db027ad4"
|
|
9
9
|
static let otaManifestUrl = ""
|
|
10
10
|
static let otaManifestSha256 = ""
|
|
11
11
|
}
|
package/ios/Source/sgcs/G2.swift
CHANGED
|
@@ -6180,16 +6180,9 @@ final class G2: NSObject, SGCManager {
|
|
|
6180
6180
|
setControllerFullyConnected()
|
|
6181
6181
|
}
|
|
6182
6182
|
|
|
6183
|
-
// Double-tap policy (dashboard vs head-up toggle)
|
|
6184
|
-
// DeviceEventRouter, which subscribes to the touch_event
|
|
6185
|
-
|
|
6186
|
-
// if eventType == .foregroundEnter {
|
|
6187
|
-
// Bridge.log("G2: Foreground enter detected")
|
|
6188
|
-
// }
|
|
6189
|
-
|
|
6190
|
-
// if eventType == .click {
|
|
6191
|
-
// Bridge.log("G2: Click detected")
|
|
6192
|
-
// }
|
|
6183
|
+
// Double-tap policy (dashboard vs head-up toggle) belongs to the
|
|
6184
|
+
// engine's DeviceEventRouter, which subscribes to the touch_event
|
|
6185
|
+
// stream. Do not act on it here.
|
|
6193
6186
|
|
|
6194
6187
|
// System exit: the firmware killed our page (and the mic). ONLY mark state dead;
|
|
6195
6188
|
// do NOT rebuild here. systemExit is fired alongside the dashboard-close (08011A00)
|
|
@@ -2865,8 +2865,8 @@ class MentraLive: NSObject, SGCManager {
|
|
|
2865
2865
|
case "button_press":
|
|
2866
2866
|
handleButtonPress(json)
|
|
2867
2867
|
|
|
2868
|
-
//
|
|
2869
|
-
//
|
|
2868
|
+
// version_info* falls through to the default case, which prefix-matches
|
|
2869
|
+
// every chunk variant.
|
|
2870
2870
|
|
|
2871
2871
|
case "touch_event":
|
|
2872
2872
|
let gestureName = json["gesture_name"] as? String ?? "unknown"
|
|
@@ -4015,8 +4015,8 @@ class MentraLive: NSObject, SGCManager {
|
|
|
4015
4015
|
}
|
|
4016
4016
|
}
|
|
4017
4017
|
|
|
4018
|
-
//
|
|
4019
|
-
//
|
|
4018
|
+
// There is no per-packet re-request: the phone sends transfer_complete with
|
|
4019
|
+
// success=false to trigger a full retry.
|
|
4020
4020
|
|
|
4021
4021
|
// MARK: - File Transfer Processing
|
|
4022
4022
|
|