@mentra/bluetooth-sdk 3.2.1-beta.315 → 3.2.1-beta.354

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 (83) hide show
  1. package/README.md +1 -1
  2. package/android/src/debug/java/com/mentra/bluetoothsdk/sgcs/NimoDiagnostics.kt +368 -0
  3. package/android/src/debug/java/com/mentra/bluetoothsdk/sgcs/NimoFramebufferProtocol.kt +156 -0
  4. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkDefaults.kt +3 -0
  5. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +4 -0
  6. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +2 -1
  7. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +67 -12
  8. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +37 -13
  9. package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedChangelogCatalog.kt +1 -1
  10. package/android/src/main/java/com/mentra/bluetoothsdk/GeneratedReleaseMetadata.kt +5 -5
  11. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +4 -0
  12. package/android/src/main/java/com/mentra/bluetoothsdk/VersionInfoResponseAccumulator.kt +13 -2
  13. package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +33 -0
  14. package/android/src/main/java/com/mentra/bluetoothsdk/services/G2ConnectionRecovery.kt +47 -0
  15. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +64 -14
  16. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +73 -3
  17. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Nimo.kt +257 -395
  18. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCodec.kt +245 -0
  19. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCoordinator.kt +225 -0
  20. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasEncoder.kt +58 -0
  21. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasSession.kt +168 -0
  22. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +11 -0
  23. package/android/src/main/java/com/mentra/bluetoothsdk/utils/G2Text.kt +7 -0
  24. package/android/src/release/java/com/mentra/bluetoothsdk/sgcs/NimoDiagnostics.kt +20 -0
  25. package/android/src/test/java/com/mentra/bluetoothsdk/DeviceManagerSceneHandoffTest.kt +557 -0
  26. package/android/src/test/java/com/mentra/bluetoothsdk/G2TextTest.kt +13 -0
  27. package/android/src/test/java/com/mentra/bluetoothsdk/VersionInfoResponseAccumulatorTest.kt +71 -0
  28. package/android/src/test/java/com/mentra/bluetoothsdk/services/G2ConnectionRecoveryTest.kt +51 -0
  29. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/G2DisplayThreadTest.kt +120 -0
  30. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoBitmapAcceptanceTest.kt +105 -0
  31. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCodecTest.kt +220 -0
  32. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasCoordinatorTest.kt +308 -0
  33. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/NimoCanvasSessionTest.kt +270 -0
  34. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoDiagnosticsTest.kt +287 -0
  35. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoFramebufferProtocolTest.kt +127 -0
  36. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoLifecycleTest.kt +194 -0
  37. package/android/src/testDebug/java/com/mentra/bluetoothsdk/sgcs/NimoReadinessDriverTest.kt +199 -0
  38. package/build/BluetoothSdk.types.d.ts +11 -0
  39. package/build/BluetoothSdk.types.d.ts.map +1 -1
  40. package/build/BluetoothSdk.types.js.map +1 -1
  41. package/build/_private/BluetoothSdkModule.d.ts +2 -0
  42. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  43. package/build/_private/BluetoothSdkModule.js +3 -0
  44. package/build/_private/BluetoothSdkModule.js.map +1 -1
  45. package/build/generated/changelogCatalog.d.ts +1 -1
  46. package/build/generated/changelogCatalog.js +1 -1
  47. package/build/generated/changelogCatalog.js.map +1 -1
  48. package/build/generated/releaseMetadata.js +5 -5
  49. package/build/generated/releaseMetadata.js.map +1 -1
  50. package/build/index.d.ts.map +1 -1
  51. package/build/index.js +1 -0
  52. package/build/index.js.map +1 -1
  53. package/ios/BluetoothSdkModule.swift +5 -0
  54. package/ios/MentraBluetoothSDK.podspec +3 -2
  55. package/ios/Source/BluetoothSdkDefaults.swift +6 -1
  56. package/ios/Source/Bridge.swift +15 -2
  57. package/ios/Source/DeviceManager.swift +23 -10
  58. package/ios/Source/DeviceStore.swift +26 -7
  59. package/ios/Source/GeneratedChangelogCatalog.swift +1 -1
  60. package/ios/Source/GeneratedReleaseMetadata.swift +5 -5
  61. package/ios/Source/MentraBluetoothSDK.swift +4 -0
  62. package/ios/Source/requests/VersionInfoResponseAccumulator.swift +11 -1
  63. package/ios/Source/sgcs/G2.swift +2 -2
  64. package/ios/Source/sgcs/MentraLive.swift +66 -3
  65. package/ios/Source/sgcs/Nimo.swift +182 -371
  66. package/ios/Source/sgcs/NimoCanvasCodec.swift +269 -0
  67. package/ios/Source/sgcs/NimoCanvasCoordinator.swift +219 -0
  68. package/ios/Source/sgcs/NimoCanvasImage.swift +53 -0
  69. package/ios/Source/sgcs/NimoCanvasSession.swift +150 -0
  70. package/ios/Source/sgcs/SGCManager.swift +24 -0
  71. package/ios/Source/utils/G2Text.swift +11 -0
  72. package/ios/Tests/DashboardRenderingTests.swift +31 -0
  73. package/ios/Tests/G2TextTests.swift +10 -0
  74. package/ios/Tests/NimoCanvasCodecTests.swift +204 -0
  75. package/ios/Tests/NimoCanvasSessionTests.swift +112 -0
  76. package/ios/Tests/NimoCanvasTransportTests.swift +161 -0
  77. package/ios/Tests/VersionInfoResponseAccumulatorTests.swift +65 -0
  78. package/package.json +2 -2
  79. package/src/BluetoothSdk.types.ts +11 -0
  80. package/src/_private/BluetoothSdkModule.ts +6 -0
  81. package/src/generated/changelogCatalog.ts +1 -1
  82. package/src/generated/releaseMetadata.ts +5 -5
  83. package/src/index.ts +1 -0
@@ -1,7 +1,7 @@
1
1
  /** Generated from /changelogs. Do not edit directly. */
2
2
  export declare const GENERATED_RELEASE_CHANGELOGS: readonly [{
3
3
  readonly version: "3.2.1";
4
- readonly markdown: "This release is under active development. User-facing changes will be documented as they land.";
4
+ readonly markdown: "This release is under active development. User-facing changes will be documented as they land.\n\n- Mentra Miniapp SDK: `session.stream.preview({source: \"call\"})` and the `<StreamPreview>` component (from `@mentra/miniapp/react`) show the live video of a call your miniapp owns inside its UI. Requires the `CAMERA` permission; the lease survives the UI closing and ends with `handle.stop()` or the meeting. See [Stream preview](https://docs.mentraglass.com/app-devs/core-concepts/stream-preview).";
5
5
  }, {
6
6
  readonly version: "3.2.0";
7
7
  readonly markdown: "This release is under active development. User-facing changes will be documented as they land.\n\n- Breaking Bluetooth SDK change: `forgetWifiNetwork(ssid)` now returns `WifiForgetResult` instead of `WifiStatusChangeEvent`. Migrate status-only consumers to the semantic `outcome`; the requested network remains `ssid`, while optional post-command connectivity is reported by `connected`, `currentSsid`, and `localIp`.";
@@ -2,7 +2,7 @@
2
2
  export const GENERATED_RELEASE_CHANGELOGS = Object.freeze([
3
3
  {
4
4
  "version": "3.2.1",
5
- "markdown": "This release is under active development. User-facing changes will be documented as they land."
5
+ "markdown": "This release is under active development. User-facing changes will be documented as they land.\n\n- Mentra Miniapp SDK: `session.stream.preview({source: \"call\"})` and the `<StreamPreview>` component (from `@mentra/miniapp/react`) show the live video of a call your miniapp owns inside its UI. Requires the `CAMERA` permission; the lease survives the UI closing and ends with `handle.stop()` or the meeting. See [Stream preview](https://docs.mentraglass.com/app-devs/core-concepts/stream-preview)."
6
6
  },
7
7
  {
8
8
  "version": "3.2.0",
@@ -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,gGAAgG;KAC7G;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,maAAma;KAChb;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,wFAAwF;KACrG;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,mrCAAmrC;KAChsC;CACO,CACT,CAAA","sourcesContent":["/** Generated from /changelogs. Do not edit directly. */\nexport const GENERATED_RELEASE_CHANGELOGS = Object.freeze(\n[\n {\n \"version\": \"3.2.1\",\n \"markdown\": \"This release is under active development. User-facing changes will be documented as they land.\"\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- Breaking Bluetooth SDK change: `forgetWifiNetwork(ssid)` now returns `WifiForgetResult` instead of `WifiStatusChangeEvent`. Migrate status-only consumers to the semantic `outcome`; the requested network remains `ssid`, while optional post-command connectivity is reported by `connected`, `currentSsid`, and `localIp`.\"\n },\n {\n \"version\": \"3.1.1\",\n \"markdown\": \"- Improved Google login on iOS.\\n- Pairing no longer requires phone microphone access.\"\n },\n {\n \"version\": \"3.1.0\",\n \"markdown\": \"**Mentra App and glasses**\\n\\n- Improved glasses pairing and reconnection, including on iPad.\\n- Improved Android background reliability for captions and miniapps.\\n- Added Xingyi AR99 support.\\n- More reliable photo and video capture, with improved shutter sounds and privacy-light timing. Taking photos no longer interrupts your running miniapp.\\n- Added video thumbnails and smoother gallery browsing.\\n- Easier Mentra Live updates through your phone, with clearer progress and better recovery from interruptions.\\n\\n**Miniapp updates**\\n\\n- **Mentra AI:** Control whether photos are included with questions. Improved visual answers and connected-app follow-ups.\\n- **Captions:** Added offline transcription settings and top/bottom positioning on supported displays.\\n- **Translation:** Restored all 60 languages.\\n- **Mentra Maps:** Clearer directions on G1/G2, less display flickering, and improved Android offline routing.\\n- **Livestreamer:** More video-quality controls and custom streaming options, plus improved startup and sharing.\\n- **Merge:** Tap to expand an insight; swipe down or back to dismiss it.\\n- **Mentra Notes:** Smoother back navigation.\\n- **Recorder:** Fixed audio sharing.\"\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,ofAAof;KACjgB;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,maAAma;KAChb;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,wFAAwF;KACrG;IACD;QACE,SAAS,EAAE,OAAO;QAClB,UAAU,EAAE,mrCAAmrC;KAChsC;CACO,CACT,CAAA","sourcesContent":["/** Generated from /changelogs. Do not edit directly. */\nexport const GENERATED_RELEASE_CHANGELOGS = Object.freeze(\n[\n {\n \"version\": \"3.2.1\",\n \"markdown\": \"This release is under active development. User-facing changes will be documented as they land.\\n\\n- Mentra Miniapp SDK: `session.stream.preview({source: \\\"call\\\"})` and the `<StreamPreview>` component (from `@mentra/miniapp/react`) show the live video of a call your miniapp owns inside its UI. Requires the `CAMERA` permission; the lease survives the UI closing and ends with `handle.stop()` or the meeting. See [Stream preview](https://docs.mentraglass.com/app-devs/core-concepts/stream-preview).\"\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- Breaking Bluetooth SDK change: `forgetWifiNetwork(ssid)` now returns `WifiForgetResult` instead of `WifiStatusChangeEvent`. Migrate status-only consumers to the semantic `outcome`; the requested network remains `ssid`, while optional post-command connectivity is reported by `connected`, `currentSsid`, and `localIp`.\"\n },\n {\n \"version\": \"3.1.1\",\n \"markdown\": \"- Improved Google login on iOS.\\n- Pairing no longer requires phone microphone access.\"\n },\n {\n \"version\": \"3.1.0\",\n \"markdown\": \"**Mentra App and glasses**\\n\\n- Improved glasses pairing and reconnection, including on iPad.\\n- Improved Android background reliability for captions and miniapps.\\n- Added Xingyi AR99 support.\\n- More reliable photo and video capture, with improved shutter sounds and privacy-light timing. Taking photos no longer interrupts your running miniapp.\\n- Added video thumbnails and smoother gallery browsing.\\n- Easier Mentra Live updates through your phone, with clearer progress and better recovery from interruptions.\\n\\n**Miniapp updates**\\n\\n- **Mentra AI:** Control whether photos are included with questions. Improved visual answers and connected-app follow-ups.\\n- **Captions:** Added offline transcription settings and top/bottom positioning on supported displays.\\n- **Translation:** Restored all 60 languages.\\n- **Mentra Maps:** Clearer directions on G1/G2, less display flickering, and improved Android offline routing.\\n- **Livestreamer:** More video-quality controls and custom streaming options, plus improved startup and sharing.\\n- **Merge:** Tap to expand an insight; swipe down or back to dismiss it.\\n- **Mentra Notes:** Smoother back navigation.\\n- **Recorder:** Fixed audio sharing.\"\n }\n] as const,\n)\n"]}
@@ -1,10 +1,10 @@
1
1
  export const BLUETOOTH_SDK_RELEASE_METADATA = Object.freeze({
2
2
  "schemaVersion": 1,
3
3
  "familyBaseVersion": "3.2.1",
4
- "releaseIdentity": "3.2.1-beta.315",
5
- "releaseSetId": "mentra-3.2.1-beta.315",
6
- "sourceCommit": "fdbe3c85943e23f410cde4e794e1cfcc8affa6a6",
7
- "otaManifestUrl": "https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.2.1/mentra-live-ota-3.2.1-beta.315.json",
8
- "otaManifestSha256": "e4402248a33933105ef96f40913be7ab0708d60927ca4add07495d922b707cd7"
4
+ "releaseIdentity": "3.2.1-beta.354",
5
+ "releaseSetId": "mentra-3.2.1-beta.354",
6
+ "sourceCommit": "b8fb9cd0d58df574fdf1eeb5580ce0b5144f788e",
7
+ "otaManifestUrl": "https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.2.1/mentra-live-ota-3.2.1-beta.354.json",
8
+ "otaManifestSha256": "58b07e4b77901b404a59b44f7fb45218e9be3312983659bfa07b579a437b1034"
9
9
  });
10
10
  //# sourceMappingURL=releaseMetadata.js.map
@@ -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,gBAAgB;IACnC,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,kIAAkI;IACpJ,mBAAmB,EAAE,kEAAkE;CACxF,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\": \"3.2.1\",\n \"releaseIdentity\": \"3.2.1-beta.315\",\n \"releaseSetId\": \"mentra-3.2.1-beta.315\",\n \"sourceCommit\": \"fdbe3c85943e23f410cde4e794e1cfcc8affa6a6\",\n \"otaManifestUrl\": \"https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.2.1/mentra-live-ota-3.2.1-beta.315.json\",\n \"otaManifestSha256\": \"e4402248a33933105ef96f40913be7ab0708d60927ca4add07495d922b707cd7\"\n})\n"]}
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,gBAAgB;IACnC,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,kIAAkI;IACpJ,mBAAmB,EAAE,kEAAkE;CACxF,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\": \"3.2.1\",\n \"releaseIdentity\": \"3.2.1-beta.354\",\n \"releaseSetId\": \"mentra-3.2.1-beta.354\",\n \"sourceCommit\": \"b8fb9cd0d58df574fdf1eeb5580ce0b5144f788e\",\n \"otaManifestUrl\": \"https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.2.1/mentra-live-ota-3.2.1-beta.354.json\",\n \"otaManifestSha256\": \"58b07e4b77901b404a59b44f7fb45218e9be3312983659bfa07b579a437b1034\"\n})\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,wBAAwB,EAKzB,MAAM,sBAAsB,CAAA;AAkF7B,eAAO,MAAM,YAAY,EAAE,wBAuGzB,CAAA;AAEF,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,IAAI,kBAAkB,EAC9C,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EACd,gCAAgC,EAChC,mBAAmB,EACnB,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,OAAO,EACP,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,iCAAiC,EACjC,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,gCAAgC,EAChC,yBAAyB,EACzB,yBAAyB,EACzB,gCAAgC,EAChC,gCAAgC,EAChC,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,iCAAiC,EACjC,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EAAC,wBAAwB,EAAE,wBAAwB,EAAE,0BAA0B,EAAC,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,wBAAwB,EAKzB,MAAM,sBAAsB,CAAA;AAkF7B,eAAO,MAAM,YAAY,EAAE,wBAwGzB,CAAA;AAEF,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,IAAI,kBAAkB,EAC9C,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EACd,gCAAgC,EAChC,mBAAmB,EACnB,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,0BAA0B,EAC1B,iBAAiB,EACjB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,OAAO,EACP,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,iCAAiC,EACjC,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,2BAA2B,EAC3B,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,gCAAgC,EAChC,yBAAyB,EACzB,yBAAyB,EACzB,gCAAgC,EAChC,gCAAgC,EAChC,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,iCAAiC,EACjC,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EAAC,wBAAwB,EAAE,wBAAwB,EAAE,0BAA0B,EAAC,MAAM,sBAAsB,CAAA"}
package/build/index.js CHANGED
@@ -113,6 +113,7 @@ export const BluetoothSdk = Object.freeze({
113
113
  setGalleryModeEnabled: bindPublicMethod("setGalleryModeEnabled"),
114
114
  setVoiceActivityDetectionEnabled: bindPublicMethod("setVoiceActivityDetectionEnabled"),
115
115
  setLoudnessGateEnabled: bindPublicMethod("setLoudnessGateEnabled"),
116
+ setAutoPowerOffEnabled: bindPublicMethod("setAutoPowerOffEnabled"),
116
117
  /**
117
118
  * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request
118
119
  * `requestPhoto(...)` options (e.g. `mode: "text"` for text sensor size/crop, or explicit per-shot
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {parsePhotoCompression} from \"@mentra/cloud-protocol/photo-compression\"\nimport PrivateBluetoothSdkModule from \"./_private/BluetoothSdkModule\"\nimport type {\n BluetoothSdkEventListener,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule,\n PhotoCaptureDefaults,\n PublicBluetoothStatus,\n PublicGlassesStatus,\n VideoRecordingDefaults,\n} from \"./BluetoothSdk.types\"\nimport {getReleaseChangelogs} from \"./changelogs\"\n\nconst PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([\n \"native_notification_status\",\n \"native_notification_delivery\",\n \"log\",\n \"device_discovered\",\n \"default_device_changed\",\n \"glasses_not_ready\",\n \"button_press\",\n \"touch_event\",\n \"accel_event\",\n \"head_up\",\n \"voice_activity_detection_status\",\n \"speaking_status\",\n \"battery_status\",\n \"local_transcription\",\n \"wifi_status_change\",\n \"wifi_scan_result\",\n \"wifi_forget_result\",\n \"saved_wifi_networks\",\n \"hotspot_status_change\",\n \"hotspot_error\",\n \"photo_response\",\n \"photo_status\",\n \"camera_status\",\n \"video_recording_status\",\n \"media_success\",\n \"media_error\",\n \"gallery_status\",\n \"compatible_glasses_search_stop\",\n \"swipe_volume_status\",\n \"switch_status\",\n \"rgb_led_control_response\",\n \"settings_ack\",\n \"pair_failure\",\n \"pairing_info\",\n \"entering_pairing_mode\",\n \"owner_replaced\",\n \"audio_pairing_needed\",\n \"audio_connected\",\n \"audio_disconnected\",\n \"mic_pcm\",\n \"mic_lc3\",\n \"mic_health\",\n \"stream_status\",\n \"mtk_update_complete\",\n \"glasses_session_changed\",\n \"ota_start_ack\",\n \"ota_status\",\n \"ar99_ota_status\",\n \"version_info\",\n \"extraction_progress\",\n])\n\nconst addListener: BluetoothSdkPublicModule[\"addListener\"] = (eventName, listener) => {\n if (!PUBLIC_EVENT_NAMES.has(eventName)) {\n throw new Error(`Unsupported BluetoothSdk event \"${eventName}\". Use @mentra/bluetooth-sdk/react for status state.`)\n }\n return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)\n}\n\nconst startOtaUpdate: BluetoothSdkPublicModule[\"startOtaUpdate\"] = (otaVersionUrl) => {\n return PrivateBluetoothSdkModule.startOtaUpdate(otaVersionUrl)\n}\n\nconst queryOtaStatus: BluetoothSdkPublicModule[\"queryOtaStatus\"] = () => {\n return PrivateBluetoothSdkModule.sendOtaQueryStatus()\n}\n\nconst bindPublicMethod = <K extends keyof BluetoothSdkPublicModule>(name: K): BluetoothSdkPublicModule[K] => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>)[name]\n if (typeof method === \"function\") {\n return method.bind(PrivateBluetoothSdkModule) as BluetoothSdkPublicModule[K]\n }\n\n return (async () => {\n throw new Error(`BluetoothSdk.${String(name)} is not available in this native build. Rebuild the app.`)\n }) as unknown as BluetoothSdkPublicModule[K]\n}\n\nexport const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({\n configureNativeNotifications: bindPublicMethod(\"configureNativeNotifications\"),\n getNativeNotificationStatus: bindPublicMethod(\"getNativeNotificationStatus\"),\n addListener,\n getGlassesStatus: bindPublicMethod(\"getGlassesStatus\"),\n getBluetoothStatus: bindPublicMethod(\"getBluetoothStatus\"),\n subscribeGlassesStatus: (listener: (changed: Partial<PublicGlassesStatus>) => void) =>\n PrivateBluetoothSdkModule.onGlassesStatus(listener),\n subscribeBluetoothStatus: (listener: (changed: Partial<PublicBluetoothStatus>) => void) =>\n PrivateBluetoothSdkModule.onBluetoothStatus(listener),\n getDefaultDevice: bindPublicMethod(\"getDefaultDevice\"),\n setDefaultDevice: bindPublicMethod(\"setDefaultDevice\"),\n clearDefaultDevice: bindPublicMethod(\"clearDefaultDevice\"),\n startScan: bindPublicMethod(\"startScan\"),\n stopScan: bindPublicMethod(\"stopScan\"),\n scan: bindPublicMethod(\"scan\") as BluetoothSdkPublicModule[\"scan\"],\n connect: bindPublicMethod(\"connect\"),\n connectDefault: bindPublicMethod(\"connectDefault\"),\n cancelConnectionAttempt: bindPublicMethod(\"cancelConnectionAttempt\"),\n disconnect: bindPublicMethod(\"disconnect\"),\n forget: bindPublicMethod(\"forget\"),\n displayText: bindPublicMethod(\"displayText\"),\n clearDisplay: bindPublicMethod(\"clearDisplay\"),\n setDashboardContent: bindPublicMethod(\"setDashboardContent\"),\n showDashboard: bindPublicMethod(\"showDashboard\"),\n setDashboardPosition: bindPublicMethod(\"setDashboardPosition\"),\n setHeadUpAngle: bindPublicMethod(\"setHeadUpAngle\"),\n setImuEnabled: bindPublicMethod(\"setImuEnabled\"),\n setScreenDisabled: bindPublicMethod(\"setScreenDisabled\"),\n ping: bindPublicMethod(\"ping\"),\n requestWifiScan: bindPublicMethod(\"requestWifiScan\"),\n getSavedWifiNetworks: bindPublicMethod(\"getSavedWifiNetworks\"),\n sendWifiCredentials: bindPublicMethod(\"sendWifiCredentials\"),\n forgetWifiNetwork: bindPublicMethod(\"forgetWifiNetwork\"),\n setHotspotState: bindPublicMethod(\"setHotspotState\"),\n setSystemTime: bindPublicMethod(\"setSystemTime\"),\n setWifiAdbState: bindPublicMethod(\"setWifiAdbState\"),\n setGalleryServerEnabled: bindPublicMethod(\"setGalleryServerEnabled\"),\n setGalleryModeEnabled: bindPublicMethod(\"setGalleryModeEnabled\"),\n setVoiceActivityDetectionEnabled: bindPublicMethod(\"setVoiceActivityDetectionEnabled\"),\n setLoudnessGateEnabled: bindPublicMethod(\"setLoudnessGateEnabled\"),\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for text sensor size/crop, or explicit per-shot\n * fields). Still functional until removed in a future release.\n */\n setPhotoCaptureDefaults: (settings: PhotoCaptureDefaults) => {\n if (settings.compress !== undefined) parsePhotoCompression(settings.compress)\n return bindPublicMethod(\"setPhotoCaptureDefaults\")(settings)\n },\n setVideoRecordingDefaults: ({width, height, fps}: VideoRecordingDefaults) => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>).setVideoRecordingDefaults\n if (typeof method !== \"function\") {\n return Promise.reject(\n new Error(\"BluetoothSdk.setVideoRecordingDefaults is not available in this native build. Rebuild the app.\"),\n )\n }\n return PrivateBluetoothSdkModule.setVideoRecordingDefaults(width, height, fps)\n },\n setMaxVideoRecordingDuration: bindPublicMethod(\"setMaxVideoRecordingDuration\"),\n setCameraFov: bindPublicMethod(\"setCameraFov\"),\n setLegacyCameraFov: bindPublicMethod(\"setLegacyCameraFov\"),\n setCameraFovOverride: bindPublicMethod(\"setCameraFovOverride\"),\n releaseCameraFovOverride: bindPublicMethod(\"releaseCameraFovOverride\"),\n setCameraTuningConfig: bindPublicMethod(\"setCameraTuningConfig\"),\n queryGalleryStatus: bindPublicMethod(\"queryGalleryStatus\"),\n requestPhoto: bindPublicMethod(\"requestPhoto\"),\n warmUpCamera: bindPublicMethod(\"warmUpCamera\"),\n stopCameraWarmUp: bindPublicMethod(\"stopCameraWarmUp\"),\n startVideoRecording: bindPublicMethod(\"startVideoRecording\"),\n stopVideoRecording: bindPublicMethod(\"stopVideoRecording\"),\n queryVideoRecordingStatus: bindPublicMethod(\"queryVideoRecordingStatus\"),\n startStream: bindPublicMethod(\"startStream\"),\n stopStream: bindPublicMethod(\"stopStream\"),\n setMicState: bindPublicMethod(\"setMicState\"),\n setPreferredMic: bindPublicMethod(\"setPreferredMic\"),\n setOwnAppAudioPlaying: bindPublicMethod(\"setOwnAppAudioPlaying\"),\n getGlassesMediaVolume: bindPublicMethod(\"getGlassesMediaVolume\"),\n setGlassesMediaVolume: bindPublicMethod(\"setGlassesMediaVolume\"),\n rgbLedControl: bindPublicMethod(\"rgbLedControl\"),\n requestVersionInfo: bindPublicMethod(\"requestVersionInfo\"),\n setOtaVersionUrl: bindPublicMethod(\"setOtaVersionUrl\"),\n getOtaVersionUrl: bindPublicMethod(\"getOtaVersionUrl\"),\n checkForOtaUpdate: bindPublicMethod(\"checkForOtaUpdate\"),\n getReleaseChangelogs,\n startOtaUpdate,\n queryOtaStatus,\n startAr99OtaFromFile: bindPublicMethod(\"startAr99OtaFromFile\"),\n cancelAr99Ota: bindPublicMethod(\"cancelAr99Ota\"),\n sendAr99FactoryReset: bindPublicMethod(\"sendAr99FactoryReset\"),\n buildAr99OtaSignature: bindPublicMethod(\"buildAr99OtaSignature\"),\n setSttModelDetails: bindPublicMethod(\"setSttModelDetails\"),\n getSttModelPath: bindPublicMethod(\"getSttModelPath\"),\n checkSttModelAvailable: bindPublicMethod(\"checkSttModelAvailable\"),\n validateSttModel: bindPublicMethod(\"validateSttModel\"),\n extractTarBz2: bindPublicMethod(\"extractTarBz2\"),\n restartTranscriber: bindPublicMethod(\"restartTranscriber\"),\n setTtsModelDetails: bindPublicMethod(\"setTtsModelDetails\"),\n getTtsModelPath: bindPublicMethod(\"getTtsModelPath\"),\n getTtsModelLanguage: bindPublicMethod(\"getTtsModelLanguage\"),\n checkTtsModelAvailable: bindPublicMethod(\"checkTtsModelAvailable\"),\n validateTtsModel: bindPublicMethod(\"validateTtsModel\"),\n generateTtsAudio: bindPublicMethod(\"generateTtsAudio\"),\n})\n\nexport default BluetoothSdk\n\nexport {\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n DeviceModels,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\n AccelEvent,\n Ar99OtaStatusEvent,\n AudioConnectedEvent,\n AudioDisconnectedEvent,\n AudioPairingNeededEvent,\n BatteryStatusEvent,\n BluetoothSdkEvent,\n BluetoothSdkEventListener,\n BluetoothSdkEventMap,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule as BluetoothSdkModule,\n BluetoothSdkSubscription,\n ButtonPhotoSize,\n PhotoCaptureDefaults,\n ButtonPressEvent,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovResult,\n CameraRoiPosition,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n GlassesSessionChangedEvent,\n KeepAliveAckEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicHealthEvent,\n MicMode,\n MicPcmEvent,\n MicPreference,\n OtaStartAckEvent,\n OtaProgress,\n OtaProgressStatus,\n OtaStage,\n OtaStatus,\n OtaStatusEvent,\n OtaQueryResult,\n OtaUpdateInfo,\n ReleaseChangelog,\n MtkUpdateCompleteEvent,\n PairFailureEvent,\n PairingInfoEvent,\n EnteringPairingModeEvent,\n OwnerReplacedEvent,\n PhotoCaptureMetadata,\n PhotoResolvedConfig,\n PhotoCompression,\n PhotoFpsRange,\n PhotoMeteredPreview,\n PhotoMode,\n PublicBluetoothStatus,\n PublicGlassesStatus,\n PhotoTransferMethod,\n PhotoResponseEvent,\n PhotoRequestedCaptureConfig,\n PhotoRequestParams,\n PhotoSize,\n PhotoStatusEvent,\n PhotoStatusState,\n PhotoSuccessResponseEvent,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n RgbLedControlSuccessResponseEvent,\n ScanModelOptions,\n ScanDiagnostic,\n ScanOptions,\n ScanResultsCallback,\n SpeakingStatusEvent,\n SettingsAckEvent,\n SettingsAckSetting,\n SettingsAckSuccessEvent,\n SettingsAckSuccessStatus,\n SettingsAckStatus,\n StreamAudioConfig,\n StreamDegradationPreference,\n StreamResolvedConfig,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VideoRecordingDefaults,\n VideoRecordingStartedStatusEvent,\n VideoRecordingStatusEvent,\n VideoRecordingStatusState,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingSuccessStatusEvent,\n VersionInfoEvent,\n VersionInfoResult,\n SavedWifiNetworksEvent,\n SavedWifiNetworksOutcome,\n SavedWifiNetworksResult,\n WifiForgetOutcome,\n WifiForgetResult,\n WifiForgetResultEvent,\n LegacyWifiForgetResultEvent,\n ModernWifiForgetResultEvent,\n WifiScanResultEvent,\n VoiceActivityDetectionStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n\nexport type {NativeNotificationConfig, NativeNotificationStatus, NativeNotificationDelivery} from \"./BluetoothSdk.types\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {parsePhotoCompression} from \"@mentra/cloud-protocol/photo-compression\"\nimport PrivateBluetoothSdkModule from \"./_private/BluetoothSdkModule\"\nimport type {\n BluetoothSdkEventListener,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule,\n PhotoCaptureDefaults,\n PublicBluetoothStatus,\n PublicGlassesStatus,\n VideoRecordingDefaults,\n} from \"./BluetoothSdk.types\"\nimport {getReleaseChangelogs} from \"./changelogs\"\n\nconst PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([\n \"native_notification_status\",\n \"native_notification_delivery\",\n \"log\",\n \"device_discovered\",\n \"default_device_changed\",\n \"glasses_not_ready\",\n \"button_press\",\n \"touch_event\",\n \"accel_event\",\n \"head_up\",\n \"voice_activity_detection_status\",\n \"speaking_status\",\n \"battery_status\",\n \"local_transcription\",\n \"wifi_status_change\",\n \"wifi_scan_result\",\n \"wifi_forget_result\",\n \"saved_wifi_networks\",\n \"hotspot_status_change\",\n \"hotspot_error\",\n \"photo_response\",\n \"photo_status\",\n \"camera_status\",\n \"video_recording_status\",\n \"media_success\",\n \"media_error\",\n \"gallery_status\",\n \"compatible_glasses_search_stop\",\n \"swipe_volume_status\",\n \"switch_status\",\n \"rgb_led_control_response\",\n \"settings_ack\",\n \"pair_failure\",\n \"pairing_info\",\n \"entering_pairing_mode\",\n \"owner_replaced\",\n \"audio_pairing_needed\",\n \"audio_connected\",\n \"audio_disconnected\",\n \"mic_pcm\",\n \"mic_lc3\",\n \"mic_health\",\n \"stream_status\",\n \"mtk_update_complete\",\n \"glasses_session_changed\",\n \"ota_start_ack\",\n \"ota_status\",\n \"ar99_ota_status\",\n \"version_info\",\n \"extraction_progress\",\n])\n\nconst addListener: BluetoothSdkPublicModule[\"addListener\"] = (eventName, listener) => {\n if (!PUBLIC_EVENT_NAMES.has(eventName)) {\n throw new Error(`Unsupported BluetoothSdk event \"${eventName}\". Use @mentra/bluetooth-sdk/react for status state.`)\n }\n return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)\n}\n\nconst startOtaUpdate: BluetoothSdkPublicModule[\"startOtaUpdate\"] = (otaVersionUrl) => {\n return PrivateBluetoothSdkModule.startOtaUpdate(otaVersionUrl)\n}\n\nconst queryOtaStatus: BluetoothSdkPublicModule[\"queryOtaStatus\"] = () => {\n return PrivateBluetoothSdkModule.sendOtaQueryStatus()\n}\n\nconst bindPublicMethod = <K extends keyof BluetoothSdkPublicModule>(name: K): BluetoothSdkPublicModule[K] => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>)[name]\n if (typeof method === \"function\") {\n return method.bind(PrivateBluetoothSdkModule) as BluetoothSdkPublicModule[K]\n }\n\n return (async () => {\n throw new Error(`BluetoothSdk.${String(name)} is not available in this native build. Rebuild the app.`)\n }) as unknown as BluetoothSdkPublicModule[K]\n}\n\nexport const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({\n configureNativeNotifications: bindPublicMethod(\"configureNativeNotifications\"),\n getNativeNotificationStatus: bindPublicMethod(\"getNativeNotificationStatus\"),\n addListener,\n getGlassesStatus: bindPublicMethod(\"getGlassesStatus\"),\n getBluetoothStatus: bindPublicMethod(\"getBluetoothStatus\"),\n subscribeGlassesStatus: (listener: (changed: Partial<PublicGlassesStatus>) => void) =>\n PrivateBluetoothSdkModule.onGlassesStatus(listener),\n subscribeBluetoothStatus: (listener: (changed: Partial<PublicBluetoothStatus>) => void) =>\n PrivateBluetoothSdkModule.onBluetoothStatus(listener),\n getDefaultDevice: bindPublicMethod(\"getDefaultDevice\"),\n setDefaultDevice: bindPublicMethod(\"setDefaultDevice\"),\n clearDefaultDevice: bindPublicMethod(\"clearDefaultDevice\"),\n startScan: bindPublicMethod(\"startScan\"),\n stopScan: bindPublicMethod(\"stopScan\"),\n scan: bindPublicMethod(\"scan\") as BluetoothSdkPublicModule[\"scan\"],\n connect: bindPublicMethod(\"connect\"),\n connectDefault: bindPublicMethod(\"connectDefault\"),\n cancelConnectionAttempt: bindPublicMethod(\"cancelConnectionAttempt\"),\n disconnect: bindPublicMethod(\"disconnect\"),\n forget: bindPublicMethod(\"forget\"),\n displayText: bindPublicMethod(\"displayText\"),\n clearDisplay: bindPublicMethod(\"clearDisplay\"),\n setDashboardContent: bindPublicMethod(\"setDashboardContent\"),\n showDashboard: bindPublicMethod(\"showDashboard\"),\n setDashboardPosition: bindPublicMethod(\"setDashboardPosition\"),\n setHeadUpAngle: bindPublicMethod(\"setHeadUpAngle\"),\n setImuEnabled: bindPublicMethod(\"setImuEnabled\"),\n setScreenDisabled: bindPublicMethod(\"setScreenDisabled\"),\n ping: bindPublicMethod(\"ping\"),\n requestWifiScan: bindPublicMethod(\"requestWifiScan\"),\n getSavedWifiNetworks: bindPublicMethod(\"getSavedWifiNetworks\"),\n sendWifiCredentials: bindPublicMethod(\"sendWifiCredentials\"),\n forgetWifiNetwork: bindPublicMethod(\"forgetWifiNetwork\"),\n setHotspotState: bindPublicMethod(\"setHotspotState\"),\n setSystemTime: bindPublicMethod(\"setSystemTime\"),\n setWifiAdbState: bindPublicMethod(\"setWifiAdbState\"),\n setGalleryServerEnabled: bindPublicMethod(\"setGalleryServerEnabled\"),\n setGalleryModeEnabled: bindPublicMethod(\"setGalleryModeEnabled\"),\n setVoiceActivityDetectionEnabled: bindPublicMethod(\"setVoiceActivityDetectionEnabled\"),\n setLoudnessGateEnabled: bindPublicMethod(\"setLoudnessGateEnabled\"),\n setAutoPowerOffEnabled: bindPublicMethod(\"setAutoPowerOffEnabled\"),\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for text sensor size/crop, or explicit per-shot\n * fields). Still functional until removed in a future release.\n */\n setPhotoCaptureDefaults: (settings: PhotoCaptureDefaults) => {\n if (settings.compress !== undefined) parsePhotoCompression(settings.compress)\n return bindPublicMethod(\"setPhotoCaptureDefaults\")(settings)\n },\n setVideoRecordingDefaults: ({width, height, fps}: VideoRecordingDefaults) => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>).setVideoRecordingDefaults\n if (typeof method !== \"function\") {\n return Promise.reject(\n new Error(\"BluetoothSdk.setVideoRecordingDefaults is not available in this native build. Rebuild the app.\"),\n )\n }\n return PrivateBluetoothSdkModule.setVideoRecordingDefaults(width, height, fps)\n },\n setMaxVideoRecordingDuration: bindPublicMethod(\"setMaxVideoRecordingDuration\"),\n setCameraFov: bindPublicMethod(\"setCameraFov\"),\n setLegacyCameraFov: bindPublicMethod(\"setLegacyCameraFov\"),\n setCameraFovOverride: bindPublicMethod(\"setCameraFovOverride\"),\n releaseCameraFovOverride: bindPublicMethod(\"releaseCameraFovOverride\"),\n setCameraTuningConfig: bindPublicMethod(\"setCameraTuningConfig\"),\n queryGalleryStatus: bindPublicMethod(\"queryGalleryStatus\"),\n requestPhoto: bindPublicMethod(\"requestPhoto\"),\n warmUpCamera: bindPublicMethod(\"warmUpCamera\"),\n stopCameraWarmUp: bindPublicMethod(\"stopCameraWarmUp\"),\n startVideoRecording: bindPublicMethod(\"startVideoRecording\"),\n stopVideoRecording: bindPublicMethod(\"stopVideoRecording\"),\n queryVideoRecordingStatus: bindPublicMethod(\"queryVideoRecordingStatus\"),\n startStream: bindPublicMethod(\"startStream\"),\n stopStream: bindPublicMethod(\"stopStream\"),\n setMicState: bindPublicMethod(\"setMicState\"),\n setPreferredMic: bindPublicMethod(\"setPreferredMic\"),\n setOwnAppAudioPlaying: bindPublicMethod(\"setOwnAppAudioPlaying\"),\n getGlassesMediaVolume: bindPublicMethod(\"getGlassesMediaVolume\"),\n setGlassesMediaVolume: bindPublicMethod(\"setGlassesMediaVolume\"),\n rgbLedControl: bindPublicMethod(\"rgbLedControl\"),\n requestVersionInfo: bindPublicMethod(\"requestVersionInfo\"),\n setOtaVersionUrl: bindPublicMethod(\"setOtaVersionUrl\"),\n getOtaVersionUrl: bindPublicMethod(\"getOtaVersionUrl\"),\n checkForOtaUpdate: bindPublicMethod(\"checkForOtaUpdate\"),\n getReleaseChangelogs,\n startOtaUpdate,\n queryOtaStatus,\n startAr99OtaFromFile: bindPublicMethod(\"startAr99OtaFromFile\"),\n cancelAr99Ota: bindPublicMethod(\"cancelAr99Ota\"),\n sendAr99FactoryReset: bindPublicMethod(\"sendAr99FactoryReset\"),\n buildAr99OtaSignature: bindPublicMethod(\"buildAr99OtaSignature\"),\n setSttModelDetails: bindPublicMethod(\"setSttModelDetails\"),\n getSttModelPath: bindPublicMethod(\"getSttModelPath\"),\n checkSttModelAvailable: bindPublicMethod(\"checkSttModelAvailable\"),\n validateSttModel: bindPublicMethod(\"validateSttModel\"),\n extractTarBz2: bindPublicMethod(\"extractTarBz2\"),\n restartTranscriber: bindPublicMethod(\"restartTranscriber\"),\n setTtsModelDetails: bindPublicMethod(\"setTtsModelDetails\"),\n getTtsModelPath: bindPublicMethod(\"getTtsModelPath\"),\n getTtsModelLanguage: bindPublicMethod(\"getTtsModelLanguage\"),\n checkTtsModelAvailable: bindPublicMethod(\"checkTtsModelAvailable\"),\n validateTtsModel: bindPublicMethod(\"validateTtsModel\"),\n generateTtsAudio: bindPublicMethod(\"generateTtsAudio\"),\n})\n\nexport default BluetoothSdk\n\nexport {\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n DeviceModels,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\n AccelEvent,\n Ar99OtaStatusEvent,\n AudioConnectedEvent,\n AudioDisconnectedEvent,\n AudioPairingNeededEvent,\n BatteryStatusEvent,\n BluetoothSdkEvent,\n BluetoothSdkEventListener,\n BluetoothSdkEventMap,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule as BluetoothSdkModule,\n BluetoothSdkSubscription,\n ButtonPhotoSize,\n PhotoCaptureDefaults,\n ButtonPressEvent,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovResult,\n CameraRoiPosition,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n GlassesSessionChangedEvent,\n KeepAliveAckEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicHealthEvent,\n MicMode,\n MicPcmEvent,\n MicPreference,\n OtaStartAckEvent,\n OtaProgress,\n OtaProgressStatus,\n OtaStage,\n OtaStatus,\n OtaStatusEvent,\n OtaQueryResult,\n OtaUpdateInfo,\n ReleaseChangelog,\n MtkUpdateCompleteEvent,\n PairFailureEvent,\n PairingInfoEvent,\n EnteringPairingModeEvent,\n OwnerReplacedEvent,\n PhotoCaptureMetadata,\n PhotoResolvedConfig,\n PhotoCompression,\n PhotoFpsRange,\n PhotoMeteredPreview,\n PhotoMode,\n PublicBluetoothStatus,\n PublicGlassesStatus,\n PhotoTransferMethod,\n PhotoResponseEvent,\n PhotoRequestedCaptureConfig,\n PhotoRequestParams,\n PhotoSize,\n PhotoStatusEvent,\n PhotoStatusState,\n PhotoSuccessResponseEvent,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n RgbLedControlSuccessResponseEvent,\n ScanModelOptions,\n ScanDiagnostic,\n ScanOptions,\n ScanResultsCallback,\n SpeakingStatusEvent,\n SettingsAckEvent,\n SettingsAckSetting,\n SettingsAckSuccessEvent,\n SettingsAckSuccessStatus,\n SettingsAckStatus,\n StreamAudioConfig,\n StreamDegradationPreference,\n StreamResolvedConfig,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VideoRecordingDefaults,\n VideoRecordingStartedStatusEvent,\n VideoRecordingStatusEvent,\n VideoRecordingStatusState,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingSuccessStatusEvent,\n VersionInfoEvent,\n VersionInfoResult,\n SavedWifiNetworksEvent,\n SavedWifiNetworksOutcome,\n SavedWifiNetworksResult,\n WifiForgetOutcome,\n WifiForgetResult,\n WifiForgetResultEvent,\n LegacyWifiForgetResultEvent,\n ModernWifiForgetResultEvent,\n WifiScanResultEvent,\n VoiceActivityDetectionStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n\nexport type {NativeNotificationConfig, NativeNotificationStatus, NativeNotificationDelivery} from \"./BluetoothSdk.types\"\n"]}
@@ -465,6 +465,11 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
465
465
  try await sdk.setLoudnessGateEnabled(enabled)
466
466
  }
467
467
 
468
+ AsyncFunction("setAutoPowerOffEnabled") { (enabled: Bool) in
469
+ let sdk = await MainActor.run { self.bluetoothSdk() }
470
+ try await sdk.setAutoPowerOffEnabled(enabled)
471
+ }
472
+
468
473
  AsyncFunction("setPhotoCaptureDefaults") { (params: [String: Any]) in
469
474
  let sdk = await MainActor.run { self.bluetoothSdk() }
470
475
  return try await sdk.setPhotoCaptureDefaults(PhotoCaptureDefaults.from(params: params)).values
@@ -38,13 +38,14 @@ Pod::Spec.new do |s|
38
38
  }
39
39
 
40
40
  # iOS frameworks required by Bluetooth SDK
41
- ios_frameworks = ['AVFoundation', 'CoreBluetooth', 'UIKit', 'CoreGraphics']
41
+ ios_frameworks = ['AVFoundation', 'CoreBluetooth', 'UIKit', 'CoreGraphics', 'ImageIO']
42
42
  ios_frameworks << 'Network' if include_expo_adapter
43
43
  s.ios.frameworks = ios_frameworks
44
44
  s.osx.frameworks = ['AVFoundation', 'CoreBluetooth', 'CoreAudio', 'AudioToolbox', 'ImageIO', 'JavaScriptCore', 'Network']
45
45
 
46
46
  # System libraries required by MentraOS
47
- s.ios.library = 'bz2'
47
+ s.ios.libraries = 'bz2', 'z'
48
+ s.osx.library = 'z'
48
49
 
49
50
  # Vendored frameworks
50
51
  s.ios.vendored_frameworks = 'Packages/SherpaOnnx/sherpa-onnx.xcframework'
@@ -10,8 +10,13 @@ enum BluetoothSdkDefaults {
10
10
 
11
11
  static let voiceActivityDetectionEnabled = false
12
12
  static let loudnessGateEnabled = false
13
+
14
+ /// Must stay true. The firmware defaults auto power-off on, and we re-push
15
+ /// every Bluetooth setting on connect, so a false default here would
16
+ /// silently disable it on every pair the app touches.
17
+ static let autoPowerOffEnabled = false
13
18
  private static let infoSdkVersionKey = "MentraBluetoothSdkVersion"
14
- private static let swiftPackageSdkVersion = "3.2.1-beta.315"
19
+ private static let swiftPackageSdkVersion = "3.2.1-beta.354"
15
20
  private static let swiftPackageSdkVersionPlaceholder = "__MENTRA" + "_BLUETOOTH_SDK_VERSION__"
16
21
 
17
22
  private static func normalizedSdkVersion(_ value: String?) -> String? {
@@ -335,8 +335,21 @@ class Bridge {
335
335
  }
336
336
 
337
337
  /// Wear state from sr_wrst, or from a wear transition on the glasses.
338
- static func sendWearState(worn: Bool) {
339
- Bridge.sendTypedMessage("wear_state", body: ["worn": worn])
338
+ static func sendWearState(
339
+ worn: Bool,
340
+ elapsedMs: Int? = nil,
341
+ timeoutMs: Int? = nil,
342
+ enabled: Bool? = nil,
343
+ armed: Bool? = nil,
344
+ inhibited: Bool? = nil
345
+ ) {
346
+ var body: [String: Any] = ["worn": worn]
347
+ if let elapsedMs { body["elapsedMs"] = elapsedMs }
348
+ if let timeoutMs { body["timeoutMs"] = timeoutMs }
349
+ if let enabled { body["enabled"] = enabled }
350
+ if let armed { body["armed"] = armed }
351
+ if let inhibited { body["inhibited"] = inhibited }
352
+ Bridge.sendTypedMessage("wear_state", body: body)
340
353
  }
341
354
 
342
355
  /// Wear vote config the glasses report as in force, from sr_weartun.
@@ -1024,14 +1024,18 @@ struct ViewState {
1024
1024
  sgc.setDashboardPosition(h, d)
1025
1025
  }
1026
1026
 
1027
- // Show welcome message on first connect for all display glasses
1027
+ // Preserve the connected-edge scene replay on full-frame adapters.
1028
1028
  if shouldSendBootingMessage {
1029
- Task {
1030
- await sgc.sendTextWall("// MentraOS Connected")
1031
- try? await Task.sleep(nanoseconds: 3_000_000_000) // 1 second
1032
- sgc.clearDisplay()
1033
- }
1034
1029
  shouldSendBootingMessage = false
1030
+ if sgc.showConnectionConfirmation {
1031
+ Task {
1032
+ guard (self.sgc as AnyObject?) === (sgc as AnyObject) else { return }
1033
+ await sgc.sendTextWall("// MentraOS Connected")
1034
+ try? await Task.sleep(nanoseconds: 3_000_000_000)
1035
+ guard (self.sgc as AnyObject?) === (sgc as AnyObject) else { return }
1036
+ sgc.clearDisplay()
1037
+ }
1038
+ }
1035
1039
  }
1036
1040
 
1037
1041
  // Call device-specific setup handlers
@@ -1214,7 +1218,9 @@ struct ViewState {
1214
1218
  self.dashboardSceneCleanupPending = false
1215
1219
  let elementIds = Array(self.pendingDashboardSceneElementIds)
1216
1220
  self.pendingDashboardSceneElementIds.removeAll()
1217
- await self.sgc?.clearSceneElements(elementIds)
1221
+ if self.sgc?.sceneHandoffRequiresClear == true {
1222
+ await self.sgc?.clearSceneElements(elementIds)
1223
+ }
1218
1224
  }
1219
1225
  self.dashboardSceneCleanupTask = nil
1220
1226
  }
@@ -1261,7 +1267,7 @@ struct ViewState {
1261
1267
  if stateIndex == 1, dashboardSceneCleanupDeferred {
1262
1268
  dashboardSceneCleanupPending = true
1263
1269
  pendingDashboardSceneElementIds.formUnion(prevFrame.elements.map(\.id))
1264
- } else if layoutType != "clear_view" {
1270
+ } else if layoutType != "clear_view", shouldClearSceneHandoff(stateIndex) {
1265
1271
  let ids = prevFrame.elements.map(\.id)
1266
1272
  Task { [weak self] in
1267
1273
  await self?.sgc?.clearSceneElements(ids)
@@ -1355,7 +1361,7 @@ struct ViewState {
1355
1361
  // on G2 - no page rebuild).
1356
1362
  let prevLegacyType = viewStates[stateIndex].layoutType
1357
1363
  let cleanupDeferred = stateIndex == 1 && dashboardSceneCleanupDeferred
1358
- if !cleanupDeferred,
1364
+ if !cleanupDeferred, shouldClearSceneHandoff(stateIndex),
1359
1365
  !prevLegacyType.isEmpty,
1360
1366
  prevLegacyType != "clear_view",
1361
1367
  prevLegacyType != "scene"
@@ -1371,7 +1377,7 @@ struct ViewState {
1371
1377
  if stateIndex == 1, dashboardSceneCleanupDeferred {
1372
1378
  dashboardSceneCleanupPending = true
1373
1379
  pendingDashboardSceneElementIds.formUnion(prevFrame.elements.map(\.id))
1374
- } else {
1380
+ } else if shouldClearSceneHandoff(stateIndex) {
1375
1381
  let ids = prevFrame.elements.map(\.id)
1376
1382
  Task { [weak self] in
1377
1383
  await self?.sgc?.clearSceneElements(ids)
@@ -1395,6 +1401,13 @@ struct ViewState {
1395
1401
  }
1396
1402
  }
1397
1403
 
1404
+ private func shouldClearSceneHandoff(_ stateIndex: Int) -> Bool {
1405
+ let visibleIndex = headUp && contextualDashboard ? 1 : 0
1406
+ guard let sgc else { return false }
1407
+ return stateIndex == visibleIndex && !screenDisabled && sgc.fullyBooted
1408
+ && !sgc.type.contains(DeviceTypes.SIMULATED) && sgc.sceneHandoffRequiresClear
1409
+ }
1410
+
1398
1411
  /// Guarded scene dispatch - mirrors sendCurrentState's send conditions.
1399
1412
  private func dispatchSceneFrame(_ frame: SceneFrame, stateIndex: Int) {
1400
1413
  if screenDisabled { return }
@@ -94,6 +94,7 @@ class DeviceStore {
94
94
  store.set("bluetooth", "gallery_mode", true)
95
95
  store.set("bluetooth", "voice_activity_detection_enabled", BluetoothSdkDefaults.voiceActivityDetectionEnabled)
96
96
  store.set("bluetooth", "loudness_gate_enabled", BluetoothSdkDefaults.loudnessGateEnabled)
97
+ store.set("bluetooth", "auto_power_off_enabled", BluetoothSdkDefaults.autoPowerOffEnabled)
97
98
  // Mentra Nex feature flag (off by default; toggled from Nex Developer Settings):
98
99
  store.set("bluetooth", "nex_chinese_captions", false)
99
100
  store.set("bluetooth", "screen_disabled", false)
@@ -191,14 +192,25 @@ class DeviceStore {
191
192
 
192
193
  // BLUETOOTH:
193
194
 
195
+ case ("bluetooth", "contextual_dashboard"):
196
+ if value is Bool {
197
+ Task { @MainActor in
198
+ if self.store.get("glasses", "headUp") as? Bool == true {
199
+ DeviceManager.shared.sendCurrentState()
200
+ }
201
+ }
202
+ }
203
+
194
204
  case ("bluetooth", "brightness"):
195
205
  let b = value as? Int ?? 50
196
206
  let auto = store.get("bluetooth", "auto_brightness") as? Bool ?? true
197
207
  Task {
198
- DeviceManager.shared.sgc?.setBrightness(b, autoMode: auto)
199
- await DeviceManager.shared.sgc?.sendTextWall("Set brightness to \(b)%")
208
+ guard let device = DeviceManager.shared.sgc else { return }
209
+ device.setBrightness(b, autoMode: auto)
210
+ guard device.showBrightnessConfirmation else { return }
211
+ await device.sendTextWall("Set brightness to \(b)%")
200
212
  try? await Task.sleep(nanoseconds: 800_000_000) // 0.8 seconds
201
- DeviceManager.shared.sgc?.clearDisplay()
213
+ if (DeviceManager.shared.sgc as AnyObject?) === (device as AnyObject) { device.clearDisplay() }
202
214
  }
203
215
 
204
216
  case ("bluetooth", "auto_brightness"):
@@ -206,13 +218,14 @@ class DeviceStore {
206
218
  let auto = value as? Bool ?? true
207
219
  let autoBrightnessChanged = (oldValue as? Bool) != auto
208
220
  Task {
209
- DeviceManager.shared.sgc?.setBrightness(b, autoMode: auto)
210
- if autoBrightnessChanged {
211
- await DeviceManager.shared.sgc?.sendTextWall(
221
+ guard let device = DeviceManager.shared.sgc else { return }
222
+ device.setBrightness(b, autoMode: auto)
223
+ if autoBrightnessChanged, device.showBrightnessConfirmation {
224
+ await device.sendTextWall(
212
225
  auto ? "Enabled auto brightness" : "Disabled auto brightness"
213
226
  )
214
227
  try? await Task.sleep(nanoseconds: 800_000_000) // 0.8 seconds
215
- DeviceManager.shared.sgc?.clearDisplay()
228
+ if (DeviceManager.shared.sgc as AnyObject?) === (device as AnyObject) { device.clearDisplay() }
216
229
  }
217
230
  }
218
231
 
@@ -254,6 +267,12 @@ class DeviceStore {
254
267
  case ("bluetooth", "loudness_gate_enabled"):
255
268
  DeviceManager.shared.sgc?.sendLoudnessGateSetting()
256
269
 
270
+ case ("bluetooth", "auto_power_off_enabled"):
271
+ Bridge.log(
272
+ "DeviceStore: auto_power_off_enabled changed to \(String(describing: value)) — sending cs_swit type 11"
273
+ )
274
+ DeviceManager.shared.sgc?.sendAutoPowerOffSetting()
275
+
257
276
  // Deliberately has no seeded default: the key starts absent so that a
258
277
  // session where the engine has not authorized tuning can only ever
259
278
  // send a reset.
@@ -2,7 +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.1", markdown: "This release is under active development. User-facing changes will be documented as they land."),
5
+ ReleaseChangelog(version: "3.2.1", markdown: "This release is under active development. User-facing changes will be documented as they land.\n\n- Mentra Miniapp SDK: `session.stream.preview({source: \"call\"})` and the `<StreamPreview>` component (from `@mentra/miniapp/react`) show the live video of a call your miniapp owns inside its UI. Requires the `CAMERA` permission; the lease survives the UI closing and ends with `handle.stop()` or the meeting. See [Stream preview](https://docs.mentraglass.com/app-devs/core-concepts/stream-preview)."),
6
6
  ReleaseChangelog(version: "3.2.0", markdown: "This release is under active development. User-facing changes will be documented as they land.\n\n- Breaking Bluetooth SDK change: `forgetWifiNetwork(ssid)` now returns `WifiForgetResult` instead of `WifiStatusChangeEvent`. Migrate status-only consumers to the semantic `outcome`; the requested network remains `ssid`, while optional post-command connectivity is reported by `connected`, `currentSsid`, and `localIp`."),
7
7
  ReleaseChangelog(version: "3.1.1", markdown: "- Improved Google login on iOS.\n- Pairing no longer requires phone microphone access."),
8
8
  ReleaseChangelog(version: "3.1.0", markdown: "**Mentra App and glasses**\n\n- Improved glasses pairing and reconnection, including on iPad.\n- Improved Android background reliability for captions and miniapps.\n- Added Xingyi AR99 support.\n- More reliable photo and video capture, with improved shutter sounds and privacy-light timing. Taking photos no longer interrupts your running miniapp.\n- Added video thumbnails and smoother gallery browsing.\n- Easier Mentra Live updates through your phone, with clearer progress and better recovery from interruptions.\n\n**Miniapp updates**\n\n- **Mentra AI:** Control whether photos are included with questions. Improved visual answers and connected-app follow-ups.\n- **Captions:** Added offline transcription settings and top/bottom positioning on supported displays.\n- **Translation:** Restored all 60 languages.\n- **Mentra Maps:** Clearer directions on G1/G2, less display flickering, and improved Android offline routing.\n- **Livestreamer:** More video-quality controls and custom streaming options, plus improved startup and sharing.\n- **Merge:** Tap to expand an insight; swipe down or back to dismiss it.\n- **Mentra Notes:** Smoother back navigation.\n- **Recorder:** Fixed audio sharing."),
@@ -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 = "3.2.1"
6
- static let releaseIdentity = "3.2.1-beta.315"
7
- static let releaseSetId = "mentra-3.2.1-beta.315"
8
- static let sourceCommit = "fdbe3c85943e23f410cde4e794e1cfcc8affa6a6"
9
- static let otaManifestUrl = "https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.2.1/mentra-live-ota-3.2.1-beta.315.json"
10
- static let otaManifestSha256 = "e4402248a33933105ef96f40913be7ab0708d60927ca4add07495d922b707cd7"
6
+ static let releaseIdentity = "3.2.1-beta.354"
7
+ static let releaseSetId = "mentra-3.2.1-beta.354"
8
+ static let sourceCommit = "b8fb9cd0d58df574fdf1eeb5580ce0b5144f788e"
9
+ static let otaManifestUrl = "https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.2.1/mentra-live-ota-3.2.1-beta.354.json"
10
+ static let otaManifestSha256 = "58b07e4b77901b404a59b44f7fb45218e9be3312983659bfa07b579a437b1034"
11
11
  }
@@ -688,6 +688,10 @@ public final class MentraBluetoothSDK {
688
688
  DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "loudness_gate_enabled", enabled)
689
689
  }
690
690
 
691
+ public func setAutoPowerOffEnabled(_ enabled: Bool) async throws {
692
+ DeviceStore.shared.apply(ObservableStore.bluetoothCategory, "auto_power_off_enabled", enabled)
693
+ }
694
+
691
695
  @available(*, deprecated, message: "Sticky action-button photo presets are deprecated. Prefer per-request requestPhoto(...) options (e.g. mode .text for text sensor size/crop, or explicit per-shot fields). This method still works but will be removed in a future release.")
692
696
  public func setPhotoCaptureDefaults(_ settings: PhotoCaptureDefaults) async throws -> SettingsAckEvent {
693
697
  try await performSettingsCommand(
@@ -7,7 +7,7 @@ enum VersionInfoAccumulatorOutcome {
7
7
  case complete(VersionInfoResult)
8
8
  }
9
9
 
10
- /// One request, explicit modern completion, or the deployed legacy chunk-3 terminal boundary.
10
+ /// One request, explicit modern completion, or the legacy firmware's terminal chunk.
11
11
  final class VersionInfoResponseAccumulator {
12
12
  static let responseChunkKey = "_responseChunk"
13
13
  static let responseRequestIdKey = "_responseRequestId"
@@ -23,6 +23,7 @@ final class VersionInfoResponseAccumulator {
23
23
  private var count: Int?
24
24
  private var sid: String?
25
25
  private var legacyStarted = false
26
+ private var legacyTwoChunkResponse = false
26
27
  private var completed = false
27
28
 
28
29
  init(expectedRequestId: String) {
@@ -63,10 +64,19 @@ final class VersionInfoResponseAccumulator {
63
64
  case "version_info_1":
64
65
  values.removeAll()
65
66
  legacyStarted = true
67
+ legacyTwoChunkResponse = event["buildNumber"] as? String == "27"
66
68
  merge(event)
67
69
  case "version_info_2":
68
70
  guard legacyStarted else { return .ignored }
71
+ // Factory ASG27 sends only chunks 1 and 2. Its second chunk carries the
72
+ // OTA URL and legacy firmware version; ASG31+ moves firmware to chunk 3.
69
73
  merge(event)
74
+ if legacyTwoChunkResponse, values["buildNumber"] as? String == "27",
75
+ let otaUrl = event["otaVersionUrl"] as? String,
76
+ !otaUrl.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
77
+ {
78
+ return finish()
79
+ }
70
80
  case "version_info_3":
71
81
  guard legacyStarted else { return .ignored }
72
82
  merge(event)
@@ -2230,7 +2230,7 @@ class G2: NSObject, SGCManager {
2230
2230
  let borderColor = borderColor ?? G2.defaultTextContainer.borderColor
2231
2231
  let borderRadius = borderRadius ?? G2.defaultTextContainer.borderRadius
2232
2232
  let paddingLength = paddingLength ?? G2.defaultTextContainer.paddingLength
2233
- let content = text.isEmpty ? " " : text
2233
+ let content = G2Text.containerContent(text)
2234
2234
 
2235
2235
  // Pure state mutation: update the container's content and schedule its sends; the reconcile
2236
2236
  // loop (`displayReconcileTask`) does the actual updateText writes. Reuse an existing container
@@ -2391,7 +2391,7 @@ class G2: NSObject, SGCManager {
2391
2391
  // y is clamped first so the height term can't go negative.
2392
2392
  let y = min(max(y, 0), 288 - G2.minTextContainerHeight)
2393
2393
  let height = min(max(height, G2.minTextContainerHeight), 288 - y)
2394
- let content = text.isEmpty ? " " : text
2394
+ let content = G2Text.containerContent(text)
2395
2395
  if let existingId = sceneTextByElement[elementId] {
2396
2396
  if let i = textContainers.firstIndex(where: { $0.id == existingId }) {
2397
2397
  let c = textContainers[i]
@@ -1414,6 +1414,7 @@ class MentraLive: NSObject, SGCManager {
1414
1414
  private let BLOCK_AUDIO_DUPLEX = false
1415
1415
  private static let voiceActivityDetectionSwitchType = 8
1416
1416
  private static let loudnessGateSwitchType = 10
1417
+ private static let autoPowerOffSwitchType = 11
1417
1418
  private func pairingAdvertisement(
1418
1419
  _ advertisementData: [String: Any]
1419
1420
  ) -> MentraLivePairingAdvertisement? {
@@ -3440,10 +3441,13 @@ class MentraLive: NSObject, SGCManager {
3440
3441
  if let body = k900ParseBody(json["B"]) {
3441
3442
  let switchType = k900JsonInt(body, "type") ?? -1
3442
3443
  let switchValue = k900JsonInt(body, "switch") ?? -1
3444
+ // K900 replies carry result in "S"; 0 is RC_SUCCESS.
3445
+ let resultCode = k900JsonInt(json, "S") ?? -1
3443
3446
  handleSwitchStatus(
3444
3447
  switchType: switchType,
3445
3448
  value: switchValue,
3446
- timestamp: Int64(Date().timeIntervalSince1970 * 1000)
3449
+ timestamp: Int64(Date().timeIntervalSince1970 * 1000),
3450
+ resultCode: resultCode
3447
3451
  )
3448
3452
  }
3449
3453
 
@@ -3459,7 +3463,14 @@ class MentraLive: NSObject, SGCManager {
3459
3463
 
3460
3464
  case "sr_wrst":
3461
3465
  if let body = k900ParseBody(json["B"]) {
3462
- Bridge.sendWearState(worn: (k900JsonInt(body, "on") ?? 0) != 0)
3466
+ Bridge.sendWearState(
3467
+ worn: (k900JsonInt(body, "on") ?? 0) != 0,
3468
+ elapsedMs: k900JsonInt(body, "elapsed_ms"),
3469
+ timeoutMs: k900JsonInt(body, "timeout_ms"),
3470
+ enabled: body["enabled"] == nil ? nil : (k900JsonInt(body, "enabled") ?? 0) != 0,
3471
+ armed: body["armed"] == nil ? nil : (k900JsonInt(body, "armed") ?? 0) != 0,
3472
+ inhibited: body["inhibited"] == nil ? nil : (k900JsonInt(body, "inhibited") ?? 0) != 0
3473
+ )
3463
3474
  }
3464
3475
 
3465
3476
  case "sr_micrms":
@@ -5523,8 +5534,17 @@ class MentraLive: NSObject, SGCManager {
5523
5534
  Bridge.sendSpeakingStatus(speaking)
5524
5535
  }
5525
5536
 
5526
- private func handleSwitchStatus(switchType: Int, value: Int, timestamp: Int64) {
5537
+ private func handleSwitchStatus(
5538
+ switchType: Int, value: Int, timestamp: Int64, resultCode: Int = -1
5539
+ ) {
5527
5540
  Bridge.sendSwitchStatus(switchType: switchType, value: value, timestamp: timestamp)
5541
+ if switchType == Self.autoPowerOffSwitchType {
5542
+ let ok = resultCode == 0
5543
+ Bridge.log(
5544
+ "LIVE: 🔋 auto power-off sr_swit reply type=\(switchType) switch=\(value)"
5545
+ + " result=\(resultCode) ok=\(ok)"
5546
+ )
5547
+ }
5528
5548
  if switchType == Self.voiceActivityDetectionSwitchType, value == 0 || value == 1 {
5529
5549
  handleVoiceActivityDetectionStatus(enabled: value == 1)
5530
5550
  }
@@ -6874,6 +6894,9 @@ extension MentraLive {
6874
6894
  // Send glasses-side loudness / Barrier gate setting.
6875
6895
  sendLoudnessGateSetting()
6876
6896
 
6897
+ // Send glasses-side auto power-off setting.
6898
+ sendAutoPowerOffSetting()
6899
+
6877
6900
  // Send mic tuning. With nothing authorized this sends a reset, which is
6878
6901
  // what returns a freshly connected pair of glasses to stock behaviour.
6879
6902
  sendMicTuningSetting()
@@ -7100,6 +7123,46 @@ extension MentraLive {
7100
7123
  }
7101
7124
  }
7102
7125
 
7126
+ func sendAutoPowerOffSetting() {
7127
+ let enabled = DeviceStore.shared.get("bluetooth", "auto_power_off_enabled") as? Bool
7128
+ ?? BluetoothSdkDefaults.autoPowerOffEnabled
7129
+ Bridge.log(
7130
+ "LIVE: 🔋 Sending auto power-off setting to glasses: enabled=\(enabled)"
7131
+ + " (cs_swit type=\(Self.autoPowerOffSwitchType))"
7132
+ )
7133
+
7134
+ guard connectedPeripheral != nil, txCharacteristic != nil else {
7135
+ Bridge.log("LIVE: Cannot send auto power-off setting - BLE write path not ready")
7136
+ return
7137
+ }
7138
+
7139
+ do {
7140
+ let bodyData = try JSONSerialization.data(withJSONObject: [
7141
+ "type": Self.autoPowerOffSwitchType,
7142
+ "switch": enabled ? 1 : 0,
7143
+ ])
7144
+ guard let bodyString = String(data: bodyData, encoding: .utf8) else {
7145
+ Bridge.log("LIVE: Failed to encode auto power-off payload")
7146
+ return
7147
+ }
7148
+ let command: [String: Any] = [
7149
+ "C": "cs_swit",
7150
+ "V": 1,
7151
+ "B": bodyString,
7152
+ ]
7153
+ if !sendRawK900Command(command, wakeUp: true) {
7154
+ Bridge.log("LIVE: Failed to send auto power-off setting command")
7155
+ } else {
7156
+ Bridge.log(
7157
+ "LIVE: 🔋 Queued auto power-off cs_swit type=\(Self.autoPowerOffSwitchType)"
7158
+ + " switch=\(enabled ? 1 : 0)"
7159
+ )
7160
+ }
7161
+ } catch {
7162
+ Bridge.log("LIVE: Error encoding auto power-off payload: \(error)")
7163
+ }
7164
+ }
7165
+
7103
7166
  func sendButtonVideoRecordingSettings() {
7104
7167
  let settings =
7105
7168
  DeviceStore.shared.get("bluetooth", "button_video_settings") as? [String: Any] ?? [