@mentra/bluetooth-sdk 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -11
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkAnalytics.kt +182 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +73 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +10 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +83 -26
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +1 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +266 -31
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdkDebug.kt +14 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/ObservableStore.kt +20 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/OtaManifest.kt +153 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +93 -10
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +3 -14
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +3 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +1 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +90 -4
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.kt +3835 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +20 -23
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/{Mach1.java → Mach1.kt} +517 -560
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +8712 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +11 -1
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +15 -13
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +7 -14
- package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +2 -1
- package/build/BluetoothSdk.types.d.ts +72 -10
- package/build/BluetoothSdk.types.d.ts.map +1 -1
- package/build/BluetoothSdk.types.js.map +1 -1
- package/build/_private/BluetoothSdkModule.d.ts +9 -7
- package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
- package/build/_private/BluetoothSdkModule.js +0 -2
- package/build/_private/BluetoothSdkModule.js.map +1 -1
- package/build/_private/photoRequestPayload.d.ts +3 -1
- package/build/_private/photoRequestPayload.d.ts.map +1 -1
- package/build/_private/photoRequestPayload.js +43 -1
- package/build/_private/photoRequestPayload.js.map +1 -1
- package/build/debug.d.ts +3 -0
- package/build/debug.d.ts.map +1 -0
- package/build/debug.js +8 -0
- package/build/debug.js.map +1 -0
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +16 -5
- package/build/index.js.map +1 -1
- package/ios/BluetoothSdkModule.swift +59 -64
- package/ios/Source/BluetoothSdkDefaults.swift +47 -0
- package/ios/Source/Bridge.swift +6 -0
- package/ios/Source/DeviceManager.swift +46 -32
- package/ios/Source/DeviceStore.swift +5 -1
- package/ios/Source/MentraBluetoothSDK.swift +357 -34
- package/ios/Source/MentraBluetoothSDKDebug.swift +12 -0
- package/ios/Source/ObservableStore.swift +11 -0
- package/ios/Source/OtaManifest.swift +170 -0
- package/ios/Source/camera/CameraModels.swift +267 -9
- package/ios/Source/controllers/ControllerManager.swift +2 -5
- package/ios/Source/controllers/R1.swift +2 -5
- package/ios/Source/events/BluetoothEvents.swift +3 -0
- package/ios/Source/internal/BluetoothAvailability.swift +20 -0
- package/ios/Source/internal/BluetoothSdkAnalytics.swift +160 -0
- package/ios/Source/sgcs/G1.swift +6 -5
- package/ios/Source/sgcs/G2.swift +20 -18
- package/ios/Source/sgcs/Mach1.swift +6 -5
- package/ios/Source/sgcs/MentraLive.swift +158 -38
- package/ios/Source/sgcs/MentraNex.swift +6 -5
- package/ios/Source/sgcs/SGCManager.swift +16 -7
- package/ios/Source/sgcs/Simulated.swift +7 -3
- package/ios/Source/status/DeviceStatus.swift +1 -1
- package/ios/Source/types/DeviceModels.swift +5 -1
- package/package.json +6 -1
- package/plugin/build/index.d.ts +4 -0
- package/plugin/build/withAndroid.d.ts +2 -3
- package/plugin/build/withAndroid.js +46 -0
- package/plugin/build/withIos.d.ts +2 -3
- package/plugin/build/withIos.js +32 -0
- package/src/BluetoothSdk.types.ts +80 -10
- package/src/_private/BluetoothSdkModule.ts +13 -10
- package/src/_private/photoRequestPayload.ts +45 -2
- package/src/debug.ts +9 -0
- package/src/index.ts +25 -6
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +0 -3974
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +0 -7405
|
@@ -18,10 +18,7 @@ protocol SGCManager {
|
|
|
18
18
|
|
|
19
19
|
// MARK: - Camera & Media
|
|
20
20
|
|
|
21
|
-
func requestPhoto(
|
|
22
|
-
_ requestId: String, appId: String, size: String?, webhookUrl: String?, authToken: String?,
|
|
23
|
-
compress: String?, flash: Bool, save: Bool, sound: Bool, exposureTimeNs: Double?, iso: Int?
|
|
24
|
-
)
|
|
21
|
+
func requestPhoto(_ request: PhotoRequest)
|
|
25
22
|
func startStream(_ message: [String: Any])
|
|
26
23
|
func stopStream()
|
|
27
24
|
func sendStreamKeepAlive(_ message: [String: Any])
|
|
@@ -31,9 +28,16 @@ protocol SGCManager {
|
|
|
31
28
|
/// Defaulted in an extension to delegate to the basic recording path; devices
|
|
32
29
|
/// that support custom settings (e.g. Mentra Live) override this.
|
|
33
30
|
func startVideoRecording(
|
|
34
|
-
requestId: String, save: Bool, flash: Bool, sound: Bool, width: Int, height: Int, fps: Int
|
|
31
|
+
requestId: String, save: Bool, flash: Bool, sound: Bool, width: Int, height: Int, fps: Int,
|
|
32
|
+
maxRecordingTimeMinutes: Int
|
|
35
33
|
)
|
|
36
34
|
func stopVideoRecording(requestId: String)
|
|
35
|
+
/// Stop recording and upload the result to `webhookUrl` (multipart) using
|
|
36
|
+
/// `authToken`. Supplied at stop time so the token is fresh when the upload
|
|
37
|
+
/// runs. Defaulted in an extension to ignore the upload target and just stop;
|
|
38
|
+
/// devices that support webhook upload (e.g. Mentra Live) override this. An
|
|
39
|
+
/// empty/nil `webhookUrl` means "keep the video on device".
|
|
40
|
+
func stopVideoRecording(requestId: String, webhookUrl: String?, authToken: String?)
|
|
37
41
|
|
|
38
42
|
// MARK: - Button Settings
|
|
39
43
|
|
|
@@ -47,6 +51,7 @@ protocol SGCManager {
|
|
|
47
51
|
|
|
48
52
|
func setBrightness(_ level: Int, autoMode: Bool)
|
|
49
53
|
func clearDisplay()
|
|
54
|
+
func sendText(_ text: String) async
|
|
50
55
|
func sendTextWall(_ text: String) async
|
|
51
56
|
func sendDoubleTextWall(_ top: String, _ bottom: String) async
|
|
52
57
|
/// Display a bitmap. Optional `x`/`y`/`width`/`height` position and size the target
|
|
@@ -111,7 +116,7 @@ protocol SGCManager {
|
|
|
111
116
|
func sendWifiCredentials(_ ssid: String, _ password: String)
|
|
112
117
|
func forgetWifiNetwork(_ ssid: String)
|
|
113
118
|
func sendHotspotState(_ enabled: Bool)
|
|
114
|
-
func sendOtaStart()
|
|
119
|
+
func sendOtaStart(otaVersionUrl: String?)
|
|
115
120
|
func sendOtaQueryStatus()
|
|
116
121
|
func sendSetSystemTime(_ timestampMs: Int64)
|
|
117
122
|
func sendOtaRetryVersionCheck()
|
|
@@ -145,11 +150,15 @@ extension SGCManager {
|
|
|
145
150
|
|
|
146
151
|
func startVideoRecording(
|
|
147
152
|
requestId: String, save: Bool, flash: Bool, sound: Bool, width _: Int, height _: Int,
|
|
148
|
-
fps _: Int
|
|
153
|
+
fps _: Int, maxRecordingTimeMinutes _: Int
|
|
149
154
|
) {
|
|
150
155
|
startVideoRecording(requestId: requestId, save: save, flash: flash, sound: sound)
|
|
151
156
|
}
|
|
152
157
|
|
|
158
|
+
func stopVideoRecording(requestId: String, webhookUrl _: String?, authToken _: String?) {
|
|
159
|
+
stopVideoRecording(requestId: requestId)
|
|
160
|
+
}
|
|
161
|
+
|
|
153
162
|
// MARK: - Dashboard (default: combined wire format; Nex implements single-field)
|
|
154
163
|
|
|
155
164
|
func setDashboardHeightOnly(_ height: Int) {
|
|
@@ -79,8 +79,8 @@ class Simulated: SGCManager {
|
|
|
79
79
|
|
|
80
80
|
// MARK: - Camera & Media
|
|
81
81
|
|
|
82
|
-
func requestPhoto(_
|
|
83
|
-
Bridge.log("requestPhoto")
|
|
82
|
+
func requestPhoto(_ request: PhotoRequest) {
|
|
83
|
+
Bridge.log("requestPhoto flash=\(request.flash) save=\(request.save) sound=\(request.sound)")
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
func startStream(_: [String: Any]) {
|
|
@@ -133,6 +133,10 @@ class Simulated: SGCManager {
|
|
|
133
133
|
Bridge.log("clearDisplay")
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
func sendText(_ text: String) async {
|
|
137
|
+
await sendTextWall(text)
|
|
138
|
+
}
|
|
139
|
+
|
|
136
140
|
func sendTextWall(_: String) async {
|
|
137
141
|
Bridge.log("sendTextWall")
|
|
138
142
|
}
|
|
@@ -246,7 +250,7 @@ class Simulated: SGCManager {
|
|
|
246
250
|
Bridge.log("sendUserEmailToGlasses: \(email)")
|
|
247
251
|
}
|
|
248
252
|
|
|
249
|
-
func sendOtaStart() {
|
|
253
|
+
func sendOtaStart(otaVersionUrl: String?) {
|
|
250
254
|
Bridge.log("sendOtaStart")
|
|
251
255
|
}
|
|
252
256
|
|
|
@@ -921,7 +921,7 @@ struct BluetoothStatusUpdate: CustomStringConvertible {
|
|
|
921
921
|
}
|
|
922
922
|
|
|
923
923
|
var buttonPhotoSize: ButtonPhotoSize? {
|
|
924
|
-
optionalStringValue(values, "button_photo_size").
|
|
924
|
+
optionalStringValue(values, "button_photo_size").map { ButtonPhotoSize(normalizedRawValue: $0) }
|
|
925
925
|
}
|
|
926
926
|
|
|
927
927
|
var buttonCameraLed: Bool? {
|
|
@@ -3,7 +3,11 @@ import Foundation
|
|
|
3
3
|
public struct MentraBluetoothSDKConfiguration {
|
|
4
4
|
public static let `default` = MentraBluetoothSDKConfiguration()
|
|
5
5
|
|
|
6
|
-
public
|
|
6
|
+
public let analytics: BluetoothSdkAnalyticsConfiguration
|
|
7
|
+
|
|
8
|
+
public init(analytics: BluetoothSdkAnalyticsConfiguration = BluetoothSdkAnalyticsConfiguration()) {
|
|
9
|
+
self.analytics = analytics
|
|
10
|
+
}
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
public enum DeviceModel: String {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mentra/bluetooth-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "SDK for communicating with smart glasses",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"react-native": "./src/photo-receiver/index.ts",
|
|
23
23
|
"default": "./build/photo-receiver/index.js"
|
|
24
24
|
},
|
|
25
|
+
"./debug": {
|
|
26
|
+
"types": "./build/debug.d.ts",
|
|
27
|
+
"react-native": "./src/debug.ts",
|
|
28
|
+
"default": "./build/debug.js"
|
|
29
|
+
},
|
|
25
30
|
"./_private/*": null,
|
|
26
31
|
"./build/*": null,
|
|
27
32
|
"./src/*": null,
|
package/plugin/build/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { type ConfigPlugin } from "expo/config-plugins";
|
|
2
2
|
export interface BluetoothSdkPluginProps {
|
|
3
3
|
node?: boolean;
|
|
4
|
+
analytics?: boolean | BluetoothSdkAnalyticsPluginProps;
|
|
5
|
+
}
|
|
6
|
+
export interface BluetoothSdkAnalyticsPluginProps {
|
|
7
|
+
enabled?: boolean;
|
|
4
8
|
}
|
|
5
9
|
declare const withBluetoothSdk: ConfigPlugin<BluetoothSdkPluginProps>;
|
|
6
10
|
export default withBluetoothSdk;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import { type ConfigPlugin } from "expo/config-plugins";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}>;
|
|
2
|
+
import { type BluetoothSdkPluginProps } from "./index";
|
|
3
|
+
export declare const withAndroidConfiguration: ConfigPlugin<BluetoothSdkPluginProps>;
|
|
@@ -7,6 +7,10 @@ exports.withAndroidConfiguration = void 0;
|
|
|
7
7
|
const child_process_1 = require("child_process");
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const config_plugins_1 = require("expo/config-plugins");
|
|
10
|
+
const META_ANALYTICS_DISABLED = "com.mentra.bluetoothsdk.analytics.disabled";
|
|
11
|
+
const STALE_META_POSTHOG_API_KEY = "com.mentra.bluetoothsdk.analytics.posthog_api_key";
|
|
12
|
+
const STALE_META_POSTHOG_HOST = "com.mentra.bluetoothsdk.analytics.posthog_host";
|
|
13
|
+
const ANALYTICS_META_NAMES = [META_ANALYTICS_DISABLED, STALE_META_POSTHOG_API_KEY, STALE_META_POSTHOG_HOST];
|
|
10
14
|
function getBluetoothSdkRoot() {
|
|
11
15
|
return path_1.default.dirname(require.resolve("../../package.json"));
|
|
12
16
|
}
|
|
@@ -133,9 +137,51 @@ function withSherpaOnnxLocalMavenRepo(config) {
|
|
|
133
137
|
return config;
|
|
134
138
|
});
|
|
135
139
|
}
|
|
140
|
+
function resolveAnalyticsProps(props) {
|
|
141
|
+
const analytics = props?.analytics;
|
|
142
|
+
let disabled;
|
|
143
|
+
if (analytics === false) {
|
|
144
|
+
disabled = true;
|
|
145
|
+
}
|
|
146
|
+
else if (analytics === true) {
|
|
147
|
+
disabled = false;
|
|
148
|
+
}
|
|
149
|
+
else if (typeof analytics === "object" && analytics.enabled !== undefined) {
|
|
150
|
+
disabled = !analytics.enabled;
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
disabled,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function upsertMetaData(application, name, value) {
|
|
157
|
+
application["meta-data"] ??= [];
|
|
158
|
+
const existing = application["meta-data"].find((item) => item.$?.["android:name"] === name);
|
|
159
|
+
const entry = existing ?? { $: { "android:name": name } };
|
|
160
|
+
entry.$["android:value"] = value;
|
|
161
|
+
if (!existing) {
|
|
162
|
+
application["meta-data"].push(entry);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function removeMetaData(application, name) {
|
|
166
|
+
application["meta-data"] = (application["meta-data"] ?? []).filter((item) => item.$?.["android:name"] !== name);
|
|
167
|
+
}
|
|
168
|
+
function withAnalyticsManifestMetadata(config, props) {
|
|
169
|
+
return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
|
|
170
|
+
const analytics = resolveAnalyticsProps(props);
|
|
171
|
+
const application = config_plugins_1.AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);
|
|
172
|
+
for (const name of ANALYTICS_META_NAMES) {
|
|
173
|
+
removeMetaData(application, name);
|
|
174
|
+
}
|
|
175
|
+
if (analytics.disabled !== undefined) {
|
|
176
|
+
upsertMetaData(application, META_ANALYTICS_DISABLED, analytics.disabled ? "true" : "false");
|
|
177
|
+
}
|
|
178
|
+
return config;
|
|
179
|
+
});
|
|
180
|
+
}
|
|
136
181
|
const withAndroidConfiguration = (config, props) => {
|
|
137
182
|
config = withSettingsGradleModifications(config);
|
|
138
183
|
config = withSherpaOnnxLocalMavenRepo(config);
|
|
184
|
+
config = withAnalyticsManifestMetadata(config, props);
|
|
139
185
|
if (props?.node) {
|
|
140
186
|
config = withGradlePropertiesModifications(config);
|
|
141
187
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import { type ConfigPlugin } from "expo/config-plugins";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}>;
|
|
2
|
+
import { type BluetoothSdkPluginProps } from "./index";
|
|
3
|
+
export declare const withIosConfiguration: ConfigPlugin<BluetoothSdkPluginProps>;
|
package/plugin/build/withIos.js
CHANGED
|
@@ -10,6 +10,9 @@ const path_1 = __importDefault(require("path"));
|
|
|
10
10
|
const config_plugins_1 = require("expo/config-plugins");
|
|
11
11
|
const BLUETOOTH_SDK_EXPO_ADAPTER_ENV = "MENTRA_BLUETOOTH_SDK_INCLUDE_EXPO_ADAPTER";
|
|
12
12
|
const BLUETOOTH_SDK_EXPO_ADAPTER_LINE = `ENV['${BLUETOOTH_SDK_EXPO_ADAPTER_ENV}'] ||= '1'`;
|
|
13
|
+
const INFO_ANALYTICS_DISABLED = "MentraBluetoothSdkAnalyticsDisabled";
|
|
14
|
+
const STALE_INFO_POSTHOG_API_KEY = "MentraBluetoothSdkPostHogApiKey";
|
|
15
|
+
const STALE_INFO_POSTHOG_HOST = "MentraBluetoothSdkPostHogHost";
|
|
13
16
|
const ensureBluetoothSdkExpoAdapterPodEnv = (podfile) => {
|
|
14
17
|
if (podfile.includes(BLUETOOTH_SDK_EXPO_ADAPTER_ENV)) {
|
|
15
18
|
return podfile;
|
|
@@ -51,11 +54,40 @@ const withXcodeEnvLocal = (config) => {
|
|
|
51
54
|
},
|
|
52
55
|
]);
|
|
53
56
|
};
|
|
57
|
+
function resolveAnalyticsProps(props) {
|
|
58
|
+
const analytics = props?.analytics;
|
|
59
|
+
let disabled;
|
|
60
|
+
if (analytics === false) {
|
|
61
|
+
disabled = true;
|
|
62
|
+
}
|
|
63
|
+
else if (analytics === true) {
|
|
64
|
+
disabled = false;
|
|
65
|
+
}
|
|
66
|
+
else if (typeof analytics === "object" && analytics.enabled !== undefined) {
|
|
67
|
+
disabled = !analytics.enabled;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
disabled,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function withAnalyticsInfoPlist(config, props) {
|
|
74
|
+
return (0, config_plugins_1.withInfoPlist)(config, (config) => {
|
|
75
|
+
const analytics = resolveAnalyticsProps(props);
|
|
76
|
+
delete config.modResults[INFO_ANALYTICS_DISABLED];
|
|
77
|
+
delete config.modResults[STALE_INFO_POSTHOG_API_KEY];
|
|
78
|
+
delete config.modResults[STALE_INFO_POSTHOG_HOST];
|
|
79
|
+
if (analytics.disabled !== undefined) {
|
|
80
|
+
config.modResults[INFO_ANALYTICS_DISABLED] = analytics.disabled;
|
|
81
|
+
}
|
|
82
|
+
return config;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
54
85
|
const withIosConfiguration = (config, props) => {
|
|
55
86
|
config = (0, config_plugins_1.withPodfile)(config, (config) => {
|
|
56
87
|
config.modResults.contents = ensureBluetoothSdkExpoAdapterPodEnv(config.modResults.contents);
|
|
57
88
|
return config;
|
|
58
89
|
});
|
|
90
|
+
config = withAnalyticsInfoPlist(config, props);
|
|
59
91
|
if (props?.node) {
|
|
60
92
|
config = withXcodeEnvLocal(config);
|
|
61
93
|
}
|
|
@@ -248,6 +248,13 @@ export type PhotoCaptureMetadata = {
|
|
|
248
248
|
sensorTimestampNs?: number
|
|
249
249
|
totalLightProxy?: number
|
|
250
250
|
mfnrLikely?: boolean
|
|
251
|
+
mfnrApplied?: boolean
|
|
252
|
+
width?: number
|
|
253
|
+
height?: number
|
|
254
|
+
noiseReductionWarning?: "not_implemented" | string
|
|
255
|
+
ispDigitalGainWarning?: "not_implemented" | string
|
|
256
|
+
ispAnalogGainWarning?: "not_implemented" | string
|
|
257
|
+
[key: string]: unknown
|
|
251
258
|
}
|
|
252
259
|
|
|
253
260
|
export type PhotoStatusEvent = {
|
|
@@ -307,6 +314,24 @@ export type VideoRecordingSuccessStatusEvent =
|
|
|
307
314
|
| VideoRecordingStartedStatusEvent
|
|
308
315
|
| VideoRecordingStoppedStatusEvent
|
|
309
316
|
|
|
317
|
+
export type MediaUploadSuccessEvent = {
|
|
318
|
+
type: "media_success"
|
|
319
|
+
requestId: string
|
|
320
|
+
mediaUrl: string
|
|
321
|
+
mediaType: number
|
|
322
|
+
timestamp: number
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export type MediaUploadErrorEvent = {
|
|
326
|
+
type: "media_error"
|
|
327
|
+
requestId: string
|
|
328
|
+
errorMessage: string
|
|
329
|
+
mediaType: number
|
|
330
|
+
timestamp: number
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export type MediaUploadEvent = MediaUploadSuccessEvent | MediaUploadErrorEvent
|
|
334
|
+
|
|
310
335
|
export type GalleryStatusEvent = {
|
|
311
336
|
type: "gallery_status"
|
|
312
337
|
photos: number
|
|
@@ -403,8 +428,24 @@ export type SettingsAckSuccessEvent = Omit<SettingsAckEvent, "status"> & {
|
|
|
403
428
|
|
|
404
429
|
export type RgbLedAction = "on" | "off"
|
|
405
430
|
export type RgbLedColor = "red" | "green" | "blue" | "orange" | "white"
|
|
406
|
-
export type PhotoSize = "
|
|
407
|
-
export type ButtonPhotoSize = "
|
|
431
|
+
export type PhotoSize = "low" | "medium" | "high" | "max"
|
|
432
|
+
export type ButtonPhotoSize = "low" | "medium" | "high" | "max"
|
|
433
|
+
|
|
434
|
+
export type ButtonPhotoSettings = {
|
|
435
|
+
size: ButtonPhotoSize
|
|
436
|
+
mfnr?: boolean
|
|
437
|
+
zsl?: boolean
|
|
438
|
+
noiseReduction?: boolean
|
|
439
|
+
edgeEnhancement?: boolean
|
|
440
|
+
ispDigitalGain?: number
|
|
441
|
+
ispAnalogGain?: string
|
|
442
|
+
aeExposureDivisor?: number
|
|
443
|
+
isoCap?: number
|
|
444
|
+
compress?: PhotoCompression
|
|
445
|
+
sound?: boolean
|
|
446
|
+
/** When true, clears stored NR/edge/ISP presets on the glasses before applying other fields. */
|
|
447
|
+
resetCaptureTuning?: boolean
|
|
448
|
+
}
|
|
408
449
|
export type PhotoCompression = "none" | "medium" | "heavy"
|
|
409
450
|
|
|
410
451
|
/**
|
|
@@ -416,6 +457,12 @@ export interface VideoRecordingSettings {
|
|
|
416
457
|
width?: number
|
|
417
458
|
height?: number
|
|
418
459
|
fps?: number
|
|
460
|
+
/**
|
|
461
|
+
* Optional auto-stop timer in minutes, sent on `start_video_recording`.
|
|
462
|
+
* `0` (the default) means record until stopped or interrupted
|
|
463
|
+
* (battery/storage/thermal/error).
|
|
464
|
+
*/
|
|
465
|
+
maxRecordingTimeMinutes?: number
|
|
419
466
|
}
|
|
420
467
|
export const DeviceModels = {
|
|
421
468
|
Simulated: "Simulated Glasses",
|
|
@@ -487,6 +534,17 @@ export type PhotoRequestParams = {
|
|
|
487
534
|
exposureTimeNs?: number | null
|
|
488
535
|
/** Sensor ISO for this capture only. Only used when exposureTimeNs enables manual exposure. */
|
|
489
536
|
iso?: number | null
|
|
537
|
+
/** After AE convergence, divide metered exposure by this factor (scan mode). */
|
|
538
|
+
aeExposureDivisor?: number
|
|
539
|
+
/** Cap ISO after AE metering (scan mode). */
|
|
540
|
+
isoCap?: number
|
|
541
|
+
/** Requested on wire; glasses may log not_implemented. */
|
|
542
|
+
noiseReduction?: boolean
|
|
543
|
+
edgeEnhancement?: boolean
|
|
544
|
+
mfnr?: boolean
|
|
545
|
+
zsl?: boolean
|
|
546
|
+
ispDigitalGain?: number
|
|
547
|
+
ispAnalogGain?: string
|
|
490
548
|
}
|
|
491
549
|
|
|
492
550
|
export type StreamVideoConfig = {
|
|
@@ -743,6 +801,8 @@ export type BluetoothSdkModuleEvents = {
|
|
|
743
801
|
photo_response: (event: PhotoResponseEvent) => void
|
|
744
802
|
photo_status: (event: PhotoStatusEvent) => void
|
|
745
803
|
video_recording_status: (event: VideoRecordingStatusEvent) => void
|
|
804
|
+
media_success: (event: MediaUploadSuccessEvent) => void
|
|
805
|
+
media_error: (event: MediaUploadErrorEvent) => void
|
|
746
806
|
gallery_status: (event: GalleryStatusEvent) => void
|
|
747
807
|
compatible_glasses_search_stop: (event: CompatibleGlassesSearchStopEvent) => void
|
|
748
808
|
heartbeat_sent: (event: HeartbeatSentEvent) => void
|
|
@@ -818,6 +878,8 @@ export type BluetoothSdkEventMap = {
|
|
|
818
878
|
photo_response: PhotoResponseEvent
|
|
819
879
|
photo_status: PhotoStatusEvent
|
|
820
880
|
video_recording_status: VideoRecordingStatusEvent
|
|
881
|
+
media_success: MediaUploadSuccessEvent
|
|
882
|
+
media_error: MediaUploadErrorEvent
|
|
821
883
|
gallery_status: GalleryStatusEvent
|
|
822
884
|
compatible_glasses_search_stop: CompatibleGlassesSearchStopEvent
|
|
823
885
|
swipe_volume_status: SwipeVolumeStatusEvent
|
|
@@ -831,7 +893,6 @@ export type BluetoothSdkEventMap = {
|
|
|
831
893
|
mic_pcm: MicPcmEvent
|
|
832
894
|
mic_lc3: MicLc3Event
|
|
833
895
|
stream_status: StreamStatusEvent
|
|
834
|
-
ota_update_available: OtaUpdateAvailableEvent
|
|
835
896
|
ota_start_ack: OtaStartAckEvent
|
|
836
897
|
ota_status: OtaStatusEvent
|
|
837
898
|
version_info: VersionInfoEvent
|
|
@@ -885,7 +946,7 @@ export interface BluetoothSdkPublicModule {
|
|
|
885
946
|
|
|
886
947
|
setGalleryModeEnabled(enabled: boolean): Promise<SettingsAckSuccessEvent>
|
|
887
948
|
setVoiceActivityDetectionEnabled(enabled: boolean): Promise<void>
|
|
888
|
-
setButtonPhotoSettings(
|
|
949
|
+
setButtonPhotoSettings(settings: ButtonPhotoSettings): Promise<SettingsAckSuccessEvent>
|
|
889
950
|
setButtonVideoRecordingSettings(width: number, height: number, fps: number): Promise<SettingsAckSuccessEvent>
|
|
890
951
|
setButtonCameraLed(enabled: boolean): Promise<SettingsAckSuccessEvent>
|
|
891
952
|
setButtonMaxRecordingTime(minutes: number): Promise<SettingsAckSuccessEvent>
|
|
@@ -898,7 +959,18 @@ export interface BluetoothSdkPublicModule {
|
|
|
898
959
|
sound: boolean,
|
|
899
960
|
settings?: VideoRecordingSettings,
|
|
900
961
|
): Promise<VideoRecordingStartedStatusEvent>
|
|
901
|
-
|
|
962
|
+
/**
|
|
963
|
+
* Stop the active recording. When {@link webhookUrl} is provided, the glasses
|
|
964
|
+
* upload the recorded video to it (multipart) using {@link authToken}. These
|
|
965
|
+
* are supplied at stop time (not start) so the token is fresh when the upload
|
|
966
|
+
* runs — a recording can last arbitrarily long. An empty/omitted webhook keeps
|
|
967
|
+
* the video on device (no upload).
|
|
968
|
+
*/
|
|
969
|
+
stopVideoRecording(
|
|
970
|
+
requestId: string,
|
|
971
|
+
webhookUrl?: string,
|
|
972
|
+
authToken?: string,
|
|
973
|
+
): Promise<VideoRecordingStoppedStatusEvent>
|
|
902
974
|
|
|
903
975
|
startStream(params: StreamStartRequest): Promise<StreamStatusEvent>
|
|
904
976
|
stopStream(): Promise<StreamStatusEvent>
|
|
@@ -920,12 +992,10 @@ export interface BluetoothSdkPublicModule {
|
|
|
920
992
|
): Promise<RgbLedControlSuccessResponseEvent>
|
|
921
993
|
|
|
922
994
|
requestVersionInfo(): Promise<VersionInfoResult>
|
|
923
|
-
/**
|
|
924
|
-
checkForOtaUpdate(): Promise<
|
|
925
|
-
/** Start the OTA flow
|
|
995
|
+
/** Fetch the configured OTA manifest and return whether any ASG/BES/MTK update is available. */
|
|
996
|
+
checkForOtaUpdate(): Promise<boolean>
|
|
997
|
+
/** Start the OTA flow with the same configured manifest URL used by checkForOtaUpdate(). */
|
|
926
998
|
startOtaUpdate(): Promise<OtaStartAckEvent>
|
|
927
|
-
/** Re-run the glasses-side OTA version check, mainly after correcting clock skew/TLS failures. */
|
|
928
|
-
retryOtaVersionCheck(): Promise<OtaQueryResult>
|
|
929
999
|
|
|
930
1000
|
// // stt commands (MOVE TO CRUST)
|
|
931
1001
|
// setSttModelDetails(path: string, languageCode: string): Promise<void>
|
|
@@ -2,10 +2,9 @@ import {NativeModule, requireNativeModule} from "expo"
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
BluetoothSettingsUpdate,
|
|
5
|
-
BluetoothSdkPublicModule,
|
|
6
5
|
BluetoothSdkModuleEvents,
|
|
7
6
|
BluetoothStatus,
|
|
8
|
-
|
|
7
|
+
ButtonPhotoSettings,
|
|
9
8
|
CalendarEvent,
|
|
10
9
|
CAMERA_FOV_DEFAULT,
|
|
11
10
|
CAMERA_FOV_MAX,
|
|
@@ -122,7 +121,8 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
|
|
|
122
121
|
// Gallery Commands
|
|
123
122
|
setGalleryModeEnabled(enabled: boolean): Promise<SettingsAckSuccessEvent>
|
|
124
123
|
setVoiceActivityDetectionEnabled(enabled: boolean): Promise<void>
|
|
125
|
-
setButtonPhotoSettings(
|
|
124
|
+
setButtonPhotoSettings(settings: ButtonPhotoSettings): Promise<SettingsAckSuccessEvent>
|
|
125
|
+
setButtonPhotoCaptureSettings(settings: ButtonPhotoSettings): Promise<SettingsAckSuccessEvent>
|
|
126
126
|
setButtonVideoRecordingSettings(width: number, height: number, fps: number): Promise<SettingsAckSuccessEvent>
|
|
127
127
|
setButtonCameraLed(enabled: boolean): Promise<SettingsAckSuccessEvent>
|
|
128
128
|
setButtonMaxRecordingTime(minutes: number): Promise<SettingsAckSuccessEvent>
|
|
@@ -131,12 +131,13 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
|
|
|
131
131
|
requestPhoto(params: PhotoRequestParams): Promise<PhotoSuccessResponseEvent>
|
|
132
132
|
|
|
133
133
|
// OTA Commands
|
|
134
|
-
|
|
134
|
+
setOtaVersionUrl(otaVersionUrl: string): void
|
|
135
|
+
getOtaVersionUrl(): string
|
|
136
|
+
checkForOtaUpdate(): Promise<boolean>
|
|
137
|
+
startOtaUpdate(otaVersionUrl?: string | null): Promise<OtaStartAckEvent>
|
|
135
138
|
sendOtaQueryStatus(): Promise<OtaQueryResult>
|
|
136
139
|
/** Re-run glasses-side OTA version check (called after a clock fix invalidates a TLS failure). */
|
|
137
140
|
retryOtaVersionCheck(): Promise<OtaQueryResult>
|
|
138
|
-
checkForOtaUpdate(): Promise<OtaQueryResult>
|
|
139
|
-
startOtaUpdate(): Promise<OtaStartAckEvent>
|
|
140
141
|
|
|
141
142
|
// Version Info Commands
|
|
142
143
|
requestVersionInfo(): Promise<VersionInfoResult>
|
|
@@ -148,7 +149,11 @@ declare class BluetoothSdkNativeModule extends NativeModule<BluetoothSdkModuleEv
|
|
|
148
149
|
sound: boolean,
|
|
149
150
|
settings?: VideoRecordingSettings,
|
|
150
151
|
): Promise<VideoRecordingStartedStatusEvent>
|
|
151
|
-
stopVideoRecording(
|
|
152
|
+
stopVideoRecording(
|
|
153
|
+
requestId: string,
|
|
154
|
+
webhookUrl?: string,
|
|
155
|
+
authToken?: string,
|
|
156
|
+
): Promise<VideoRecordingStoppedStatusEvent>
|
|
152
157
|
|
|
153
158
|
// Stream Commands
|
|
154
159
|
startStream(params: StreamStartRequest): Promise<StreamStatusEvent>
|
|
@@ -567,8 +572,6 @@ const nativeStartStream = NativeBluetoothSdkModule.startStream.bind(NativeBlueto
|
|
|
567
572
|
NativeBluetoothSdkModule.startExternallyManagedStream = function (params: StreamStartRequest) {
|
|
568
573
|
return nativeStartStream({...params, keepAliveMode: "external"} as StreamStartRequest)
|
|
569
574
|
}
|
|
570
|
-
NativeBluetoothSdkModule.checkForOtaUpdate = NativeBluetoothSdkModule.sendOtaQueryStatus.bind(NativeBluetoothSdkModule)
|
|
571
|
-
NativeBluetoothSdkModule.startOtaUpdate = NativeBluetoothSdkModule.sendOtaStart.bind(NativeBluetoothSdkModule)
|
|
572
575
|
|
|
573
576
|
export default NativeBluetoothSdkModule
|
|
574
|
-
export const BluetoothSdk = NativeBluetoothSdkModule as
|
|
577
|
+
export const BluetoothSdk = NativeBluetoothSdkModule as BluetoothSdkInternalModule
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
import type {PhotoRequestParams} from "../BluetoothSdk.types"
|
|
1
|
+
import type {PhotoRequestParams, PhotoSize} from "../BluetoothSdk.types"
|
|
2
|
+
|
|
3
|
+
/** Maps unknown/legacy size strings to the current wire format. */
|
|
4
|
+
export function normalizePhotoSizeTier(size: string | undefined): PhotoSize {
|
|
5
|
+
switch (size) {
|
|
6
|
+
case "small":
|
|
7
|
+
return "low"
|
|
8
|
+
case "large":
|
|
9
|
+
return "high"
|
|
10
|
+
case "full":
|
|
11
|
+
return "max"
|
|
12
|
+
case "low":
|
|
13
|
+
case "medium":
|
|
14
|
+
case "high":
|
|
15
|
+
case "max":
|
|
16
|
+
return size
|
|
17
|
+
default:
|
|
18
|
+
return "medium"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
2
21
|
|
|
3
22
|
/** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */
|
|
4
23
|
export function photoRequestParamsForNative(
|
|
@@ -7,7 +26,7 @@ export function photoRequestParamsForNative(
|
|
|
7
26
|
const payload: Record<string, string | number | boolean> = {
|
|
8
27
|
requestId: params.requestId,
|
|
9
28
|
appId: params.appId,
|
|
10
|
-
size: params.size,
|
|
29
|
+
size: normalizePhotoSizeTier(params.size),
|
|
11
30
|
webhookUrl: params.webhookUrl ?? "",
|
|
12
31
|
compress: params.compress,
|
|
13
32
|
flash: true,
|
|
@@ -24,5 +43,29 @@ export function photoRequestParamsForNative(
|
|
|
24
43
|
if (hasManualExposure && params.iso != null && Number.isFinite(params.iso) && params.iso > 0) {
|
|
25
44
|
payload.iso = Math.round(params.iso)
|
|
26
45
|
}
|
|
46
|
+
if (params.aeExposureDivisor != null && params.aeExposureDivisor > 1) {
|
|
47
|
+
payload.aeExposureDivisor = Math.round(params.aeExposureDivisor)
|
|
48
|
+
}
|
|
49
|
+
if (params.isoCap != null && params.isoCap > 0) {
|
|
50
|
+
payload.isoCap = Math.round(params.isoCap)
|
|
51
|
+
}
|
|
52
|
+
if (params.noiseReduction != null) {
|
|
53
|
+
payload.noiseReduction = params.noiseReduction
|
|
54
|
+
}
|
|
55
|
+
if (params.edgeEnhancement != null) {
|
|
56
|
+
payload.edgeEnhancement = params.edgeEnhancement
|
|
57
|
+
}
|
|
58
|
+
if (params.mfnr != null) {
|
|
59
|
+
payload.mfnr = params.mfnr
|
|
60
|
+
}
|
|
61
|
+
if (params.zsl != null) {
|
|
62
|
+
payload.zsl = params.zsl
|
|
63
|
+
}
|
|
64
|
+
if (params.ispDigitalGain != null) {
|
|
65
|
+
payload.ispDigitalGain = Math.round(params.ispDigitalGain)
|
|
66
|
+
}
|
|
67
|
+
if (params.ispAnalogGain != null && params.ispAnalogGain.length > 0) {
|
|
68
|
+
payload.ispAnalogGain = params.ispAnalogGain
|
|
69
|
+
}
|
|
27
70
|
return payload
|
|
28
71
|
}
|
package/src/debug.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import PrivateBluetoothSdkModule from "./_private/BluetoothSdkModule"
|
|
2
|
+
|
|
3
|
+
export function setOtaVersionUrl(otaVersionUrl: string): void {
|
|
4
|
+
PrivateBluetoothSdkModule.setOtaVersionUrl(otaVersionUrl)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function getOtaVersionUrl(): string {
|
|
8
|
+
return PrivateBluetoothSdkModule.getOtaVersionUrl()
|
|
9
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import PrivateBluetoothSdkModule from "./_private/BluetoothSdkModule"
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
BluetoothSdkEventListener,
|
|
4
|
+
BluetoothSdkEventName,
|
|
5
|
+
BluetoothSdkPublicModule,
|
|
6
|
+
ButtonPhotoSettings,
|
|
7
|
+
} from "./BluetoothSdk.types"
|
|
3
8
|
|
|
4
9
|
const PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([
|
|
5
10
|
"log",
|
|
@@ -21,6 +26,8 @@ const PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([
|
|
|
21
26
|
"photo_response",
|
|
22
27
|
"photo_status",
|
|
23
28
|
"video_recording_status",
|
|
29
|
+
"media_success",
|
|
30
|
+
"media_error",
|
|
24
31
|
"gallery_status",
|
|
25
32
|
"compatible_glasses_search_stop",
|
|
26
33
|
"swipe_volume_status",
|
|
@@ -34,7 +41,6 @@ const PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([
|
|
|
34
41
|
"mic_pcm",
|
|
35
42
|
"mic_lc3",
|
|
36
43
|
"stream_status",
|
|
37
|
-
"ota_update_available",
|
|
38
44
|
"ota_start_ack",
|
|
39
45
|
"ota_status",
|
|
40
46
|
"version_info",
|
|
@@ -48,6 +54,10 @@ const addListener: BluetoothSdkPublicModule["addListener"] = (eventName, listene
|
|
|
48
54
|
return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
const startOtaUpdate: BluetoothSdkPublicModule["startOtaUpdate"] = () => {
|
|
58
|
+
return PrivateBluetoothSdkModule.startOtaUpdate()
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
export const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({
|
|
52
62
|
addListener,
|
|
53
63
|
getDefaultDevice: PrivateBluetoothSdkModule.getDefaultDevice.bind(PrivateBluetoothSdkModule),
|
|
@@ -75,7 +85,15 @@ export const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({
|
|
|
75
85
|
setGalleryModeEnabled: PrivateBluetoothSdkModule.setGalleryModeEnabled.bind(PrivateBluetoothSdkModule),
|
|
76
86
|
setVoiceActivityDetectionEnabled:
|
|
77
87
|
PrivateBluetoothSdkModule.setVoiceActivityDetectionEnabled.bind(PrivateBluetoothSdkModule),
|
|
78
|
-
setButtonPhotoSettings:
|
|
88
|
+
setButtonPhotoSettings: (settings: ButtonPhotoSettings) => {
|
|
89
|
+
// setButtonPhotoCaptureSettings is available in SDK 0.1.13+. Guard for OTA version-skew
|
|
90
|
+
// where a new JS bundle runs against an older native module that only has the string form.
|
|
91
|
+
if (typeof PrivateBluetoothSdkModule.setButtonPhotoCaptureSettings === "function") {
|
|
92
|
+
return PrivateBluetoothSdkModule.setButtonPhotoCaptureSettings(settings)
|
|
93
|
+
}
|
|
94
|
+
// Legacy fallback: old native bridge only accepts a size string
|
|
95
|
+
return PrivateBluetoothSdkModule.setButtonPhotoSettings({size: settings.size ?? "max"} as any)
|
|
96
|
+
},
|
|
79
97
|
setButtonVideoRecordingSettings:
|
|
80
98
|
PrivateBluetoothSdkModule.setButtonVideoRecordingSettings.bind(PrivateBluetoothSdkModule),
|
|
81
99
|
setButtonCameraLed: PrivateBluetoothSdkModule.setButtonCameraLed.bind(PrivateBluetoothSdkModule),
|
|
@@ -94,9 +112,8 @@ export const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({
|
|
|
94
112
|
setGlassesMediaVolume: PrivateBluetoothSdkModule.setGlassesMediaVolume.bind(PrivateBluetoothSdkModule),
|
|
95
113
|
rgbLedControl: PrivateBluetoothSdkModule.rgbLedControl.bind(PrivateBluetoothSdkModule),
|
|
96
114
|
requestVersionInfo: PrivateBluetoothSdkModule.requestVersionInfo.bind(PrivateBluetoothSdkModule),
|
|
97
|
-
checkForOtaUpdate: PrivateBluetoothSdkModule.
|
|
98
|
-
startOtaUpdate
|
|
99
|
-
retryOtaVersionCheck: PrivateBluetoothSdkModule.retryOtaVersionCheck.bind(PrivateBluetoothSdkModule),
|
|
115
|
+
checkForOtaUpdate: PrivateBluetoothSdkModule.checkForOtaUpdate.bind(PrivateBluetoothSdkModule),
|
|
116
|
+
startOtaUpdate,
|
|
100
117
|
setSttModelDetails: PrivateBluetoothSdkModule.setSttModelDetails.bind(PrivateBluetoothSdkModule),
|
|
101
118
|
getSttModelPath: PrivateBluetoothSdkModule.getSttModelPath.bind(PrivateBluetoothSdkModule),
|
|
102
119
|
checkSttModelAvailable: PrivateBluetoothSdkModule.checkSttModelAvailable.bind(PrivateBluetoothSdkModule),
|
|
@@ -138,6 +155,7 @@ export type {
|
|
|
138
155
|
BluetoothSdkPublicModule as BluetoothSdkModule,
|
|
139
156
|
BluetoothSdkSubscription,
|
|
140
157
|
ButtonPhotoSize,
|
|
158
|
+
ButtonPhotoSettings,
|
|
141
159
|
ButtonPressEvent,
|
|
142
160
|
CameraFovPreset,
|
|
143
161
|
CameraFovRequest,
|
|
@@ -179,6 +197,7 @@ export type {
|
|
|
179
197
|
PhotoMeteredPreview,
|
|
180
198
|
PhotoResponseEvent,
|
|
181
199
|
PhotoRequestedCaptureConfig,
|
|
200
|
+
PhotoRequestParams,
|
|
182
201
|
PhotoSize,
|
|
183
202
|
PhotoStatusEvent,
|
|
184
203
|
PhotoStatusState,
|