@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.
- package/README.md +33 -19
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +13 -13
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +42 -18
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +19 -21
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +4 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +118 -103
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +110 -38
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +4 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +6 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3 -3
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +18 -18
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +4 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +2 -2
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +6 -6
- package/build/BluetoothSdk.types.d.ts +126 -27
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_internal.d.ts +12 -0
- package/build/_internal.d.ts.map +1 -0
- package/build/_internal.js +11 -0
- package/build/_internal.js.map +1 -0
- package/build/{BluetoothSdkModule.d.ts → _private/BluetoothSdkModule.d.ts} +19 -8
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -0
- package/build/{BluetoothSdkModule.js → _private/BluetoothSdkModule.js} +41 -26
- package/build/_private/BluetoothSdkModule.js.map +1 -0
- package/build/index.d.ts +4 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -4
- package/build/index.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +14 -9
- package/ios/Source/Bridge.swift +44 -12
- package/ios/Source/DeviceManager.swift +27 -26
- package/ios/Source/DeviceStore.swift +4 -4
- package/ios/Source/MentraBluetoothSDK.swift +250 -132
- package/ios/Source/controllers/ControllerManager.swift +5 -5
- package/ios/Source/controllers/R1.swift +3 -3
- package/ios/Source/services/PhoneMic.swift +5 -5
- package/ios/Source/sgcs/Frame.swift +1 -1
- package/ios/Source/sgcs/G1.swift +1 -1
- package/ios/Source/sgcs/G2.swift +3 -3
- package/ios/Source/sgcs/Mach1.swift +1 -1
- package/ios/Source/sgcs/MentraLive.swift +31 -33
- package/ios/Source/sgcs/MentraNex.swift +2 -2
- package/ios/Source/sgcs/SGCManager.swift +5 -5
- package/ios/Source/sgcs/Simulated.swift +3 -3
- package/ios/Source/utils/Constants.swift +6 -6
- package/ios/Source/utils/JSCExperiment.swift +8 -8
- package/ios/Source/utils/TarBz2Extractor.swift +2 -2
- package/package.json +13 -1
- package/src/BluetoothSdk.types.ts +186 -28
- package/src/_internal.ts +11 -0
- package/src/{BluetoothSdkModule.ts → _private/BluetoothSdkModule.ts} +71 -38
- package/src/index.ts +80 -4
- package/build/BluetoothSdkModule.d.ts.map +0 -1
- package/build/BluetoothSdkModule.js.map +0 -1
|
@@ -6,13 +6,22 @@ const DEFAULT_CONNECT_OPTIONS = {
|
|
|
6
6
|
saveAsDefault: true,
|
|
7
7
|
cancelExistingConnectionAttempt: true,
|
|
8
8
|
};
|
|
9
|
-
const
|
|
9
|
+
const DEFAULT_SCAN_TIMEOUT_MS = 15_000;
|
|
10
10
|
const CAMERA_FOV_SETTINGS = {
|
|
11
|
-
standard: { fov: 118,
|
|
12
|
-
wide: { fov: 118,
|
|
11
|
+
standard: { fov: 118, roiPosition: 0 },
|
|
12
|
+
wide: { fov: 118, roiPosition: 0 },
|
|
13
13
|
};
|
|
14
|
-
function
|
|
15
|
-
return status.searchResults?.
|
|
14
|
+
function searchResultsForModel(status, model) {
|
|
15
|
+
return status.searchResults?.filter((device) => device.model === model) ?? [];
|
|
16
|
+
}
|
|
17
|
+
function normalizeScanArgs(modelOrOptions, options) {
|
|
18
|
+
if (typeof modelOrOptions === "string") {
|
|
19
|
+
return { model: modelOrOptions, ...options };
|
|
20
|
+
}
|
|
21
|
+
return modelOrOptions;
|
|
22
|
+
}
|
|
23
|
+
function normalizeTimeoutMs(timeoutMs, defaultTimeoutMs) {
|
|
24
|
+
return typeof timeoutMs === "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : defaultTimeoutMs;
|
|
16
25
|
}
|
|
17
26
|
function dashboardMenuItemToNative(item) {
|
|
18
27
|
return {
|
|
@@ -131,11 +140,11 @@ NativeBluetoothSdkModule.setScreenDisabled = function (disabled) {
|
|
|
131
140
|
NativeBluetoothSdkModule.setButtonPhotoSettings = function (size) {
|
|
132
141
|
return this.updateBluetoothSettings({ button_photo_size: size });
|
|
133
142
|
};
|
|
134
|
-
NativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width, height,
|
|
143
|
+
NativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width, height, frameRate) {
|
|
135
144
|
return this.updateBluetoothSettings({
|
|
136
145
|
button_video_width: width,
|
|
137
146
|
button_video_height: height,
|
|
138
|
-
button_video_fps:
|
|
147
|
+
button_video_fps: frameRate,
|
|
139
148
|
});
|
|
140
149
|
};
|
|
141
150
|
NativeBluetoothSdkModule.setButtonCameraLed = function (enabled) {
|
|
@@ -171,19 +180,29 @@ NativeBluetoothSdkModule.connectDefault = function (options) {
|
|
|
171
180
|
NativeBluetoothSdkModule.connect = function (device, options) {
|
|
172
181
|
return this.connectWithOptions(device, { ...DEFAULT_CONNECT_OPTIONS, ...options });
|
|
173
182
|
};
|
|
174
|
-
NativeBluetoothSdkModule.
|
|
175
|
-
const
|
|
176
|
-
const
|
|
183
|
+
NativeBluetoothSdkModule.scan = async function (modelOrOptions, options) {
|
|
184
|
+
const scanOptions = normalizeScanArgs(modelOrOptions, options);
|
|
185
|
+
const timeoutMs = normalizeTimeoutMs(scanOptions.timeoutMs ?? scanOptions.timeout, DEFAULT_SCAN_TIMEOUT_MS);
|
|
186
|
+
let latestResults = [];
|
|
187
|
+
return new Promise((resolve, reject) => {
|
|
177
188
|
let timeout = null;
|
|
178
189
|
let removeBluetoothListener = () => { };
|
|
179
190
|
let settled = false;
|
|
191
|
+
let scanStarted = false;
|
|
192
|
+
const emitResults = (devices) => {
|
|
193
|
+
latestResults = devices;
|
|
194
|
+
scanOptions.onResults?.([...devices]);
|
|
195
|
+
};
|
|
180
196
|
const cleanup = () => {
|
|
181
197
|
if (timeout) {
|
|
182
198
|
clearTimeout(timeout);
|
|
183
199
|
}
|
|
184
200
|
removeBluetoothListener();
|
|
201
|
+
if (scanStarted) {
|
|
202
|
+
void Promise.resolve(this.stopScan()).catch(() => undefined);
|
|
203
|
+
}
|
|
185
204
|
};
|
|
186
|
-
const settle = (error
|
|
205
|
+
const settle = (error) => {
|
|
187
206
|
if (settled) {
|
|
188
207
|
return;
|
|
189
208
|
}
|
|
@@ -192,29 +211,25 @@ NativeBluetoothSdkModule.connectFirst = async function (model, options) {
|
|
|
192
211
|
if (error) {
|
|
193
212
|
reject(error);
|
|
194
213
|
}
|
|
195
|
-
else
|
|
196
|
-
resolve(
|
|
214
|
+
else {
|
|
215
|
+
resolve([...latestResults]);
|
|
197
216
|
}
|
|
198
217
|
};
|
|
199
218
|
const handleBluetoothStatus = (status) => {
|
|
200
|
-
|
|
201
|
-
if (result) {
|
|
202
|
-
settle(null, result);
|
|
203
|
-
}
|
|
219
|
+
emitResults(searchResultsForModel(status, scanOptions.model));
|
|
204
220
|
};
|
|
205
221
|
removeBluetoothListener = this.onBluetoothStatus(handleBluetoothStatus);
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
222
|
+
emitResults([]);
|
|
223
|
+
timeout = setTimeout(() => settle(), timeoutMs);
|
|
224
|
+
Promise.resolve(this.startScan(scanOptions.model))
|
|
225
|
+
.then(() => {
|
|
226
|
+
scanStarted = true;
|
|
227
|
+
return this.getBluetoothStatus();
|
|
228
|
+
})
|
|
213
229
|
.then(handleBluetoothStatus)
|
|
214
230
|
.catch((error) => settle(error instanceof Error ? error : new Error(String(error))));
|
|
215
231
|
});
|
|
216
|
-
await this.connect(device, connectOptions);
|
|
217
|
-
return device;
|
|
218
232
|
};
|
|
219
233
|
export default NativeBluetoothSdkModule;
|
|
234
|
+
export const BluetoothSdk = NativeBluetoothSdkModule;
|
|
220
235
|
//# sourceMappingURL=BluetoothSdkModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BluetoothSdkModule.js","sourceRoot":"","sources":["../../src/_private/BluetoothSdkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,mBAAmB,EAAC,MAAM,MAAM,CAAA;AAoLtD,yDAAyD;AACzD,gGAAgG;AAChG,MAAM,wBAAwB,GAAG,mBAAmB,CAA2B,cAAc,CAAC,CAAA;AAE9F,MAAM,uBAAuB,GAA6B;IACxD,aAAa,EAAE,IAAI;IACnB,+BAA+B,EAAE,IAAI;CACtC,CAAA;AAED,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAEtC,MAAM,mBAAmB,GAAwC;IAC/D,QAAQ,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,EAAC;IACpC,IAAI,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,EAAC;CACjC,CAAA;AAED,SAAS,qBAAqB,CAAC,MAAgC,EAAE,KAAkB;IACjF,OAAO,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,CAAA;AAC/E,CAAC;AAED,SAAS,iBAAiB,CAAC,cAAyC,EAAE,OAA0B;IAC9F,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,EAAC,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,EAAC,CAAA;IAC5C,CAAC;IACD,OAAO,cAAc,CAAA;AACvB,CAAC;AAED,SAAS,kBAAkB,CAAC,SAA6B,EAAE,gBAAwB;IACjF,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAA;AACpH,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAuB;IACxD,OAAO;QACL,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QACtB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;KAC9B,CAAA;AACH,CAAC;AAED,SAAS,6BAA6B,CAAC,UAAuC;IAC5E,QAAQ,UAAU,CAAC,KAAK,EAAE,CAAC;QACzB,KAAK,WAAW;YACd,OAAO,EAAC,eAAe,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC,WAAW,EAAC,CAAA;QAC7F,KAAK,UAAU;YACb,OAAO,EAAC,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;QAC5E,KAAK,YAAY;YACf,OAAO,EAAC,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;QAC9E,KAAK,SAAS;YACZ,OAAO,EAAC,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;QAC3E,KAAK,cAAc;YACjB,OAAO,EAAC,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAC,CAAA;IAClF,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,MAA8B;IAChE,MAAM,EAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,EAAC,GAAG,MAAM,CAAA;IACnD,IAAI,MAAM,GAA4B,EAAC,GAAG,IAAI,EAAC,CAAA;IAC/C,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,GAAG;YACP,GAAG,MAAM;YACT,GAAG,6BAA6B,CAAC,UAAU,CAAC;SAC7C,CAAA;IACH,CAAC;IACD,IAAI,IAAI,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;QAChC,MAAM,GAAG;YACP,GAAG,MAAM;YACT,aAAa,EAAE,IAAI;YACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,WAAW,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;SAChC,CAAA;IACH,CAAC;SAAM,IAAI,IAAI,EAAE,KAAK,KAAK,cAAc,EAAE,CAAC;QAC1C,MAAM,GAAG;YACP,GAAG,MAAM;YACT,aAAa,EAAE,KAAK;YACpB,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,EAAE;SAChB,CAAA;IACH,CAAC;IACD,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG;YACP,GAAG,MAAM;YACT,cAAc,EAAE,IAAI;YACpB,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,eAAe,EAAE,OAAO,CAAC,QAAQ;YACjC,gBAAgB,EAAE,OAAO,CAAC,OAAO;SAClC,CAAA;IACH,CAAC;SAAM,IAAI,OAAO,EAAE,KAAK,KAAK,UAAU,EAAE,CAAC;QACzC,MAAM,GAAG;YACP,GAAG,MAAM;YACT,cAAc,EAAE,KAAK;YACrB,WAAW,EAAE,EAAE;YACf,eAAe,EAAE,EAAE;YACnB,gBAAgB,EAAE,EAAE;SACrB,CAAA;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,mCAAmC;AACnC,MAAM,sBAAsB,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,IAAI,CAC3E,wBAAwB,CACY,CAAA;AACtC,wBAAwB,CAAC,gBAAgB,GAAG;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAA;AAClD,CAAC,CAAA;AAED,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,kBAAkB,CAAC,IAAI,CAAC,wBAAwB,CAAwC,CAAA;AAClJ,wBAAwB,CAAC,kBAAkB,GAAG;IAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAA;AACpD,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,IAAI,CAC3E,wBAAwB,CACY,CAAA;AACtC,wBAAwB,CAAC,gBAAgB,GAAG;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAA;AAClD,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAMrE,CAAA;AAEvB,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,WAAW,CAAC,IAAI,CAAC,wBAAwB,CAKrE,CAAA;AAEvB,wBAAwB,CAAC,aAAa,GAAG,UAAU,MAA8B;IAC/E,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC,CAAA;AACnE,CAAC,CAAA;AAED,wBAAwB,CAAC,uBAAuB,GAAG,UAAU,MAA+B;IAC1F,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;AACzC,CAAC,CAAA;AAED,wBAAwB,CAAC,WAAW,GAAG,UAAU,IAAY,EAAE,CAAU,EAAE,CAAU,EAAE,IAAa;IAClG,OAAO,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAA;AAC7E,CAAC,CAAA;AAED,wBAAwB,CAAC,aAAa,GAAG,UAAU,KAAa,EAAE,QAAyB;IACzF,OAAO,IAAI,CAAC,uBAAuB,CAAC;QAClC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,eAAe,EAAE,QAAQ,EAAC,CAAC;QACxD,UAAU,EAAE,KAAK;KAClB,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,wBAAwB,CAAC,iBAAiB,GAAG,UAAU,OAAgB;IACrE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,eAAe,EAAE,OAAO,EAAC,CAAC,CAAA;AACjE,CAAC,CAAA;AAED,wBAAwB,CAAC,oBAAoB,GAAG,UAAU,MAAc,EAAE,KAAa;IACrF,OAAO,IAAI,CAAC,uBAAuB,CAAC;QAClC,gBAAgB,EAAE,MAAM;QACxB,eAAe,EAAE,KAAK;KACvB,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,wBAAwB,CAAC,gBAAgB,GAAG,UAAU,KAA0B;IAC9E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAC,CAAC,CAAA;AACxF,CAAC,CAAA;AAED,wBAAwB,CAAC,cAAc,GAAG,UAAU,YAAoB;IACtE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,aAAa,EAAE,YAAY,EAAC,CAAC,CAAA;AACpE,CAAC,CAAA;AAED,wBAAwB,CAAC,iBAAiB,GAAG,UAAU,QAAiB;IACtE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,eAAe,EAAE,QAAQ,EAAC,CAAC,CAAA;AAClE,CAAC,CAAA;AAED,wBAAwB,CAAC,sBAAsB,GAAG,UAAU,IAAqB;IAC/E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,iBAAiB,EAAE,IAAI,EAAC,CAAC,CAAA;AAChE,CAAC,CAAA;AAED,wBAAwB,CAAC,+BAA+B,GAAG,UAAU,KAAa,EAAE,MAAc,EAAE,SAAiB;IACnH,OAAO,IAAI,CAAC,uBAAuB,CAAC;QAClC,kBAAkB,EAAE,KAAK;QACzB,mBAAmB,EAAE,MAAM;QAC3B,gBAAgB,EAAE,SAAS;KAC5B,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,wBAAwB,CAAC,kBAAkB,GAAG,UAAU,OAAgB;IACtE,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,iBAAiB,EAAE,OAAO,EAAC,CAAC,CAAA;AACnE,CAAC,CAAA;AAED,wBAAwB,CAAC,yBAAyB,GAAG,UAAU,OAAe;IAC5E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,yBAAyB,EAAE,OAAO,EAAC,CAAC,CAAA;AAC3E,CAAC,CAAA;AAED,wBAAwB,CAAC,YAAY,GAAG,UAAU,GAAc;IAC9D,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,UAAU,EAAE,mBAAmB,CAAC,GAAG,CAAC,EAAC,CAAC,CAAA;AAC7E,CAAC,CAAA;AAED,wBAAwB,CAAC,WAAW,GAAG,UACrC,OAAgB,EAChB,aAAuB,EACvB,SAAmB,EACnB,cAAwB,EACxB,WAAqB;IAErB,OAAO,OAAO,CAAC,OAAO,CACpB,iBAAiB,CACf,OAAO,EACP,aAAa,IAAI,IAAI,EACrB,SAAS,IAAI,KAAK,EAClB,cAAc,IAAI,KAAK,EACvB,WAAW,IAAI,KAAK,CACrB,CACF,CAAA;AACH,CAAC,CAAA;AAED,wBAAwB,CAAC,eAAe,GAAG,UAAU,YAA2B;IAC9E,OAAO,IAAI,CAAC,uBAAuB,CAAC,EAAC,aAAa,EAAE,YAAY,EAAC,CAAC,CAAA;AACpE,CAAC,CAAA;AAED,wBAAwB,CAAC,eAAe,GAAG,UAAU,QAAyB;IAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAA;IACjE,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAA;AACpC,CAAC,CAAA;AAED,wBAAwB,CAAC,iBAAiB,GAAG,UAAU,QAAiC;IACtF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAA;IACnE,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAA;AACpC,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,wBAAwB,CAAC,cAAc,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;AACnG,wBAAwB,CAAC,cAAc,GAAG,UAAU,OAAwB;IAC1E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,oBAAoB,EAAE,CAAA;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC,yBAAyB,CAAC,EAAC,GAAG,uBAAuB,EAAE,GAAG,OAAO,EAAC,CAAC,CAAA;AACjF,CAAC,CAAA;AAED,wBAAwB,CAAC,OAAO,GAAG,UAAU,MAAc,EAAE,OAAwB;IACnF,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAC,GAAG,uBAAuB,EAAE,GAAG,OAAO,EAAC,CAAC,CAAA;AAClF,CAAC,CAAA;AAED,wBAAwB,CAAC,IAAI,GAAG,KAAK,WACnC,cAAyC,EACzC,OAA0B;IAE1B,MAAM,WAAW,GAAG,iBAAiB,CAAC,cAAc,EAAE,OAAO,CAAC,CAAA;IAC9D,MAAM,SAAS,GAAG,kBAAkB,CAAC,WAAW,CAAC,SAAS,IAAI,WAAW,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAA;IAC3G,IAAI,aAAa,GAAa,EAAE,CAAA;IAEhC,OAAO,IAAI,OAAO,CAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC/C,IAAI,OAAO,GAAyC,IAAI,CAAA;QACxD,IAAI,uBAAuB,GAAG,GAAG,EAAE,GAAE,CAAC,CAAA;QACtC,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,WAAW,GAAG,KAAK,CAAA;QAEvB,MAAM,WAAW,GAAG,CAAC,OAAiB,EAAE,EAAE;YACxC,aAAa,GAAG,OAAO,CAAA;YACvB,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAA;QACvC,CAAC,CAAA;QAED,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,OAAO,CAAC,CAAA;YACvB,CAAC;YACD,uBAAuB,EAAE,CAAA;YACzB,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;YAC9D,CAAC;QACH,CAAC,CAAA;QAED,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAM;YACR,CAAC;YACD,OAAO,GAAG,IAAI,CAAA;YACd,OAAO,EAAE,CAAA;YACT,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,KAAK,CAAC,CAAA;YACf,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC,CAAA;QAED,MAAM,qBAAqB,GAAG,CAAC,MAAgC,EAAE,EAAE;YACjE,WAAW,CAAC,qBAAqB,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;QAC/D,CAAC,CAAA;QAED,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,CAAA;QACvE,WAAW,CAAC,EAAE,CAAC,CAAA;QAEf,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,CAAC,CAAA;QAE/C,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;aAC/C,IAAI,CAAC,GAAG,EAAE;YACT,WAAW,GAAG,IAAI,CAAA;YAClB,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAA;QAClC,CAAC,CAAC;aACD,IAAI,CAAC,qBAAqB,CAAC;aAC3B,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACxF,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,eAAe,wBAAwB,CAAA;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAoD,CAAA","sourcesContent":["import {NativeModule, requireNativeModule} from \"expo\"\n\nimport {\n BluetoothSettingsUpdate,\n BluetoothSdkPublicModule,\n BluetoothSdkModuleEvents,\n BluetoothStatus,\n ButtonPhotoSize,\n CameraFov,\n CameraFovSetting,\n ConnectOptions,\n DashboardMenuItem,\n Device,\n DeviceModel,\n GalleryMode,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesStatus,\n MicPreference,\n ObservableStoreCategory,\n PhotoCompression,\n PhotoSize,\n RgbLedAction,\n RgbLedColor,\n ScanModelOptions,\n ScanOptions,\n StreamKeepAliveRequest,\n StreamStartRequest,\n} from \"../BluetoothSdk.types\"\n\n/**\n * Private React Native native-module facade.\n *\n * This file intentionally lives under `_private` so the package root can expose\n * a small SDK surface while MentraOS uses its monorepo-only internal alias\n * during migration.\n */\n\ntype GlassesListener = (changed: Partial<GlassesStatus>) => void\ntype BluetoothStatusListener = (changed: Partial<BluetoothStatus>) => void\ntype MaybePromise<T> = T | Promise<T>\n\ndeclare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEvents> {\n // Observable Store Functions (native)\n getGlassesStatus(): Promise<GlassesStatus>\n getBluetoothStatus(): Promise<BluetoothStatus>\n getDefaultDevice(): Promise<Device | null>\n update(category: ObservableStoreCategory, values: object): Promise<void>\n\n // Display Commands\n displayEvent(params: Record<string, unknown>): Promise<void>\n displayText(text: string, x?: number, y?: number, size?: number): Promise<void>\n clearDisplay(): Promise<void>\n\n // Connection Commands\n requestStatus(): Promise<void>\n connectDefault(options?: ConnectOptions): Promise<void>\n connectDefaultWithOptions(options: Required<ConnectOptions>): Promise<void>\n setDefaultDevice(device: Device | null): Promise<void>\n clearDefaultDevice(): Promise<void>\n startScan(model: DeviceModel): Promise<void>\n stopScan(): Promise<void>\n scan(options: ScanOptions): Promise<Device[]>\n scan(model: DeviceModel, options?: ScanModelOptions): Promise<Device[]>\n connect(device: Device, options?: ConnectOptions): Promise<void>\n connectWithOptions(device: Device, options: Required<ConnectOptions>): Promise<void>\n cancelConnectionAttempt(): Promise<void>\n connectDefaultController(): Promise<void>\n disconnectController(): Promise<void>\n connectSimulated(): Promise<void>\n disconnect(): Promise<void>\n forget(): Promise<void>\n forgetController(): Promise<void>\n showDashboard(): Promise<void>\n setBrightness(level: number, autoMode?: boolean | null): Promise<void>\n setAutoBrightness(enabled: boolean): Promise<void>\n setDashboardPosition(height: number, depth: number): Promise<void>\n setDashboardMenu(items: DashboardMenuItem[]): Promise<void>\n setHeadUpAngle(angleDegrees: number): Promise<void>\n setScreenDisabled(disabled: boolean): Promise<void>\n ping(): Promise<void>\n dbg1(): Promise<void>\n dbg2(): Promise<void>\n\n // Incident Reporting\n sendIncidentId(incidentId: string, apiBaseUrl?: string | null): Promise<void>\n\n // WiFi Commands\n requestWifiScan(): Promise<void>\n sendWifiCredentials(ssid: string, password: string): Promise<void>\n forgetWifiNetwork(ssid: string): Promise<void>\n setHotspotState(enabled: boolean): Promise<void>\n /** Logs current WiFi frequency (MHz) and 5 GHz band to Android logcat. */\n logCurrentWifiFrequency(): Promise<void>\n\n // Gallery Commands\n setGalleryMode(mode: GalleryMode): Promise<void>\n setButtonPhotoSettings(size: ButtonPhotoSize): Promise<void>\n setButtonVideoRecordingSettings(width: number, height: number, frameRate: number): Promise<void>\n setButtonCameraLed(enabled: boolean): Promise<void>\n setButtonMaxRecordingTime(minutes: number): Promise<void>\n setCameraFov(fov: CameraFov): Promise<void>\n queryGalleryStatus(): Promise<void>\n requestPhoto(\n requestId: string,\n appId: string,\n size: PhotoSize,\n webhookUrl: string | null,\n authToken: string | null,\n compress: PhotoCompression,\n sound: boolean,\n ): Promise<void>\n\n // OTA Commands\n sendOtaStart(): Promise<void>\n sendOtaQueryStatus(): Promise<void>\n\n // Version Info Commands\n requestVersionInfo(): Promise<void>\n\n // Video Recording Commands\n startVideoRecording(requestId: string, save: boolean, sound: boolean): Promise<void>\n stopVideoRecording(requestId: string): Promise<void>\n\n // Stream Commands\n startStream(params: StreamStartRequest): Promise<void>\n stopStream(): Promise<void>\n keepStreamAlive(params: StreamKeepAliveRequest): Promise<void>\n\n // Microphone Commands\n setMicState(\n enabled: boolean,\n useGlassesMic?: boolean,\n bypassVad?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n ): Promise<void>\n setPreferredMic(preferredMic: MicPreference): Promise<void>\n restartTranscriber(): Promise<void>\n\n // Audio Playback Monitoring\n // Notify native side when our app starts/stops playing audio\n // Used to suspend LC3 mic during audio playback to avoid MCU overload\n setOwnAppAudioPlaying(playing: boolean): Promise<void>\n\n /** Mentra Live only: K900 `cs_getvol` / `sr_getvol`. */\n getGlassesMediaVolume(): Promise<GlassesMediaVolumeGetResult>\n /** Mentra Live only: K900 `cs_vol` / `sr_vol`; level clamped 0–15 on native. */\n setGlassesMediaVolume(level: number): Promise<GlassesMediaVolumeSetResult>\n\n // RGB LED Control\n rgbLedControl(\n requestId: string,\n packageName: string | null,\n action: RgbLedAction,\n color: RgbLedColor | null,\n onDurationMs: number,\n offDurationMs: number,\n count: number,\n ): Promise<void>\n\n // STT Commands\n setSttModelDetails(path: string, languageCode: string): Promise<void>\n getSttModelPath(): Promise<string>\n checkSttModelAvailable(): Promise<boolean>\n validateSttModel(path: string): Promise<boolean>\n extractTarBz2(sourcePath: string, destinationPath: string): Promise<boolean>\n\n // Helper methods for type-safe observable store access\n updateGlasses(values: Partial<GlassesStatus>): Promise<void>\n updateBluetoothSettings(values: BluetoothSettingsUpdate): Promise<void>\n onGlassesStatus(callback: GlassesListener): () => void\n onBluetoothStatus(callback: BluetoothStatusListener): () => void\n\n // Process resident-set-size in MB. iOS-only; Android stub returns 0.\n getMemoryMB(): number\n}\n\nexport type BluetoothSdkInternalModule = BluetoothSdkNativeModule\n\n// This call loads the native module object from the JSI.\n// NativeModule<BluetoothSdkModuleEvents> already extends EventEmitter<BluetoothSdkModuleEvents>\nconst NativeBluetoothSdkModule = requireNativeModule<BluetoothSdkNativeModule>(\"BluetoothSdk\")\n\nconst DEFAULT_CONNECT_OPTIONS: Required<ConnectOptions> = {\n saveAsDefault: true,\n cancelExistingConnectionAttempt: true,\n}\n\nconst DEFAULT_SCAN_TIMEOUT_MS = 15_000\n\nconst CAMERA_FOV_SETTINGS: Record<CameraFov, CameraFovSetting> = {\n standard: {fov: 118, roiPosition: 0},\n wide: {fov: 118, roiPosition: 0},\n}\n\nfunction searchResultsForModel(status: Partial<BluetoothStatus>, model: DeviceModel): Device[] {\n return status.searchResults?.filter((device) => device.model === model) ?? []\n}\n\nfunction normalizeScanArgs(modelOrOptions: DeviceModel | ScanOptions, options?: ScanModelOptions): ScanOptions {\n if (typeof modelOrOptions === \"string\") {\n return {model: modelOrOptions, ...options}\n }\n return modelOrOptions\n}\n\nfunction normalizeTimeoutMs(timeoutMs: number | undefined, defaultTimeoutMs: number): number {\n return typeof timeoutMs === \"number\" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : defaultTimeoutMs\n}\n\nfunction dashboardMenuItemToNative(item: DashboardMenuItem): Record<string, unknown> {\n return {\n ...(item.values ?? {}),\n title: item.title,\n packageName: item.packageName,\n }\n}\n\nfunction adaptConnectionStatusToNative(connection: GlassesStatus[\"connection\"]): Record<string, unknown> {\n switch (connection.state) {\n case \"connected\":\n return {connectionState: \"CONNECTED\", connected: true, fullyBooted: connection.fullyBooted}\n case \"scanning\":\n return {connectionState: \"SCANNING\", connected: false, fullyBooted: false}\n case \"connecting\":\n return {connectionState: \"CONNECTING\", connected: false, fullyBooted: false}\n case \"bonding\":\n return {connectionState: \"BONDING\", connected: false, fullyBooted: false}\n case \"disconnected\":\n return {connectionState: \"DISCONNECTED\", connected: false, fullyBooted: false}\n }\n}\n\nfunction adaptGlassesUpdateToNative(values: Partial<GlassesStatus>): Record<string, unknown> {\n const {wifi, hotspot, connection, ...rest} = values\n let update: Record<string, unknown> = {...rest}\n if (connection) {\n update = {\n ...update,\n ...adaptConnectionStatusToNative(connection),\n }\n }\n if (wifi?.state === \"connected\") {\n update = {\n ...update,\n wifiConnected: true,\n wifiSsid: wifi.ssid,\n wifiLocalIp: wifi.localIp ?? \"\",\n }\n } else if (wifi?.state === \"disconnected\") {\n update = {\n ...update,\n wifiConnected: false,\n wifiSsid: \"\",\n wifiLocalIp: \"\",\n }\n }\n if (hotspot?.state === \"enabled\") {\n update = {\n ...update,\n hotspotEnabled: true,\n hotspotSsid: hotspot.ssid,\n hotspotPassword: hotspot.password,\n hotspotGatewayIp: hotspot.localIp,\n }\n } else if (hotspot?.state === \"disabled\") {\n update = {\n ...update,\n hotspotEnabled: false,\n hotspotSsid: \"\",\n hotspotPassword: \"\",\n hotspotGatewayIp: \"\",\n }\n }\n return update\n}\n\n// Add helper methods to the module\nconst nativeGetGlassesStatus = NativeBluetoothSdkModule.getGlassesStatus.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<GlassesStatus>\nNativeBluetoothSdkModule.getGlassesStatus = function () {\n return Promise.resolve(nativeGetGlassesStatus())\n}\n\nconst nativeGetBluetoothStatus = NativeBluetoothSdkModule.getBluetoothStatus.bind(NativeBluetoothSdkModule) as () => MaybePromise<BluetoothStatus>\nNativeBluetoothSdkModule.getBluetoothStatus = function () {\n return Promise.resolve(nativeGetBluetoothStatus())\n}\n\nconst nativeGetDefaultDevice = NativeBluetoothSdkModule.getDefaultDevice.bind(\n NativeBluetoothSdkModule,\n) as () => MaybePromise<Device | null>\nNativeBluetoothSdkModule.getDefaultDevice = function () {\n return Promise.resolve(nativeGetDefaultDevice())\n}\n\nconst nativeSetMicState = NativeBluetoothSdkModule.setMicState.bind(NativeBluetoothSdkModule) as (\n enabled: boolean,\n useGlassesMic: boolean,\n bypassVad: boolean,\n sendTranscript: boolean,\n sendLc3Data: boolean,\n) => MaybePromise<void>\n\nconst nativeDisplayText = NativeBluetoothSdkModule.displayText.bind(NativeBluetoothSdkModule) as (\n text: string,\n x: number,\n y: number,\n size: number,\n) => MaybePromise<void>\n\nNativeBluetoothSdkModule.updateGlasses = function (values: Partial<GlassesStatus>) {\n return this.update(\"glasses\", adaptGlassesUpdateToNative(values))\n}\n\nNativeBluetoothSdkModule.updateBluetoothSettings = function (values: BluetoothSettingsUpdate) {\n return this.update(\"bluetooth\", values)\n}\n\nNativeBluetoothSdkModule.displayText = function (text: string, x?: number, y?: number, size?: number) {\n return Promise.resolve(nativeDisplayText(text, x ?? 0, y ?? 0, size ?? 24))\n}\n\nNativeBluetoothSdkModule.setBrightness = function (level: number, autoMode?: boolean | null) {\n return this.updateBluetoothSettings({\n ...(autoMode == null ? {} : {auto_brightness: autoMode}),\n brightness: level,\n })\n}\n\nNativeBluetoothSdkModule.setAutoBrightness = function (enabled: boolean) {\n return this.updateBluetoothSettings({auto_brightness: enabled})\n}\n\nNativeBluetoothSdkModule.setDashboardPosition = function (height: number, depth: number) {\n return this.updateBluetoothSettings({\n dashboard_height: height,\n dashboard_depth: depth,\n })\n}\n\nNativeBluetoothSdkModule.setDashboardMenu = function (items: DashboardMenuItem[]) {\n return this.updateBluetoothSettings({menu_apps: items.map(dashboardMenuItemToNative)})\n}\n\nNativeBluetoothSdkModule.setHeadUpAngle = function (angleDegrees: number) {\n return this.updateBluetoothSettings({head_up_angle: angleDegrees})\n}\n\nNativeBluetoothSdkModule.setScreenDisabled = function (disabled: boolean) {\n return this.updateBluetoothSettings({screen_disabled: disabled})\n}\n\nNativeBluetoothSdkModule.setButtonPhotoSettings = function (size: ButtonPhotoSize) {\n return this.updateBluetoothSettings({button_photo_size: size})\n}\n\nNativeBluetoothSdkModule.setButtonVideoRecordingSettings = function (width: number, height: number, frameRate: number) {\n return this.updateBluetoothSettings({\n button_video_width: width,\n button_video_height: height,\n button_video_fps: frameRate,\n })\n}\n\nNativeBluetoothSdkModule.setButtonCameraLed = function (enabled: boolean) {\n return this.updateBluetoothSettings({button_camera_led: enabled})\n}\n\nNativeBluetoothSdkModule.setButtonMaxRecordingTime = function (minutes: number) {\n return this.updateBluetoothSettings({button_max_recording_time: minutes})\n}\n\nNativeBluetoothSdkModule.setCameraFov = function (fov: CameraFov) {\n return this.updateBluetoothSettings({camera_fov: CAMERA_FOV_SETTINGS[fov]})\n}\n\nNativeBluetoothSdkModule.setMicState = function (\n enabled: boolean,\n useGlassesMic?: boolean,\n bypassVad?: boolean,\n sendTranscript?: boolean,\n sendLc3Data?: boolean,\n) {\n return Promise.resolve(\n nativeSetMicState(\n enabled,\n useGlassesMic ?? true,\n bypassVad ?? false,\n sendTranscript ?? false,\n sendLc3Data ?? false,\n ),\n )\n}\n\nNativeBluetoothSdkModule.setPreferredMic = function (preferredMic: MicPreference) {\n return this.updateBluetoothSettings({preferred_mic: preferredMic})\n}\n\nNativeBluetoothSdkModule.onGlassesStatus = function (callback: GlassesListener) {\n const subscription = this.addListener(\"glasses_status\", callback)\n return () => subscription.remove()\n}\n\nNativeBluetoothSdkModule.onBluetoothStatus = function (callback: BluetoothStatusListener) {\n const subscription = this.addListener(\"bluetooth_status\", callback)\n return () => subscription.remove()\n}\n\nconst nativeConnectDefault = NativeBluetoothSdkModule.connectDefault.bind(NativeBluetoothSdkModule)\nNativeBluetoothSdkModule.connectDefault = function (options?: ConnectOptions) {\n if (!options) {\n return nativeConnectDefault()\n }\n return this.connectDefaultWithOptions({...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nNativeBluetoothSdkModule.connect = function (device: Device, options?: ConnectOptions) {\n return this.connectWithOptions(device, {...DEFAULT_CONNECT_OPTIONS, ...options})\n}\n\nNativeBluetoothSdkModule.scan = async function (\n modelOrOptions: DeviceModel | ScanOptions,\n options?: ScanModelOptions,\n) {\n const scanOptions = normalizeScanArgs(modelOrOptions, options)\n const timeoutMs = normalizeTimeoutMs(scanOptions.timeoutMs ?? scanOptions.timeout, DEFAULT_SCAN_TIMEOUT_MS)\n let latestResults: Device[] = []\n\n return new Promise<Device[]>((resolve, reject) => {\n let timeout: ReturnType<typeof setTimeout> | null = null\n let removeBluetoothListener = () => {}\n let settled = false\n let scanStarted = false\n\n const emitResults = (devices: Device[]) => {\n latestResults = devices\n scanOptions.onResults?.([...devices])\n }\n\n const cleanup = () => {\n if (timeout) {\n clearTimeout(timeout)\n }\n removeBluetoothListener()\n if (scanStarted) {\n void Promise.resolve(this.stopScan()).catch(() => undefined)\n }\n }\n\n const settle = (error?: Error) => {\n if (settled) {\n return\n }\n settled = true\n cleanup()\n if (error) {\n reject(error)\n } else {\n resolve([...latestResults])\n }\n }\n\n const handleBluetoothStatus = (status: Partial<BluetoothStatus>) => {\n emitResults(searchResultsForModel(status, scanOptions.model))\n }\n\n removeBluetoothListener = this.onBluetoothStatus(handleBluetoothStatus)\n emitResults([])\n\n timeout = setTimeout(() => settle(), timeoutMs)\n\n Promise.resolve(this.startScan(scanOptions.model))\n .then(() => {\n scanStarted = true\n return this.getBluetoothStatus()\n })\n .then(handleBluetoothStatus)\n .catch((error) => settle(error instanceof Error ? error : new Error(String(error))))\n })\n}\n\nexport default NativeBluetoothSdkModule\nexport const BluetoothSdk = NativeBluetoothSdkModule as BluetoothSdkPublicModule\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import { BluetoothSdk } from "./_private/BluetoothSdkModule";
|
|
2
|
+
export default BluetoothSdk;
|
|
3
|
+
export { DeviceModels, createDisconnectedGlassesStatus, isBusyGlassesConnectionStatus, isConnectedGlassesConnectionStatus, isConnectedWifiStatus, isEnabledHotspotStatus, isReadyGlassesConnectionStatus, } from "./BluetoothSdk.types";
|
|
4
|
+
export type { AudioConnectedEvent, AudioDisconnectedEvent, AudioPairingNeededEvent, BatteryStatusEvent, BluetoothSdkEvent, BluetoothSdkEventListener, BluetoothSdkEventMap, BluetoothSdkEventName, BluetoothSdkPublicModule as BluetoothSdkModule, BluetoothSdkSubscription, ButtonPhotoSize, ButtonPressEvent, CameraFov, CompatibleGlassesSearchStopEvent, ConnectOptions, ConnectedGlassesConnectionStatus, ConnectedWifiStatus, Device, DeviceModel, EnabledHotspotStatus, GalleryMode, GalleryStatusEvent, GlassesConnectionStatus, GlassesMediaVolumeGetResult, GlassesMediaVolumeSetResult, GlassesNotReadyEvent, HeadUpEvent, HotspotErrorEvent, HotspotStatus, HotspotStatusChangeEvent, KeepAliveAckEvent, LocalTranscriptionEvent, LogEvent, MicLc3Event, MicMode, MicPcmEvent, MicPreference, PairFailureEvent, PhotoCompression, PhotoResponseEvent, PhotoSize, PublicBluetoothStatus as BluetoothStatus, PublicGlassesStatus as GlassesStatus, RgbLedAction, RgbLedColor, RgbLedControlResponseEvent, ScanModelOptions, ScanOptions, ScanResultsCallback, StreamAudioConfig, StreamKeepAliveRequest, StreamStartRequest, StreamStatusEvent, StreamStatusLifecycleState, StreamStatusReconnectState, StreamStatusState, StreamVideoConfig, SwipeVolumeStatusEvent, SwitchStatusEvent, TouchEvent, VadStatusEvent, WifiSearchResult, WifiStatus, WifiStatusChangeEvent, } from "./BluetoothSdk.types";
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,+BAA+B,CAAA;AAE1D,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,YAAY,EACZ,+BAA+B,EAC/B,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,IAAI,kBAAkB,EAC9C,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,SAAS,EACT,gCAAgC,EAChC,cAAc,EACd,gCAAgC,EAChC,mBAAmB,EACnB,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,iBAAiB,EACjB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,OAAO,EACP,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,EACT,qBAAqB,IAAI,eAAe,EACxC,mBAAmB,IAAI,aAAa,EACpC,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,gBAAgB,EAChB,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,sBAAsB,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export {
|
|
4
|
-
export * from "./BluetoothSdk.types";
|
|
1
|
+
import { BluetoothSdk } from "./_private/BluetoothSdkModule";
|
|
2
|
+
export default BluetoothSdk;
|
|
3
|
+
export { DeviceModels, createDisconnectedGlassesStatus, isBusyGlassesConnectionStatus, isConnectedGlassesConnectionStatus, isConnectedWifiStatus, isEnabledHotspotStatus, isReadyGlassesConnectionStatus, } from "./BluetoothSdk.types";
|
|
5
4
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,+BAA+B,CAAA;AAE1D,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,YAAY,EACZ,+BAA+B,EAC/B,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA","sourcesContent":["import {BluetoothSdk} from \"./_private/BluetoothSdkModule\"\n\nexport default BluetoothSdk\n\nexport {\n DeviceModels,\n createDisconnectedGlassesStatus,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\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 ButtonPressEvent,\n CameraFov,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryMode,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n KeepAliveAckEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicMode,\n MicPcmEvent,\n MicPreference,\n PairFailureEvent,\n PhotoCompression,\n PhotoResponseEvent,\n PhotoSize,\n PublicBluetoothStatus as BluetoothStatus,\n PublicGlassesStatus as GlassesStatus,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n ScanModelOptions,\n ScanOptions,\n ScanResultsCallback,\n StreamAudioConfig,\n StreamKeepAliveRequest,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VadStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n"]}
|
|
@@ -193,6 +193,12 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
AsyncFunction("stopScan") {
|
|
197
|
+
await MainActor.run {
|
|
198
|
+
self.bluetoothSdk().stopScan()
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
196
202
|
AsyncFunction("cancelConnectionAttempt") {
|
|
197
203
|
await MainActor.run {
|
|
198
204
|
self.bluetoothSdk().cancelConnectionAttempt()
|
|
@@ -308,10 +314,10 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
308
314
|
}
|
|
309
315
|
}
|
|
310
316
|
|
|
311
|
-
AsyncFunction("
|
|
317
|
+
AsyncFunction("requestPhoto") {
|
|
312
318
|
(
|
|
313
319
|
requestId: String, appId: String, size: String, webhookUrl: String?,
|
|
314
|
-
authToken: String?, compress: String?,
|
|
320
|
+
authToken: String?, compress: String?, sound: Bool
|
|
315
321
|
) in
|
|
316
322
|
await MainActor.run {
|
|
317
323
|
self.bluetoothSdk().requestPhoto(
|
|
@@ -322,7 +328,6 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
322
328
|
webhookUrl: webhookUrl,
|
|
323
329
|
authToken: authToken,
|
|
324
330
|
compress: compress.flatMap(PhotoCompression.init(rawValue:)),
|
|
325
|
-
flash: flash,
|
|
326
331
|
sound: sound
|
|
327
332
|
)
|
|
328
333
|
)
|
|
@@ -367,10 +372,10 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
367
372
|
|
|
368
373
|
// MARK: - Video Recording Commands
|
|
369
374
|
|
|
370
|
-
AsyncFunction("startVideoRecording") { (requestId: String, save: Bool,
|
|
375
|
+
AsyncFunction("startVideoRecording") { (requestId: String, save: Bool, sound: Bool) in
|
|
371
376
|
await MainActor.run {
|
|
372
377
|
self.bluetoothSdk().startVideoRecording(
|
|
373
|
-
VideoRecordingRequest(requestId: requestId, save: save,
|
|
378
|
+
VideoRecordingRequest(requestId: requestId, save: save, sound: sound)
|
|
374
379
|
)
|
|
375
380
|
}
|
|
376
381
|
}
|
|
@@ -422,7 +427,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
422
427
|
AsyncFunction("rgbLedControl") {
|
|
423
428
|
(
|
|
424
429
|
requestId: String, packageName: String?, action: String, color: String?,
|
|
425
|
-
|
|
430
|
+
onDurationMs: Int, offDurationMs: Int, count: Int
|
|
426
431
|
) in
|
|
427
432
|
await MainActor.run {
|
|
428
433
|
self.bluetoothSdk().rgbLedControl(
|
|
@@ -431,8 +436,8 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
431
436
|
packageName: packageName,
|
|
432
437
|
action: RgbLedAction(rawValue: action) ?? .off,
|
|
433
438
|
color: color.flatMap(RgbLedColor.init(rawValue:)),
|
|
434
|
-
|
|
435
|
-
|
|
439
|
+
onDurationMs: onDurationMs,
|
|
440
|
+
offDurationMs: offDurationMs,
|
|
436
441
|
count: count
|
|
437
442
|
)
|
|
438
443
|
)
|
|
@@ -545,7 +550,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
|
|
|
545
550
|
"compatible_glasses_search_stop",
|
|
546
551
|
[
|
|
547
552
|
"type": "compatible_glasses_search_stop",
|
|
548
|
-
"
|
|
553
|
+
"deviceModel": deviceModel,
|
|
549
554
|
]
|
|
550
555
|
)
|
|
551
556
|
}
|
package/ios/Source/Bridge.swift
CHANGED
|
@@ -126,18 +126,48 @@ class Bridge {
|
|
|
126
126
|
if let rssi {
|
|
127
127
|
newResult["rssi"] = rssi
|
|
128
128
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
let uniqueResults =
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
DeviceStore.shared.set("bluetooth", "searchResults",
|
|
129
|
+
// Keep the public searchResults array stable as glasses are added or removed.
|
|
130
|
+
// Duplicate discoveries refresh their existing row; only new glasses append.
|
|
131
|
+
let uniqueResults = mergeStableSearchResults(
|
|
132
|
+
searchResults,
|
|
133
|
+
newResult: newResult,
|
|
134
|
+
fallbackModel: deviceModel
|
|
135
|
+
)
|
|
136
|
+
DeviceStore.shared.set("bluetooth", "searchResults", uniqueResults)
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
private static func mergeStableSearchResults(
|
|
142
|
+
_ currentResults: [[String: Any]],
|
|
143
|
+
newResult: [String: Any],
|
|
144
|
+
fallbackModel: String
|
|
145
|
+
) -> [[String: Any]] {
|
|
146
|
+
guard let newKey = searchResultKey(newResult, fallbackModel: fallbackModel) else {
|
|
147
|
+
return currentResults
|
|
148
|
+
}
|
|
149
|
+
var nextResults = currentResults
|
|
150
|
+
if let existingIndex = nextResults.firstIndex(where: {
|
|
151
|
+
searchResultKey($0, fallbackModel: fallbackModel) == newKey
|
|
152
|
+
}) {
|
|
153
|
+
nextResults[existingIndex] = newResult
|
|
154
|
+
} else {
|
|
155
|
+
nextResults.append(newResult)
|
|
156
|
+
}
|
|
157
|
+
return nextResults
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private static func searchResultKey(_ result: [String: Any], fallbackModel: String) -> String? {
|
|
161
|
+
if let id = result["id"] as? String, !id.isEmpty {
|
|
162
|
+
return id
|
|
163
|
+
}
|
|
164
|
+
let model = result["model"] as? String ?? fallbackModel
|
|
165
|
+
guard let name = result["name"] as? String else {
|
|
166
|
+
return nil
|
|
167
|
+
}
|
|
168
|
+
return "\(model):\(name)"
|
|
169
|
+
}
|
|
170
|
+
|
|
141
171
|
// MARK: - Hardware Events
|
|
142
172
|
|
|
143
173
|
static func sendButtonPress(buttonId: String, pressType: String) {
|
|
@@ -153,8 +183,9 @@ class Bridge {
|
|
|
153
183
|
|
|
154
184
|
static func sendTouchEvent(deviceModel: String, gestureName: String, timestamp: Int64, source: Int32? = nil) {
|
|
155
185
|
var body: [String: Any] = [
|
|
156
|
-
"
|
|
157
|
-
"
|
|
186
|
+
"type": "touch_event",
|
|
187
|
+
"deviceModel": deviceModel,
|
|
188
|
+
"gestureName": gestureName,
|
|
158
189
|
"timestamp": timestamp,
|
|
159
190
|
]
|
|
160
191
|
if let source {
|
|
@@ -173,8 +204,8 @@ class Bridge {
|
|
|
173
204
|
|
|
174
205
|
static func sendSwitchStatus(switchType: Int, value: Int, timestamp: Int64) {
|
|
175
206
|
let body: [String: Any] = [
|
|
176
|
-
"
|
|
177
|
-
"
|
|
207
|
+
"switchType": switchType,
|
|
208
|
+
"switchValue": value,
|
|
178
209
|
"timestamp": timestamp,
|
|
179
210
|
]
|
|
180
211
|
Bridge.sendTypedMessage("switch_status", body: body)
|
|
@@ -183,6 +214,7 @@ class Bridge {
|
|
|
183
214
|
static func sendRgbLedControlResponse(requestId: String, success: Bool, error: String?) {
|
|
184
215
|
guard !requestId.isEmpty else { return }
|
|
185
216
|
var body: [String: Any] = [
|
|
217
|
+
"type": "rgb_led_control_response",
|
|
186
218
|
"requestId": requestId,
|
|
187
219
|
"state": success ? "success" : "error",
|
|
188
220
|
]
|
|
@@ -66,9 +66,9 @@ struct ViewState {
|
|
|
66
66
|
if isPaired {
|
|
67
67
|
// Device is paired! Don't activate it - let PhoneMic.swift activate when recording starts
|
|
68
68
|
Bridge.log("Audio: ✅ Mentra Live is paired (preserving A2DP for music)")
|
|
69
|
-
|
|
69
|
+
glassesBluetoothClassicConnected = true
|
|
70
70
|
} else {
|
|
71
|
-
|
|
71
|
+
glassesBluetoothClassicConnected = false
|
|
72
72
|
// Not found in availableInputs - not paired yet
|
|
73
73
|
|
|
74
74
|
// Start monitoring for when user pairs manually
|
|
@@ -79,10 +79,10 @@ struct ViewState {
|
|
|
79
79
|
if connected {
|
|
80
80
|
Bridge.log("Audio: ✅ Device paired and connected")
|
|
81
81
|
// Don't activate - let PhoneMic.swift handle that when recording starts
|
|
82
|
-
self.
|
|
82
|
+
self.glassesBluetoothClassicConnected = true
|
|
83
83
|
} else {
|
|
84
84
|
Bridge.log("Audio: Device disconnected")
|
|
85
|
-
self.
|
|
85
|
+
self.glassesBluetoothClassicConnected = false
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
}
|
|
@@ -214,9 +214,9 @@ struct ViewState {
|
|
|
214
214
|
set { DeviceStore.shared.apply("bluetooth", "searchingController", newValue) }
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
private var
|
|
218
|
-
get { DeviceStore.shared.get("glasses", "
|
|
219
|
-
set { DeviceStore.shared.apply("glasses", "
|
|
217
|
+
private var glassesBluetoothClassicConnected: Bool {
|
|
218
|
+
get { DeviceStore.shared.get("glasses", "bluetoothClassicConnected") as? Bool ?? false }
|
|
219
|
+
set { DeviceStore.shared.apply("glasses", "bluetoothClassicConnected", newValue) }
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
private var micRanking: [String] {
|
|
@@ -506,8 +506,8 @@ struct ViewState {
|
|
|
506
506
|
|
|
507
507
|
if micEnabled {
|
|
508
508
|
for micMode in micRanking {
|
|
509
|
-
if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.
|
|
510
|
-
|| micMode == MicTypes.
|
|
509
|
+
if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.BLUETOOTH_CLASSIC
|
|
510
|
+
|| micMode == MicTypes.BLUETOOTH
|
|
511
511
|
{
|
|
512
512
|
if PhoneMic.shared.isRecordingWithMode(micMode) {
|
|
513
513
|
micUsed = micMode
|
|
@@ -572,8 +572,8 @@ struct ViewState {
|
|
|
572
572
|
continue
|
|
573
573
|
}
|
|
574
574
|
|
|
575
|
-
if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.
|
|
576
|
-
|| micMode == MicTypes.
|
|
575
|
+
if micMode == MicTypes.PHONE_INTERNAL || micMode == MicTypes.BLUETOOTH_CLASSIC
|
|
576
|
+
|| micMode == MicTypes.BLUETOOTH
|
|
577
577
|
{
|
|
578
578
|
PhoneMic.shared.stopMode(micMode)
|
|
579
579
|
}
|
|
@@ -849,7 +849,7 @@ struct ViewState {
|
|
|
849
849
|
Bridge.log("MAN: checkCurrentAudioDevice: audioDevicePattern: \(audioDevicePattern)")
|
|
850
850
|
|
|
851
851
|
if audioDevicePattern.isEmpty || audioDevicePattern == DeviceTypes.SIMULATED {
|
|
852
|
-
|
|
852
|
+
glassesBluetoothClassicConnected = false
|
|
853
853
|
Bridge.log("MAN: Audio device pattern is empty or simulated, returning")
|
|
854
854
|
return
|
|
855
855
|
}
|
|
@@ -861,7 +861,7 @@ struct ViewState {
|
|
|
861
861
|
|
|
862
862
|
if !isConnected {
|
|
863
863
|
Bridge.log("MAN: Device '\(deviceName)' disconnected")
|
|
864
|
-
|
|
864
|
+
glassesBluetoothClassicConnected = false
|
|
865
865
|
|
|
866
866
|
let isOtherDeviceConnected = AudioSessionMonitor.isOtherAudioDeviceConnected(
|
|
867
867
|
devicePattern: audioDevicePattern
|
|
@@ -880,9 +880,9 @@ struct ViewState {
|
|
|
880
880
|
$0.portName.localizedCaseInsensitiveContains(audioDevicePattern)
|
|
881
881
|
})?.portName
|
|
882
882
|
Bridge.log("MAN: ✅ Successfully detected newly paired device '\(deviceName)'")
|
|
883
|
-
|
|
883
|
+
glassesBluetoothClassicConnected = true
|
|
884
884
|
} else {
|
|
885
|
-
|
|
885
|
+
glassesBluetoothClassicConnected = false
|
|
886
886
|
}
|
|
887
887
|
}
|
|
888
888
|
|
|
@@ -1120,6 +1120,8 @@ struct ViewState {
|
|
|
1120
1120
|
func dbg2() {}
|
|
1121
1121
|
|
|
1122
1122
|
func startStream(_ message: [String: Any]) {
|
|
1123
|
+
var message = message
|
|
1124
|
+
message["flash"] = true
|
|
1123
1125
|
Bridge.log("MAN: startStream: \(message)")
|
|
1124
1126
|
sgc?.startStream(message)
|
|
1125
1127
|
}
|
|
@@ -1199,11 +1201,11 @@ struct ViewState {
|
|
|
1199
1201
|
sgc?.sendReboot()
|
|
1200
1202
|
}
|
|
1201
1203
|
|
|
1202
|
-
func startVideoRecording(_ requestId: String, _ save: Bool, _
|
|
1204
|
+
func startVideoRecording(_ requestId: String, _ save: Bool, _ sound: Bool) {
|
|
1203
1205
|
Bridge.log(
|
|
1204
|
-
"MAN: onStartVideoRecording: requestId=\(requestId), save=\(save), flash
|
|
1206
|
+
"MAN: onStartVideoRecording: requestId=\(requestId), save=\(save), flash=true, sound=\(sound)"
|
|
1205
1207
|
)
|
|
1206
|
-
sgc?.startVideoRecording(requestId: requestId, save: save, flash:
|
|
1208
|
+
sgc?.startVideoRecording(requestId: requestId, save: save, flash: true, sound: sound)
|
|
1207
1209
|
}
|
|
1208
1210
|
|
|
1209
1211
|
func stopVideoRecording(_ requestId: String) {
|
|
@@ -1223,8 +1225,8 @@ struct ViewState {
|
|
|
1223
1225
|
packageName: String?,
|
|
1224
1226
|
action: String,
|
|
1225
1227
|
color: String?,
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
+
onDurationMs: Int,
|
|
1229
|
+
offDurationMs: Int,
|
|
1228
1230
|
count: Int
|
|
1229
1231
|
) {
|
|
1230
1232
|
sgc?.sendRgbLedControl(
|
|
@@ -1232,8 +1234,8 @@ struct ViewState {
|
|
|
1232
1234
|
packageName: packageName,
|
|
1233
1235
|
action: action,
|
|
1234
1236
|
color: color,
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
+
onDurationMs: onDurationMs,
|
|
1238
|
+
offDurationMs: offDurationMs,
|
|
1237
1239
|
count: count
|
|
1238
1240
|
)
|
|
1239
1241
|
}
|
|
@@ -1272,22 +1274,21 @@ struct ViewState {
|
|
|
1272
1274
|
}
|
|
1273
1275
|
}
|
|
1274
1276
|
|
|
1275
|
-
func
|
|
1277
|
+
func requestPhoto(
|
|
1276
1278
|
_ requestId: String,
|
|
1277
1279
|
_ appId: String,
|
|
1278
1280
|
_ size: String,
|
|
1279
1281
|
_ webhookUrl: String?,
|
|
1280
1282
|
_ authToken: String?,
|
|
1281
1283
|
_ compress: String?,
|
|
1282
|
-
_ flash: Bool,
|
|
1283
1284
|
_ sound: Bool
|
|
1284
1285
|
) {
|
|
1285
1286
|
Bridge.log(
|
|
1286
|
-
"MAN:
|
|
1287
|
+
"MAN: requestPhoto: \(requestId), \(appId), \(webhookUrl), size=\(size), compress=\(compress ?? "none"), flash=true, sound=\(sound)"
|
|
1287
1288
|
)
|
|
1288
1289
|
sgc?.requestPhoto(
|
|
1289
1290
|
requestId, appId: appId, size: size, webhookUrl: webhookUrl, authToken: authToken,
|
|
1290
|
-
compress: compress, flash:
|
|
1291
|
+
compress: compress, flash: true, sound: sound
|
|
1291
1292
|
)
|
|
1292
1293
|
}
|
|
1293
1294
|
|
|
@@ -28,7 +28,7 @@ class DeviceStore {
|
|
|
28
28
|
store.set("glasses", "deviceModel", "")
|
|
29
29
|
store.set("glasses", "firmwareVersion", "")
|
|
30
30
|
store.set("glasses", "micEnabled", false)
|
|
31
|
-
store.set("glasses", "
|
|
31
|
+
store.set("glasses", "bluetoothClassicConnected", false)
|
|
32
32
|
store.set("glasses", "caseRemoved", true)
|
|
33
33
|
store.set("glasses", "caseOpen", true)
|
|
34
34
|
store.set("glasses", "caseCharging", false)
|
|
@@ -80,12 +80,12 @@ class DeviceStore {
|
|
|
80
80
|
store.set("bluetooth", "dashboard_depth", 2)
|
|
81
81
|
store.set("bluetooth", "head_up_angle", 30)
|
|
82
82
|
store.set("bluetooth", "contextual_dashboard", true)
|
|
83
|
-
store.set("bluetooth", "
|
|
83
|
+
store.set("bluetooth", "galleryModeAuto", true)
|
|
84
84
|
store.set("bluetooth", "screen_disabled", false)
|
|
85
85
|
store.set("bluetooth", "button_photo_size", "medium")
|
|
86
86
|
store.set("bluetooth", "button_camera_led", true)
|
|
87
87
|
store.set("bluetooth", "button_max_recording_time", 10)
|
|
88
|
-
store.set("bluetooth", "camera_fov", ["fov": 118, "
|
|
88
|
+
store.set("bluetooth", "camera_fov", ["fov": 118, "roiPosition": 0])
|
|
89
89
|
store.set("bluetooth", "button_video_width", 1280)
|
|
90
90
|
store.set("bluetooth", "button_video_height", 720)
|
|
91
91
|
store.set("bluetooth", "button_video_fps", 30)
|
|
@@ -214,7 +214,7 @@ class DeviceStore {
|
|
|
214
214
|
DeviceManager.shared.sgc?.setDashboardMenu(items)
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
case ("bluetooth", "
|
|
217
|
+
case ("bluetooth", "galleryModeAuto"):
|
|
218
218
|
DeviceManager.shared.sgc?.sendGalleryMode()
|
|
219
219
|
|
|
220
220
|
case ("bluetooth", "screen_disabled"):
|