@mentra/bluetooth-sdk 0.1.2 → 0.1.3

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 (59) hide show
  1. package/README.md +33 -19
  2. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +13 -13
  3. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +42 -18
  4. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +19 -21
  5. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +4 -4
  6. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +118 -103
  7. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +110 -38
  8. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +4 -4
  9. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +2 -2
  10. package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +6 -6
  11. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +1 -1
  12. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3 -3
  13. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1 -1
  14. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +18 -18
  15. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1 -1
  16. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +4 -4
  17. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +2 -2
  18. package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +6 -6
  19. package/build/BluetoothSdk.types.d.ts +126 -27
  20. package/build/BluetoothSdk.types.d.ts.map +1 -1
  21. package/build/BluetoothSdk.types.js.map +1 -1
  22. package/build/_internal.d.ts +12 -0
  23. package/build/_internal.d.ts.map +1 -0
  24. package/build/_internal.js +11 -0
  25. package/build/_internal.js.map +1 -0
  26. package/build/{BluetoothSdkModule.d.ts → _private/BluetoothSdkModule.d.ts} +19 -8
  27. package/build/_private/BluetoothSdkModule.d.ts.map +1 -0
  28. package/build/{BluetoothSdkModule.js → _private/BluetoothSdkModule.js} +41 -26
  29. package/build/_private/BluetoothSdkModule.js.map +1 -0
  30. package/build/index.d.ts +4 -2
  31. package/build/index.d.ts.map +1 -1
  32. package/build/index.js +3 -4
  33. package/build/index.js.map +1 -1
  34. package/ios/BluetoothSdkModule.swift +14 -9
  35. package/ios/Source/Bridge.swift +44 -12
  36. package/ios/Source/DeviceManager.swift +27 -26
  37. package/ios/Source/DeviceStore.swift +4 -4
  38. package/ios/Source/MentraBluetoothSDK.swift +250 -132
  39. package/ios/Source/controllers/ControllerManager.swift +5 -5
  40. package/ios/Source/controllers/R1.swift +3 -3
  41. package/ios/Source/services/PhoneMic.swift +5 -5
  42. package/ios/Source/sgcs/Frame.swift +1 -1
  43. package/ios/Source/sgcs/G1.swift +1 -1
  44. package/ios/Source/sgcs/G2.swift +3 -3
  45. package/ios/Source/sgcs/Mach1.swift +1 -1
  46. package/ios/Source/sgcs/MentraLive.swift +31 -33
  47. package/ios/Source/sgcs/MentraNex.swift +2 -2
  48. package/ios/Source/sgcs/SGCManager.swift +5 -5
  49. package/ios/Source/sgcs/Simulated.swift +3 -3
  50. package/ios/Source/utils/Constants.swift +6 -6
  51. package/ios/Source/utils/JSCExperiment.swift +8 -8
  52. package/ios/Source/utils/TarBz2Extractor.swift +2 -2
  53. package/package.json +13 -1
  54. package/src/BluetoothSdk.types.ts +186 -28
  55. package/src/_internal.ts +11 -0
  56. package/src/{BluetoothSdkModule.ts → _private/BluetoothSdkModule.ts} +71 -38
  57. package/src/index.ts +80 -4
  58. package/build/BluetoothSdkModule.d.ts.map +0 -1
  59. package/build/BluetoothSdkModule.js.map +0 -1
package/README.md CHANGED
@@ -23,8 +23,8 @@ Use a development build or production native build. Expo Go cannot load this pac
23
23
  ## Install
24
24
 
25
25
  ```sh
26
- npm install @mentra/bluetooth-sdk
27
- npx expo install expo-build-properties
26
+ bun add @mentra/bluetooth-sdk
27
+ bunx expo install expo-build-properties
28
28
  ```
29
29
 
30
30
  For Expo apps, add the plugin to `app.json` or `app.config.ts`:
@@ -62,10 +62,10 @@ For Expo apps, add the plugin to `app.json` or `app.config.ts`:
62
62
  Then regenerate native projects and run a development build:
63
63
 
64
64
  ```sh
65
- npx expo prebuild
66
- npx expo run:ios
65
+ bunx expo prebuild
66
+ bunx expo run:ios
67
67
  # or
68
- npx expo run:android
68
+ bunx expo run:android
69
69
  ```
70
70
 
71
71
  ## Permissions
@@ -107,7 +107,7 @@ iOS apps should include usage descriptions:
107
107
 
108
108
  ## Minimal Usage
109
109
 
110
- `connectFirst()` scans for the first matching glasses and connects to them. It times out after 15 seconds by default. Use `startScan()` plus `onBluetoothStatus()` only when your app needs to present a custom device picker.
110
+ Use `scan()` when your app needs to show a picker. It calls `onResults` every time the discovered list changes, then resolves with the final list after the timeout.
111
111
 
112
112
  ```ts
113
113
  import BluetoothSdk, {
@@ -119,7 +119,19 @@ const removeGlassesListener = BluetoothSdk.onGlassesStatus((status) => {
119
119
  console.log('Glasses status changed', status)
120
120
  })
121
121
 
122
- await BluetoothSdk.connectFirst(DeviceModels.MentraLive)
122
+ const devices = await BluetoothSdk.scan(DeviceModels.MentraLive, {
123
+ timeoutMs: 10_000,
124
+ onResults: (nextDevices) => {
125
+ console.log('Nearby glasses:', nextDevices)
126
+ },
127
+ })
128
+
129
+ const device = devices[0]
130
+ if (!device) {
131
+ throw new Error('No Mentra Live glasses found')
132
+ }
133
+
134
+ await BluetoothSdk.connect(device)
123
135
 
124
136
  const glasses = await BluetoothSdk.getGlassesStatus()
125
137
  if (isReadyGlassesConnectionStatus(glasses.connection)) {
@@ -166,7 +178,6 @@ await saveDeviceToYourAppStorage(null)
166
178
  ```ts
167
179
  await BluetoothSdk.clearDisplay()
168
180
  await BluetoothSdk.showDashboard()
169
- await BluetoothSdk.setBrightness(60, false)
170
181
  await BluetoothSdk.setDashboardPosition(4, 2)
171
182
 
172
183
  await BluetoothSdk.requestWifiScan()
@@ -195,19 +206,18 @@ await BluetoothSdk.rgbLedControl(
195
206
  ## Photo Upload
196
207
 
197
208
  ```ts
198
- await BluetoothSdk.photoRequest(
209
+ await BluetoothSdk.requestPhoto(
199
210
  `photo-${Date.now()}`,
200
211
  'com.example.app',
201
212
  'medium',
202
213
  'https://api.example.com/mentra/photo',
203
214
  'optional-token',
204
215
  'medium',
205
- false,
206
216
  true,
207
217
  )
208
218
  ```
209
219
 
210
- The webhook should accept multipart form data with a `photo` file and `requestId`. If `authToken` is provided, the uploader adds `Authorization: Bearer <token>`.
220
+ The webhook should accept multipart form data with a `photo` file and `requestId`. If `authToken` is provided, the uploader adds `Authorization: Bearer <token>`. The camera light is always enabled for photo capture.
211
221
 
212
222
  ## Streaming
213
223
 
@@ -229,7 +239,7 @@ await BluetoothSdk.keepStreamAlive({
229
239
  await BluetoothSdk.stopStream()
230
240
  ```
231
241
 
232
- Use `rtmp://` or `rtmps://` for RTMP, `srt://` for SRT, and `http://` or `https://` for WHIP/WebRTC ingest. Send keep-alives about every 15 seconds while streaming.
242
+ Use `rtmp://` or `rtmps://` for RTMP, `srt://` for SRT, and `http://` or `https://` for WHIP/WebRTC ingest. Send keep-alives about every 15 seconds while streaming. The camera light is always enabled while streaming.
233
243
 
234
244
  ## Events
235
245
 
@@ -245,19 +255,23 @@ const subscriptions = [
245
255
  subscriptions.forEach((subscription) => subscription.remove())
246
256
  ```
247
257
 
248
- Common event names include `button_press`, `touch_event`, `head_up`, `battery_status`, `wifi_status_change`, `hotspot_status_change`, `photo_response`, `gallery_status`, `stream_status`, `keep_alive_ack`, `mic_pcm`, `mic_lc3`, `local_transcription`, `rgb_led_control_response`, `audio_connected`, `audio_disconnected`, `log`, `send_command_to_ble`, and `receive_command_from_ble`.
258
+ Common event names include `button_press`, `touch_event`, `head_up`, `battery_status`, `wifi_status_change`, `hotspot_status_change`, `photo_response`, `gallery_status`, `stream_status`, `keep_alive_ack`, `mic_pcm`, `mic_lc3`, `local_transcription`, `rgb_led_control_response`, `audio_connected`, `audio_disconnected`, and `log`.
259
+
260
+ React Native event payload fields use camelCase. For example, `touch_event` includes `gestureName`, `photo_response` success includes `uploadUrl`, and `gallery_status` includes `hasContent` and `cameraBusy`.
261
+
262
+ Only the documented root import is supported for partner apps. Package subpaths or symbols with a leading underscore are private implementation details and can change without notice.
249
263
 
250
264
  ## Local SDK Development
251
265
 
252
- For normal app development, install the published npm package. For SDK development before a package release, install a local checkout and point Metro/native resolution at the same path:
266
+ For normal app development, install the published JavaScript package. For SDK development before a package release, install a local checkout and point Metro/native resolution at the same path:
253
267
 
254
268
  ```sh
255
- npm install --no-save /path/to/MentraOS/mobile/modules/bluetooth-sdk
256
- MENTRA_BLUETOOTH_SDK_PACKAGE_PATH=/path/to/MentraOS/mobile/modules/bluetooth-sdk npx expo run:ios
269
+ bun add --no-save /path/to/MentraOS/mobile/modules/bluetooth-sdk
270
+ MENTRA_BLUETOOTH_SDK_PACKAGE_PATH=/path/to/MentraOS/mobile/modules/bluetooth-sdk bunx expo run:ios
257
271
  ```
258
272
 
259
- Use `npx expo run:android` for Android. Keep local paths in your shell or CI environment, not in committed app config.
273
+ Use `bunx expo run:android` for Android. Keep local paths in your shell or CI environment, not in committed app config.
260
274
 
261
- ## Example App
275
+ ## Starter Example App
262
276
 
263
- The partner example app lives in `Mentra-Bluetooth-SDK-Partner-Kit/examples/react-native`. It demonstrates scan/connect, display, camera photo upload, RTMP/SRT/WebRTC streaming, Wi-Fi/hotspot, microphone PCM, RGB LED, gallery-button mode, and console event inspection.
277
+ The [Mentra Bluetooth SDK Starter Kit](https://github.com/Mentra-Community/Mentra-Bluetooth-SDK-Starter-Kit) includes starter example apps for Android, iOS, and React Native / Expo. The React Native starter demonstrates scan/connect, display, camera photo upload, RTMP/SRT/WebRTC streaming, Wi-Fi/hotspot, microphone PCM, RGB LED, gallery-button mode, and console event inspection.
@@ -40,7 +40,7 @@ class BluetoothSdkModule : Module() {
40
40
  "compatible_glasses_search_stop",
41
41
  mapOf(
42
42
  "type" to "compatible_glasses_search_stop",
43
- "device_model" to deviceModel,
43
+ "deviceModel" to deviceModel,
44
44
  )
45
45
  )
46
46
  }
@@ -294,6 +294,8 @@ class BluetoothSdkModule : Module() {
294
294
  sdk?.startScan(DeviceModel.fromDeviceType(model))
295
295
  }
296
296
 
297
+ AsyncFunction("stopScan") { sdk?.stopScan() }
298
+
297
299
  AsyncFunction("cancelConnectionAttempt") { sdk?.cancelConnectionAttempt() }
298
300
 
299
301
  AsyncFunction("showDashboard") { sdk?.showDashboard() }
@@ -346,14 +348,13 @@ class BluetoothSdkModule : Module() {
346
348
 
347
349
  AsyncFunction("queryGalleryStatus") { sdk?.queryGalleryStatus() }
348
350
 
349
- AsyncFunction("photoRequest") {
351
+ AsyncFunction("requestPhoto") {
350
352
  requestId: String,
351
353
  appId: String,
352
354
  size: String,
353
355
  webhookUrl: String,
354
356
  authToken: String?,
355
357
  compress: String,
356
- flash: Boolean,
357
358
  sound: Boolean ->
358
359
  sdk?.requestPhoto(
359
360
  PhotoRequest(
@@ -363,7 +364,6 @@ class BluetoothSdkModule : Module() {
363
364
  webhookUrl = webhookUrl,
364
365
  authToken = authToken,
365
366
  compress = PhotoCompression.fromValue(compress),
366
- flash = flash,
367
367
  sound = sound,
368
368
  )
369
369
  )
@@ -387,8 +387,8 @@ class BluetoothSdkModule : Module() {
387
387
 
388
388
  // MARK: - Video Recording Commands
389
389
 
390
- AsyncFunction("startVideoRecording") { requestId: String, save: Boolean, flash: Boolean, sound: Boolean ->
391
- sdk?.startVideoRecording(VideoRecordingRequest(requestId, save, flash, sound))
390
+ AsyncFunction("startVideoRecording") { requestId: String, save: Boolean, sound: Boolean ->
391
+ sdk?.startVideoRecording(VideoRecordingRequest(requestId, save, sound))
392
392
  }
393
393
 
394
394
  AsyncFunction("stopVideoRecording") { requestId: String ->
@@ -449,8 +449,8 @@ class BluetoothSdkModule : Module() {
449
449
  packageName: String?,
450
450
  action: String,
451
451
  color: String?,
452
- ontime: Int,
453
- offtime: Int,
452
+ onDurationMs: Int,
453
+ offDurationMs: Int,
454
454
  count: Int ->
455
455
  sdk?.rgbLedControl(
456
456
  RgbLedRequest(
@@ -458,8 +458,8 @@ class BluetoothSdkModule : Module() {
458
458
  packageName = packageName,
459
459
  action = RgbLedAction.fromValue(action),
460
460
  color = RgbLedColor.fromValue(color),
461
- ontime = ontime,
462
- offtime = offtime,
461
+ onDurationMs = onDurationMs,
462
+ offDurationMs = offDurationMs,
463
463
  count = count,
464
464
  )
465
465
  )
@@ -504,9 +504,9 @@ class BluetoothSdkModule : Module() {
504
504
 
505
505
  private fun Map<String, Any>?.toMentraDevice(): Device? {
506
506
  val values = this ?: return null
507
- val model = values["model"] as? String ?: values["deviceModel"] as? String ?: return null
508
- val name = values["name"] as? String ?: values["deviceName"] as? String ?: return null
509
- val address = values["address"] as? String ?: values["deviceAddress"] as? String
507
+ val model = values["model"] as? String ?: return null
508
+ val name = values["name"] as? String ?: return null
509
+ val address = values["address"] as? String
510
510
  val rssi = (values["rssi"] as? Number)?.toInt()
511
511
  val id = values["id"] as? String
512
512
  return Device(
@@ -121,7 +121,7 @@ public class Bridge private constructor() {
121
121
  @JvmStatic
122
122
  fun sendAudioConnected(deviceName: String) {
123
123
  val data = HashMap<String, Any>()
124
- data["device_name"] = deviceName
124
+ data["deviceName"] = deviceName
125
125
  sendTypedMessage("audio_connected", data as Map<String, Any>)
126
126
  }
127
127
 
@@ -211,19 +211,41 @@ public class Bridge private constructor() {
211
211
  }
212
212
  rssi?.let { put("rssi", it) }
213
213
  }
214
- val allResults = searchResults + newResult
215
- val uniqueResults =
216
- allResults
217
- .asReversed()
218
- .distinctBy {
219
- val model = it["model"] ?: it["deviceModel"] ?: deviceModel
220
- val name = it["name"] ?: it["deviceName"] ?: return@distinctBy null
221
- "$model:$name"
222
- }
223
- .asReversed()
214
+ // Keep the public searchResults array stable as glasses are added or removed.
215
+ // Duplicate discoveries refresh their existing row; only new glasses append.
216
+ val uniqueResults = mergeStableSearchResults(searchResults, newResult, deviceModel)
224
217
  DeviceStore.set("bluetooth", "searchResults", uniqueResults)
225
218
  }
226
219
 
220
+ private fun mergeStableSearchResults(
221
+ currentResults: List<Map<String, Any>>,
222
+ newResult: Map<String, Any>,
223
+ fallbackModel: String
224
+ ): List<Map<String, Any>> {
225
+ val newKey = searchResultKey(newResult, fallbackModel) ?: return currentResults
226
+ val nextResults = currentResults.toMutableList()
227
+ val existingIndex =
228
+ nextResults.indexOfFirst { result ->
229
+ searchResultKey(result, fallbackModel) == newKey
230
+ }
231
+ if (existingIndex >= 0) {
232
+ nextResults[existingIndex] = newResult
233
+ } else {
234
+ nextResults += newResult
235
+ }
236
+ return nextResults
237
+ }
238
+
239
+ private fun searchResultKey(result: Map<String, Any>, fallbackModel: String): String? {
240
+ val id = result["id"] as? String
241
+ if (!id.isNullOrBlank()) {
242
+ return id
243
+ }
244
+ val model = result["model"] as? String ?: fallbackModel
245
+ val name = result["name"] as? String ?: return null
246
+ return "$model:$name"
247
+ }
248
+
227
249
  // MARK: - Hardware Events
228
250
 
229
251
  /** Send button press event to React Native - matches iOS implementation */
@@ -255,8 +277,9 @@ public class Bridge private constructor() {
255
277
  source: Int? = null
256
278
  ) {
257
279
  val body = HashMap<String, Any>()
258
- body["device_model"] = deviceModel
259
- body["gesture_name"] = gestureName
280
+ body["type"] = "touch_event"
281
+ body["deviceModel"] = deviceModel
282
+ body["gestureName"] = gestureName
260
283
  body["timestamp"] = timestamp
261
284
  if (source != null) {
262
285
  body["source"] = source
@@ -277,8 +300,8 @@ public class Bridge private constructor() {
277
300
  @JvmStatic
278
301
  fun sendSwitchStatus(switchType: Int, value: Int, timestamp: Long) {
279
302
  val body = HashMap<String, Any>()
280
- body["switch_type"] = switchType
281
- body["switch_value"] = value
303
+ body["switchType"] = switchType
304
+ body["switchValue"] = value
282
305
  body["timestamp"] = timestamp
283
306
  sendTypedMessage("switch_status", body)
284
307
  }
@@ -301,6 +324,7 @@ public class Bridge private constructor() {
301
324
  if (requestId.isEmpty()) return
302
325
  try {
303
326
  val body = HashMap<String, Any>()
327
+ body["type"] = "rgb_led_control_response"
304
328
  body["requestId"] = requestId
305
329
  body["state"] = if (success) "success" else "error"
306
330
  if (!success) {
@@ -405,8 +429,8 @@ public class Bridge private constructor() {
405
429
  galleryData["photos"] = photoCount
406
430
  galleryData["videos"] = videoCount
407
431
  galleryData["total"] = totalCount
408
- galleryData["total_size"] = totalSize
409
- galleryData["has_content"] = hasContent
432
+ galleryData["totalSize"] = totalSize
433
+ galleryData["hasContent"] = hasContent
410
434
 
411
435
  sendTypedMessage("gallery_status", galleryData as Map<String, Any>)
412
436
  }
@@ -427,7 +451,7 @@ public class Bridge private constructor() {
427
451
  @JvmStatic
428
452
  fun sendHotspotError(errorMessage: String, timestamp: Long) {
429
453
  val eventBody = HashMap<String, Any>()
430
- eventBody["error_message"] = errorMessage
454
+ eventBody["errorMessage"] = errorMessage
431
455
  eventBody["timestamp"] = timestamp
432
456
 
433
457
  sendTypedMessage("hotspot_error", eventBody as Map<String, Any>)
@@ -169,17 +169,17 @@ class DeviceManager {
169
169
  set(value) = DeviceStore.apply("bluetooth", "dashboard_depth", value)
170
170
 
171
171
  private var galleryMode: Boolean
172
- get() = DeviceStore.store.get("bluetooth", "gallery_mode") as? Boolean ?: true
173
- set(value) = DeviceStore.apply("bluetooth", "gallery_mode", value)
172
+ get() = DeviceStore.store.get("bluetooth", "galleryModeAuto") as? Boolean ?: true
173
+ set(value) = DeviceStore.apply("bluetooth", "galleryModeAuto", value)
174
174
 
175
175
  // state:
176
176
  private var searching: Boolean
177
177
  get() = DeviceStore.store.get("bluetooth", "searching") as? Boolean ?: false
178
178
  set(value) = DeviceStore.apply("bluetooth", "searching", value)
179
179
 
180
- private var glassesBtcConnected: Boolean
181
- get() = DeviceStore.store.get("glasses", "btcConnected") as? Boolean ?: false
182
- set(value) = DeviceStore.apply("glasses", "btcConnected", value)
180
+ private var glassesBluetoothClassicConnected: Boolean
181
+ get() = DeviceStore.store.get("glasses", "bluetoothClassicConnected") as? Boolean ?: false
182
+ set(value) = DeviceStore.apply("glasses", "bluetoothClassicConnected", value)
183
183
 
184
184
  public var micRanking: MutableList<String>
185
185
  get() =
@@ -727,8 +727,8 @@ class DeviceManager {
727
727
 
728
728
  for (micMode in micRanking) {
729
729
  if (micMode == MicTypes.PHONE_INTERNAL ||
730
- micMode == MicTypes.BT_CLASSIC ||
731
- micMode == MicTypes.BT
730
+ micMode == MicTypes.BLUETOOTH_CLASSIC ||
731
+ micMode == MicTypes.BLUETOOTH
732
732
  ) {
733
733
 
734
734
  if (phoneMic?.isRecordingWithMode(micMode) == true) {
@@ -790,8 +790,8 @@ class DeviceManager {
790
790
  }
791
791
 
792
792
  if (micMode == MicTypes.PHONE_INTERNAL ||
793
- micMode == MicTypes.BT_CLASSIC ||
794
- micMode == MicTypes.BT
793
+ micMode == MicTypes.BLUETOOTH_CLASSIC ||
794
+ micMode == MicTypes.BLUETOOTH
795
795
  ) {
796
796
  phoneMic?.stopMode(micMode)
797
797
  }
@@ -1221,6 +1221,7 @@ class DeviceManager {
1221
1221
 
1222
1222
  fun startStream(message: MutableMap<String, Any>) {
1223
1223
  Bridge.log("MAN: startStream")
1224
+ message["flash"] = true
1224
1225
  sgc?.startStream(message)
1225
1226
  }
1226
1227
 
@@ -1352,11 +1353,11 @@ class DeviceManager {
1352
1353
  sgc?.sendReboot()
1353
1354
  }
1354
1355
 
1355
- fun startVideoRecording(requestId: String, save: Boolean, flash: Boolean, sound: Boolean) {
1356
+ fun startVideoRecording(requestId: String, save: Boolean, sound: Boolean) {
1356
1357
  Bridge.log(
1357
- "MAN: onStartVideoRecording: requestId=$requestId, save=$save, flash=$flash, sound=$sound"
1358
+ "MAN: onStartVideoRecording: requestId=$requestId, save=$save, flash=true, sound=$sound"
1358
1359
  )
1359
- sgc?.startVideoRecording(requestId, save, flash, sound)
1360
+ sgc?.startVideoRecording(requestId, save, true, sound)
1360
1361
  }
1361
1362
 
1362
1363
  fun stopVideoRecording(requestId: String) {
@@ -1372,20 +1373,17 @@ class DeviceManager {
1372
1373
  updateMicState()
1373
1374
  }
1374
1375
 
1375
- fun photoRequest(
1376
+ fun requestPhoto(
1376
1377
  requestId: String,
1377
1378
  appId: String,
1378
1379
  size: String,
1379
1380
  webhookUrl: String,
1380
1381
  authToken: String?,
1381
1382
  compress: String,
1382
- flash: Boolean,
1383
1383
  sound: Boolean
1384
1384
  ) {
1385
- Bridge.log(
1386
- "MAN: onPhotoRequest: $requestId, $appId, $size, compress=$compress, flash=$flash, sound=$sound"
1387
- )
1388
- sgc?.requestPhoto(requestId, appId, size, webhookUrl, authToken, compress, flash, sound)
1385
+ Bridge.log("MAN: requestPhoto: $requestId, $appId, $size, compress=$compress, flash=true, sound=$sound")
1386
+ sgc?.requestPhoto(requestId, appId, size, webhookUrl, authToken, compress, true, sound)
1389
1387
  }
1390
1388
 
1391
1389
  fun rgbLedControl(
@@ -1393,12 +1391,12 @@ class DeviceManager {
1393
1391
  packageName: String?,
1394
1392
  action: String,
1395
1393
  color: String?,
1396
- ontime: Int,
1397
- offtime: Int,
1394
+ onDurationMs: Int,
1395
+ offDurationMs: Int,
1398
1396
  count: Int
1399
1397
  ) {
1400
1398
  Bridge.log("MAN: RGB LED control: action=$action, color=$color, requestId=$requestId")
1401
- sgc?.sendRgbLedControl(requestId, packageName, action, color, ontime, offtime, count)
1399
+ sgc?.sendRgbLedControl(requestId, packageName, action, color, onDurationMs, offDurationMs, count)
1402
1400
  }
1403
1401
 
1404
1402
  fun connectDefault() {
@@ -66,7 +66,7 @@ object DeviceStore {
66
66
  store.set("glasses", "deviceModel", "")
67
67
  store.set("glasses", "firmwareVersion", "")
68
68
  store.set("glasses", "micEnabled", false)
69
- store.set("glasses", "btcConnected", false)
69
+ store.set("glasses", "bluetoothClassicConnected", false)
70
70
  store.set("glasses", "caseRemoved", true)
71
71
  store.set("glasses", "caseOpen", true)
72
72
  store.set("glasses", "caseCharging", false)
@@ -121,12 +121,12 @@ object DeviceStore {
121
121
  store.set("bluetooth", "dashboard_depth", 2)
122
122
  store.set("bluetooth", "head_up_angle", 30)
123
123
  store.set("bluetooth", "contextual_dashboard", true)
124
- store.set("bluetooth", "gallery_mode", true)
124
+ store.set("bluetooth", "galleryModeAuto", true)
125
125
  store.set("bluetooth", "screen_disabled", false)
126
126
  store.set("bluetooth", "button_photo_size", "medium")
127
127
  store.set("bluetooth", "button_camera_led", true)
128
128
  store.set("bluetooth", "button_max_recording_time", 10)
129
- store.set("bluetooth", "camera_fov", mapOf("fov" to 118, "roi_position" to 0))
129
+ store.set("bluetooth", "camera_fov", mapOf("fov" to 118, "roiPosition" to 0))
130
130
  store.set("bluetooth", "button_video_width", 1280)
131
131
  store.set("bluetooth", "button_video_height", 720)
132
132
  store.set("bluetooth", "button_video_fps", 30)
@@ -239,7 +239,7 @@ object DeviceStore {
239
239
  DeviceManager.getInstance().sgc?.setDashboardMenu(items)
240
240
  }
241
241
  }
242
- "bluetooth" to "gallery_mode" -> {
242
+ "bluetooth" to "galleryModeAuto" -> {
243
243
  DeviceManager.getInstance().sgc?.sendGalleryMode()
244
244
  }
245
245
  "bluetooth" to "screen_disabled" -> {