@mentra/engine 3.1.0-dev.20 → 3.1.0-dev.22
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 +19 -5
- package/build/bluetooth-sdk/ota-transport.d.ts +2 -0
- package/build/bluetooth-sdk/ota-transport.d.ts.map +1 -0
- package/build/bluetooth-sdk/ota-transport.js +2 -0
- package/build/bluetooth-sdk/ota-transport.js.map +1 -0
- package/build/engine.d.ts +2 -2
- package/build/facades/ota.d.ts +4 -4
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +3 -4
- package/build/facades/ota.js.map +1 -1
- package/build/generated/releaseMetadata.js +4 -4
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.d.ts +3 -2
- package/build/react/MentraLiveOtaFlow.d.ts.map +1 -1
- package/build/react/MentraLiveOtaFlow.js +68 -345
- package/build/react/MentraLiveOtaFlow.js.map +1 -1
- package/build/react/index.d.ts +1 -0
- package/build/react/index.d.ts.map +1 -1
- package/build/react/index.js +1 -0
- package/build/react/index.js.map +1 -1
- package/build/react/useMentraLiveOta.d.ts +69 -0
- package/build/react/useMentraLiveOta.d.ts.map +1 -0
- package/build/react/useMentraLiveOta.js +485 -0
- package/build/react/useMentraLiveOta.js.map +1 -0
- package/build/services/GlassesStatusProjection.d.ts +15 -2
- package/build/services/GlassesStatusProjection.d.ts.map +1 -1
- package/build/services/GlassesStatusProjection.js +3 -3
- package/build/services/GlassesStatusProjection.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts.map +1 -1
- package/build/services/HotspotOtaTransport.js +8 -7
- package/build/services/HotspotOtaTransport.js.map +1 -1
- package/build/services/OtaInstallCoordinator.d.ts +24 -3
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +14 -12
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/OtaService.d.ts.map +1 -1
- package/build/services/OtaService.js +1 -1
- package/build/services/OtaService.js.map +1 -1
- package/build/services/OtaUpdateCheckService.d.ts +1 -1
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +6 -2
- package/build/services/OtaUpdateCheckService.js.map +1 -1
- package/build/services/asg/localNetworkTransport.d.ts.map +1 -1
- package/build/services/asg/localNetworkTransport.js +13 -12
- package/build/services/asg/localNetworkTransport.js.map +1 -1
- package/build/services/glassesClockSync.js +1 -1
- package/build/services/glassesClockSync.js.map +1 -1
- package/build/stores/core.d.ts +3 -3
- package/build/stores/core.d.ts.map +1 -1
- package/build/stores/core.js.map +1 -1
- package/build/stores/glasses.d.ts +10 -4
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js.map +1 -1
- package/package.json +12 -6
- package/src/bluetooth-sdk/ota-transport.ts +1 -0
- package/src/facades/ota.ts +3 -4
- package/src/generated/releaseMetadata.ts +4 -4
- package/src/react/MentraLiveOtaFlow.tsx +116 -466
- package/src/react/index.ts +13 -0
- package/src/react/useMentraLiveOta.ts +619 -0
- package/src/services/GlassesStatusProjection.ts +7 -6
- package/src/services/HotspotOtaTransport.ts +8 -7
- package/src/services/OtaInstallCoordinator.ts +16 -13
- package/src/services/OtaService.ts +1 -2
- package/src/services/OtaUpdateCheckService.ts +8 -5
- package/src/services/asg/localNetworkTransport.ts +20 -19
- package/src/services/glassesClockSync.ts +1 -1
- package/src/stores/core.ts +4 -4
- package/src/stores/glasses.ts +13 -6
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { ota } from "../facades/ota";
|
|
3
|
+
import { beginOtaAutoChain, clearOtaAutoChainReconnectWait, isOtaAutoChainActive, otaAutoChainFingerprint, otaAutoChainReconnectWaitRemaining, stopOtaAutoChain, tryAdvanceOtaAutoChain, } from "../services/OtaAutoChain";
|
|
4
|
+
import { BES_INSTALL_RESTART_MESSAGE, getOtaErrorMessage, shouldRequireGlassesRebootForBesFailure, shouldShowChangeWifiForOtaDownloadFailure, } from "../services/OtaErrorMapping";
|
|
5
|
+
import { useEngineSnapshot } from "./useEngineSnapshot";
|
|
6
|
+
const AUTO_CHAIN_NETWORK_RETRY_DELAY_MS = 5000;
|
|
7
|
+
const AUTO_CHAIN_COMPLETE_DELAY_MS = 750;
|
|
8
|
+
function installProgress(snapshot) {
|
|
9
|
+
if (snapshot.displayState !== "updating")
|
|
10
|
+
return null;
|
|
11
|
+
const { otaStatus } = snapshot;
|
|
12
|
+
const isDownload = otaStatus?.phase === "download";
|
|
13
|
+
const totalSteps = otaStatus?.totalSteps ?? 1;
|
|
14
|
+
const rawPercent = isDownload
|
|
15
|
+
? (otaStatus?.stepPercent ?? 0)
|
|
16
|
+
: totalSteps >= 2
|
|
17
|
+
? (otaStatus?.overallPercent ?? 0)
|
|
18
|
+
: (otaStatus?.stepPercent ?? 0);
|
|
19
|
+
return Math.min(Math.max(rawPercent, snapshot.mtkInstallStallSimulatedPercent ?? 0, 0), 100);
|
|
20
|
+
}
|
|
21
|
+
function progressScreen(snapshot) {
|
|
22
|
+
if (snapshot.versionChangePhase === "restarting")
|
|
23
|
+
return "restarting";
|
|
24
|
+
if (snapshot.versionChangePhase === "verifying")
|
|
25
|
+
return "verifying";
|
|
26
|
+
switch (snapshot.displayState) {
|
|
27
|
+
case "starting":
|
|
28
|
+
return snapshot.hotspotPhase === "idle" || snapshot.hotspotPhase === "serving" ? "starting" : "preparing_hotspot";
|
|
29
|
+
case "updating":
|
|
30
|
+
return "updating";
|
|
31
|
+
case "restarting":
|
|
32
|
+
return "restarting";
|
|
33
|
+
case "complete":
|
|
34
|
+
return "complete";
|
|
35
|
+
case "failed":
|
|
36
|
+
return "failed";
|
|
37
|
+
default:
|
|
38
|
+
return "disconnected";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Headless Mentra Live OTA flow. Engine owns checking, hotspot staging,
|
|
43
|
+
* APK/MTK/BES sequencing, restart recovery, retries, and verification; the host
|
|
44
|
+
* renders semantic state and invokes these idempotent actions.
|
|
45
|
+
*/
|
|
46
|
+
export function useMentraLiveOta(options = {}) {
|
|
47
|
+
const { initialPage = "check", initializeRuntime = true, onFinished, onFirmwareRestartingChange, onOpenWifiSetup, } = options;
|
|
48
|
+
const otaSnapshot = useEngineSnapshot(ota.snapshot, ota.onSnapshot);
|
|
49
|
+
const installSnapshot = useEngineSnapshot(ota.installSession.snapshot, ota.installSession.onSnapshot);
|
|
50
|
+
const [page, setPage] = useState(initialPage);
|
|
51
|
+
const [runtimeReady, setRuntimeReady] = useState(!initializeRuntime);
|
|
52
|
+
const [checkState, setCheckState] = useState("checking");
|
|
53
|
+
const [isUpdateRequired, setIsUpdateRequired] = useState(true);
|
|
54
|
+
const [isVersionChange, setIsVersionChange] = useState(false);
|
|
55
|
+
const [errorKind, setErrorKind] = useState("network");
|
|
56
|
+
const [updateFingerprint, setUpdateFingerprint] = useState(null);
|
|
57
|
+
const [checkGeneration, setCheckGeneration] = useState(0);
|
|
58
|
+
const performCheckGenerationRef = useRef(0);
|
|
59
|
+
const activeCheckKeyRef = useRef(null);
|
|
60
|
+
const checkStartedRef = useRef(false);
|
|
61
|
+
const checkCompletedRef = useRef(false);
|
|
62
|
+
const selectedCheckResultRef = useRef(null);
|
|
63
|
+
const autoChainAdvancedRef = useRef(false);
|
|
64
|
+
const installActionPendingRef = useRef(false);
|
|
65
|
+
const onFinishedRef = useRef(onFinished);
|
|
66
|
+
const onOpenWifiSetupRef = useRef(onOpenWifiSetup);
|
|
67
|
+
const onFirmwareRestartingChangeRef = useRef(onFirmwareRestartingChange);
|
|
68
|
+
onFinishedRef.current = onFinished;
|
|
69
|
+
onOpenWifiSetupRef.current = onOpenWifiSetup;
|
|
70
|
+
onFirmwareRestartingChangeRef.current = onFirmwareRestartingChange;
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!initializeRuntime) {
|
|
73
|
+
setRuntimeReady(true);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
let cancelled = false;
|
|
77
|
+
setRuntimeReady(false);
|
|
78
|
+
void ota.initialize().finally(() => {
|
|
79
|
+
if (!cancelled)
|
|
80
|
+
setRuntimeReady(true);
|
|
81
|
+
});
|
|
82
|
+
return () => {
|
|
83
|
+
cancelled = true;
|
|
84
|
+
};
|
|
85
|
+
}, [initializeRuntime]);
|
|
86
|
+
const returnToCheck = useCallback(() => {
|
|
87
|
+
installActionPendingRef.current = false;
|
|
88
|
+
autoChainAdvancedRef.current = false;
|
|
89
|
+
setPage("check");
|
|
90
|
+
setCheckGeneration((generation) => generation + 1);
|
|
91
|
+
}, []);
|
|
92
|
+
const navigateToProgress = useCallback(() => {
|
|
93
|
+
installActionPendingRef.current = true;
|
|
94
|
+
ota.clearProgress();
|
|
95
|
+
setPage("progress");
|
|
96
|
+
}, []);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!runtimeReady || page !== "check")
|
|
99
|
+
return;
|
|
100
|
+
const MIN_DISPLAY_TIME_MS = 1100;
|
|
101
|
+
const MAX_WAIT_FOR_VERSION_INFO_MS = 10_000;
|
|
102
|
+
const checkKey = String(checkGeneration);
|
|
103
|
+
if (activeCheckKeyRef.current !== checkKey) {
|
|
104
|
+
activeCheckKeyRef.current = checkKey;
|
|
105
|
+
checkStartedRef.current = false;
|
|
106
|
+
checkCompletedRef.current = false;
|
|
107
|
+
selectedCheckResultRef.current = null;
|
|
108
|
+
installActionPendingRef.current = false;
|
|
109
|
+
setCheckState("checking");
|
|
110
|
+
}
|
|
111
|
+
const myGeneration = ++performCheckGenerationRef.current;
|
|
112
|
+
let cancelled = false;
|
|
113
|
+
let reconnectTimeout = null;
|
|
114
|
+
const performCheck = async () => {
|
|
115
|
+
if (checkCompletedRef.current)
|
|
116
|
+
return;
|
|
117
|
+
if (!otaSnapshot.connected) {
|
|
118
|
+
if (isOtaAutoChainActive()) {
|
|
119
|
+
const remainingMs = otaAutoChainReconnectWaitRemaining();
|
|
120
|
+
if (remainingMs === null)
|
|
121
|
+
return;
|
|
122
|
+
reconnectTimeout = setTimeout(() => {
|
|
123
|
+
if (cancelled || myGeneration !== performCheckGenerationRef.current || ota.snapshot().connected)
|
|
124
|
+
return;
|
|
125
|
+
stopOtaAutoChain();
|
|
126
|
+
checkCompletedRef.current = true;
|
|
127
|
+
setCheckState("error");
|
|
128
|
+
}, remainingMs);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (checkStartedRef.current) {
|
|
132
|
+
stopOtaAutoChain();
|
|
133
|
+
checkCompletedRef.current = true;
|
|
134
|
+
setCheckState("error");
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
checkCompletedRef.current = true;
|
|
138
|
+
onFinishedRef.current?.();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
clearOtaAutoChainReconnectWait();
|
|
142
|
+
checkStartedRef.current = true;
|
|
143
|
+
const startTime = Date.now();
|
|
144
|
+
try {
|
|
145
|
+
const checkOptions = {
|
|
146
|
+
waitForBuildNumberMs: MAX_WAIT_FOR_VERSION_INFO_MS,
|
|
147
|
+
waitForBesVersionMs: 5000,
|
|
148
|
+
waitForMtkVersionMs: 2000,
|
|
149
|
+
refreshVersionInfo: true,
|
|
150
|
+
fixClockBeforeCheck: false,
|
|
151
|
+
};
|
|
152
|
+
let result = await ota.checkForUpdates(checkOptions);
|
|
153
|
+
if (cancelled || myGeneration !== performCheckGenerationRef.current)
|
|
154
|
+
return;
|
|
155
|
+
if (!result.hasCheckCompleted && result.checkFailureReason === "network" && isOtaAutoChainActive()) {
|
|
156
|
+
await new Promise((resolve) => setTimeout(resolve, AUTO_CHAIN_NETWORK_RETRY_DELAY_MS));
|
|
157
|
+
if (cancelled || myGeneration !== performCheckGenerationRef.current)
|
|
158
|
+
return;
|
|
159
|
+
result = await ota.checkForUpdates(checkOptions);
|
|
160
|
+
}
|
|
161
|
+
if (cancelled || myGeneration !== performCheckGenerationRef.current)
|
|
162
|
+
return;
|
|
163
|
+
selectedCheckResultRef.current = result;
|
|
164
|
+
await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))));
|
|
165
|
+
if (cancelled || myGeneration !== performCheckGenerationRef.current)
|
|
166
|
+
return;
|
|
167
|
+
if (result.skippedReason === "disconnected") {
|
|
168
|
+
stopOtaAutoChain();
|
|
169
|
+
checkCompletedRef.current = true;
|
|
170
|
+
setCheckState("error");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (result.skippedReason === "missing_build") {
|
|
174
|
+
checkCompletedRef.current = true;
|
|
175
|
+
if (isOtaAutoChainActive()) {
|
|
176
|
+
stopOtaAutoChain();
|
|
177
|
+
setCheckState("error");
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
onFinishedRef.current?.();
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (result.skippedReason === "dev_build") {
|
|
185
|
+
stopOtaAutoChain();
|
|
186
|
+
checkCompletedRef.current = true;
|
|
187
|
+
ota.clearUpdateAvailable();
|
|
188
|
+
setCheckState("dev_build");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (!result.hasCheckCompleted) {
|
|
192
|
+
stopOtaAutoChain();
|
|
193
|
+
checkCompletedRef.current = true;
|
|
194
|
+
setErrorKind(result.checkFailureReason === "pin_unavailable" ? "pin_unavailable" : "network");
|
|
195
|
+
setCheckState("error");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (result.updateAvailable && result.updateInfo) {
|
|
199
|
+
setIsUpdateRequired(result.isRequired);
|
|
200
|
+
setIsVersionChange(result.updateInfo.isDowngrade === true);
|
|
201
|
+
const fingerprint = otaAutoChainFingerprint(result);
|
|
202
|
+
setUpdateFingerprint(fingerprint);
|
|
203
|
+
if (isOtaAutoChainActive()) {
|
|
204
|
+
const snapshot = ota.snapshot();
|
|
205
|
+
if (!snapshot.wifiStatusKnown)
|
|
206
|
+
return;
|
|
207
|
+
if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {
|
|
208
|
+
stopOtaAutoChain();
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
const admission = tryAdvanceOtaAutoChain(fingerprint, result.updateInfo.isDowngrade === true);
|
|
212
|
+
if (admission.advance) {
|
|
213
|
+
checkCompletedRef.current = true;
|
|
214
|
+
ota.installSession.prepare(result);
|
|
215
|
+
navigateToProgress();
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
checkCompletedRef.current = true;
|
|
221
|
+
setCheckState("update_available");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
stopOtaAutoChain();
|
|
225
|
+
checkCompletedRef.current = true;
|
|
226
|
+
ota.clearUpdateAvailable();
|
|
227
|
+
setCheckState("no_update");
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
console.error("OTA check failed:", error);
|
|
231
|
+
await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))));
|
|
232
|
+
if (cancelled || myGeneration !== performCheckGenerationRef.current)
|
|
233
|
+
return;
|
|
234
|
+
stopOtaAutoChain();
|
|
235
|
+
checkCompletedRef.current = true;
|
|
236
|
+
setErrorKind("network");
|
|
237
|
+
setCheckState("error");
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
void performCheck();
|
|
241
|
+
return () => {
|
|
242
|
+
cancelled = true;
|
|
243
|
+
if (reconnectTimeout)
|
|
244
|
+
clearTimeout(reconnectTimeout);
|
|
245
|
+
};
|
|
246
|
+
}, [checkGeneration, navigateToProgress, otaSnapshot.connected, otaSnapshot.wifiStatusKnown, page, runtimeReady]);
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
if (!runtimeReady || page !== "progress")
|
|
249
|
+
return;
|
|
250
|
+
ota.installSession.attach();
|
|
251
|
+
return () => ota.installSession.detach();
|
|
252
|
+
}, [page, runtimeReady]);
|
|
253
|
+
const firmwareRestarting = page === "progress" &&
|
|
254
|
+
((!installSnapshot.connected && installSnapshot.displayState === "restarting") ||
|
|
255
|
+
installSnapshot.versionChangePhase === "restarting");
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
if (page !== "progress")
|
|
258
|
+
return;
|
|
259
|
+
onFirmwareRestartingChangeRef.current?.(firmwareRestarting, true);
|
|
260
|
+
}, [firmwareRestarting, page]);
|
|
261
|
+
useEffect(() => {
|
|
262
|
+
if (page !== "progress")
|
|
263
|
+
return;
|
|
264
|
+
return () => {
|
|
265
|
+
onFirmwareRestartingChangeRef.current?.(false, false);
|
|
266
|
+
};
|
|
267
|
+
}, [page]);
|
|
268
|
+
useEffect(() => {
|
|
269
|
+
if (page !== "progress" ||
|
|
270
|
+
installSnapshot.displayState !== "complete" ||
|
|
271
|
+
!installSnapshot.connected ||
|
|
272
|
+
!isOtaAutoChainActive() ||
|
|
273
|
+
autoChainAdvancedRef.current) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const timeout = setTimeout(async () => {
|
|
277
|
+
if (!isOtaAutoChainActive())
|
|
278
|
+
return;
|
|
279
|
+
autoChainAdvancedRef.current = true;
|
|
280
|
+
await ota.installSession.finish();
|
|
281
|
+
returnToCheck();
|
|
282
|
+
}, AUTO_CHAIN_COMPLETE_DELAY_MS);
|
|
283
|
+
return () => clearTimeout(timeout);
|
|
284
|
+
}, [installSnapshot.connected, installSnapshot.displayState, page, returnToCheck]);
|
|
285
|
+
const check = useCallback(() => {
|
|
286
|
+
setPage("check");
|
|
287
|
+
setCheckState("checking");
|
|
288
|
+
setCheckGeneration((generation) => generation + 1);
|
|
289
|
+
}, []);
|
|
290
|
+
const install = useCallback(() => {
|
|
291
|
+
if (installActionPendingRef.current || page !== "check")
|
|
292
|
+
return;
|
|
293
|
+
const result = selectedCheckResultRef.current;
|
|
294
|
+
if (!result) {
|
|
295
|
+
setErrorKind("network");
|
|
296
|
+
setCheckState("error");
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const snapshot = ota.snapshot();
|
|
300
|
+
if (!snapshot.wifiStatusKnown) {
|
|
301
|
+
check();
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {
|
|
305
|
+
onOpenWifiSetupRef.current?.();
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
ota.installSession.prepare(result);
|
|
309
|
+
if (updateFingerprint)
|
|
310
|
+
beginOtaAutoChain(updateFingerprint, isVersionChange);
|
|
311
|
+
navigateToProgress();
|
|
312
|
+
}, [check, isVersionChange, navigateToProgress, page, updateFingerprint]);
|
|
313
|
+
const retryInstall = useCallback(() => {
|
|
314
|
+
if (page !== "progress")
|
|
315
|
+
return;
|
|
316
|
+
onFirmwareRestartingChangeRef.current?.(false, true);
|
|
317
|
+
ota.installSession.retry();
|
|
318
|
+
}, [page]);
|
|
319
|
+
const finish = useCallback(async () => {
|
|
320
|
+
if (page === "check") {
|
|
321
|
+
onFinishedRef.current?.();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (installSnapshot.displayState === "restarting")
|
|
325
|
+
stopOtaAutoChain();
|
|
326
|
+
const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(installSnapshot.otaStatus, installSnapshot.otaProgress, installSnapshot.errorMsg);
|
|
327
|
+
if (requiresGlassesReboot)
|
|
328
|
+
stopOtaAutoChain();
|
|
329
|
+
await ota.installSession.finish();
|
|
330
|
+
returnToCheck();
|
|
331
|
+
}, [installSnapshot, page, returnToCheck]);
|
|
332
|
+
const discard = useCallback(async () => {
|
|
333
|
+
if (page !== "progress")
|
|
334
|
+
return;
|
|
335
|
+
stopOtaAutoChain();
|
|
336
|
+
await ota.installSession.discard();
|
|
337
|
+
returnToCheck();
|
|
338
|
+
}, [page, returnToCheck]);
|
|
339
|
+
const openWifiSetup = useCallback(() => {
|
|
340
|
+
if (page === "progress")
|
|
341
|
+
stopOtaAutoChain();
|
|
342
|
+
onOpenWifiSetupRef.current?.();
|
|
343
|
+
}, [page]);
|
|
344
|
+
const state = useMemo(() => {
|
|
345
|
+
const hotspotSupported = otaSnapshot.hotspotOtaVersion === 1;
|
|
346
|
+
const canInstall = otaSnapshot.wifiStatusKnown && (otaSnapshot.wifiConnected || hotspotSupported);
|
|
347
|
+
if (!runtimeReady) {
|
|
348
|
+
return {
|
|
349
|
+
screen: "initializing",
|
|
350
|
+
connected: otaSnapshot.connected,
|
|
351
|
+
transport: null,
|
|
352
|
+
updateRequired: isUpdateRequired,
|
|
353
|
+
versionChange: isVersionChange,
|
|
354
|
+
versionChangeConverged: false,
|
|
355
|
+
versionChangePhase: null,
|
|
356
|
+
wifiConnected: otaSnapshot.wifiConnected,
|
|
357
|
+
wifiStatusKnown: otaSnapshot.wifiStatusKnown,
|
|
358
|
+
hotspotSupported,
|
|
359
|
+
hotspotPhase: "idle",
|
|
360
|
+
hotspotArtifactPercent: null,
|
|
361
|
+
phase: null,
|
|
362
|
+
step: null,
|
|
363
|
+
currentStep: null,
|
|
364
|
+
totalSteps: null,
|
|
365
|
+
progress: null,
|
|
366
|
+
installingApkOnly: false,
|
|
367
|
+
firmwareRestarting: false,
|
|
368
|
+
error: null,
|
|
369
|
+
canInstall: false,
|
|
370
|
+
canRetry: false,
|
|
371
|
+
canFinish: false,
|
|
372
|
+
canDismiss: false,
|
|
373
|
+
canDiscard: false,
|
|
374
|
+
canOpenWifiSetup: false,
|
|
375
|
+
continueDisabled: false,
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
if (page === "check") {
|
|
379
|
+
const wifiRequired = otaSnapshot.wifiStatusKnown && !otaSnapshot.wifiConnected && !hotspotSupported;
|
|
380
|
+
const screen = checkState === "checking"
|
|
381
|
+
? "checking"
|
|
382
|
+
: checkState === "update_available"
|
|
383
|
+
? wifiRequired
|
|
384
|
+
? "wifi_required"
|
|
385
|
+
: "update_available"
|
|
386
|
+
: checkState === "no_update"
|
|
387
|
+
? "up_to_date"
|
|
388
|
+
: checkState === "dev_build"
|
|
389
|
+
? "dev_build"
|
|
390
|
+
: errorKind === "pin_unavailable"
|
|
391
|
+
? "update_info_unavailable"
|
|
392
|
+
: "check_failed";
|
|
393
|
+
const error = screen === "check_failed"
|
|
394
|
+
? { code: "check_failed", message: "Couldn't check for updates. Please check your connection and try again." }
|
|
395
|
+
: screen === "update_info_unavailable"
|
|
396
|
+
? { code: "update_info_unavailable", message: "Update information for this app version is unavailable." }
|
|
397
|
+
: null;
|
|
398
|
+
return {
|
|
399
|
+
screen,
|
|
400
|
+
connected: otaSnapshot.connected,
|
|
401
|
+
transport: otaSnapshot.wifiConnected ? "wifi" : hotspotSupported ? "hotspot" : null,
|
|
402
|
+
updateRequired: isUpdateRequired,
|
|
403
|
+
versionChange: isVersionChange,
|
|
404
|
+
versionChangeConverged: false,
|
|
405
|
+
versionChangePhase: null,
|
|
406
|
+
wifiConnected: otaSnapshot.wifiConnected,
|
|
407
|
+
wifiStatusKnown: otaSnapshot.wifiStatusKnown,
|
|
408
|
+
hotspotSupported,
|
|
409
|
+
hotspotPhase: "idle",
|
|
410
|
+
hotspotArtifactPercent: null,
|
|
411
|
+
phase: null,
|
|
412
|
+
step: null,
|
|
413
|
+
currentStep: null,
|
|
414
|
+
totalSteps: null,
|
|
415
|
+
progress: null,
|
|
416
|
+
installingApkOnly: false,
|
|
417
|
+
firmwareRestarting: false,
|
|
418
|
+
error,
|
|
419
|
+
canInstall: screen === "update_available" && canInstall,
|
|
420
|
+
canRetry: screen === "check_failed",
|
|
421
|
+
canFinish: screen === "up_to_date" || screen === "dev_build" || screen === "update_info_unavailable",
|
|
422
|
+
canDismiss: (screen === "update_available" || screen === "wifi_required") && !isUpdateRequired,
|
|
423
|
+
canDiscard: false,
|
|
424
|
+
canOpenWifiSetup: screen === "wifi_required",
|
|
425
|
+
continueDisabled: false,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(installSnapshot.otaStatus, installSnapshot.otaProgress, installSnapshot.errorMsg);
|
|
429
|
+
const showChangeWifi = shouldShowChangeWifiForOtaDownloadFailure(installSnapshot.otaStatus, installSnapshot.otaProgress, installSnapshot.errorMsg);
|
|
430
|
+
const displayedError = requiresGlassesReboot
|
|
431
|
+
? BES_INSTALL_RESTART_MESSAGE
|
|
432
|
+
: installSnapshot.errorMsg || getOtaErrorMessage(installSnapshot.otaStatus?.error);
|
|
433
|
+
const screen = progressScreen(installSnapshot);
|
|
434
|
+
const error = screen === "failed"
|
|
435
|
+
? {
|
|
436
|
+
code: requiresGlassesReboot ? "bes_restart_required" : "install_failed",
|
|
437
|
+
message: displayedError,
|
|
438
|
+
}
|
|
439
|
+
: null;
|
|
440
|
+
const totalSteps = installSnapshot.otaStatus?.totalSteps ?? null;
|
|
441
|
+
return {
|
|
442
|
+
screen,
|
|
443
|
+
connected: installSnapshot.connected,
|
|
444
|
+
transport: installSnapshot.transport,
|
|
445
|
+
updateRequired: isUpdateRequired,
|
|
446
|
+
versionChange: installSnapshot.isVersionChange,
|
|
447
|
+
versionChangeConverged: installSnapshot.versionChangeConverged,
|
|
448
|
+
versionChangePhase: installSnapshot.versionChangePhase,
|
|
449
|
+
wifiConnected: otaSnapshot.wifiConnected,
|
|
450
|
+
wifiStatusKnown: otaSnapshot.wifiStatusKnown,
|
|
451
|
+
hotspotSupported,
|
|
452
|
+
hotspotPhase: installSnapshot.hotspotPhase,
|
|
453
|
+
hotspotArtifactPercent: installSnapshot.hotspotArtifactPercent,
|
|
454
|
+
phase: installSnapshot.otaStatus?.phase ?? installSnapshot.otaProgress?.stage ?? null,
|
|
455
|
+
step: installSnapshot.otaStatus?.stepType ?? null,
|
|
456
|
+
currentStep: installSnapshot.otaStatus?.currentStep ?? null,
|
|
457
|
+
totalSteps,
|
|
458
|
+
progress: installProgress(installSnapshot),
|
|
459
|
+
installingApkOnly: installSnapshot.otaStatus?.stepType === "apk" &&
|
|
460
|
+
installSnapshot.otaStatus.phase === "install" &&
|
|
461
|
+
totalSteps === 1,
|
|
462
|
+
firmwareRestarting,
|
|
463
|
+
error,
|
|
464
|
+
canInstall: false,
|
|
465
|
+
canRetry: screen === "failed" && !requiresGlassesReboot,
|
|
466
|
+
canFinish: screen === "complete" || screen === "restarting" || (screen === "failed" && requiresGlassesReboot),
|
|
467
|
+
canDismiss: false,
|
|
468
|
+
canDiscard: screen === "disconnected",
|
|
469
|
+
canOpenWifiSetup: screen === "failed" && showChangeWifi,
|
|
470
|
+
continueDisabled: installSnapshot.continueButtonDisabled,
|
|
471
|
+
};
|
|
472
|
+
}, [
|
|
473
|
+
checkState,
|
|
474
|
+
errorKind,
|
|
475
|
+
firmwareRestarting,
|
|
476
|
+
installSnapshot,
|
|
477
|
+
isUpdateRequired,
|
|
478
|
+
isVersionChange,
|
|
479
|
+
otaSnapshot,
|
|
480
|
+
page,
|
|
481
|
+
runtimeReady,
|
|
482
|
+
]);
|
|
483
|
+
return useMemo(() => ({ state, check, retryCheck: check, install, retryInstall, finish, discard, openWifiSetup }), [check, discard, finish, install, openWifiSetup, retryInstall, state]);
|
|
484
|
+
}
|
|
485
|
+
//# sourceMappingURL=useMentraLiveOta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMentraLiveOta.js","sourceRoot":"","sources":["../../src/react/useMentraLiveOta.ts"],"names":[],"mappings":"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","sourcesContent":["import {useCallback, useEffect, useMemo, useRef, useState} from \"react\"\n\nimport {ota} from \"../facades/ota\"\nimport {\n beginOtaAutoChain,\n clearOtaAutoChainReconnectWait,\n isOtaAutoChainActive,\n otaAutoChainFingerprint,\n otaAutoChainReconnectWaitRemaining,\n stopOtaAutoChain,\n tryAdvanceOtaAutoChain,\n} from \"../services/OtaAutoChain\"\nimport {\n BES_INSTALL_RESTART_MESSAGE,\n getOtaErrorMessage,\n shouldRequireGlassesRebootForBesFailure,\n shouldShowChangeWifiForOtaDownloadFailure,\n} from \"../services/OtaErrorMapping\"\nimport type {OtaInstallSnapshot} from \"../services/OtaInstallCoordinator\"\nimport type {OtaCheckCurrentGlassesResult} from \"../services/OtaUpdateCheckService\"\nimport {useEngineSnapshot} from \"./useEngineSnapshot\"\n\nexport type MentraLiveOtaFlowPage = \"check\" | \"progress\"\n\nexport type MentraLiveOtaScreen =\n | \"initializing\"\n | \"checking\"\n | \"update_available\"\n | \"wifi_required\"\n | \"up_to_date\"\n | \"dev_build\"\n | \"check_failed\"\n | \"update_info_unavailable\"\n | \"starting\"\n | \"preparing_hotspot\"\n | \"updating\"\n | \"restarting\"\n | \"verifying\"\n | \"complete\"\n | \"failed\"\n | \"disconnected\"\n\nexport type MentraLiveOtaErrorCode =\n | \"check_failed\"\n | \"update_info_unavailable\"\n | \"install_failed\"\n | \"bes_restart_required\"\n\nexport type MentraLiveOtaError = {\n code: MentraLiveOtaErrorCode\n message: string\n}\n\nexport type MentraLiveOtaTransport = \"wifi\" | \"hotspot\"\nexport type MentraLiveOtaHotspotPhase = \"idle\" | \"downloading\" | \"starting_hotspot\" | \"joining_hotspot\" | \"serving\"\nexport type MentraLiveOtaInstallPhase = \"download\" | \"install\"\nexport type MentraLiveOtaStep = \"apk\" | \"mtk\" | \"bes\"\n\nexport type MentraLiveOtaState = {\n screen: MentraLiveOtaScreen\n connected: boolean\n transport: MentraLiveOtaTransport | null\n updateRequired: boolean\n versionChange: boolean\n versionChangeConverged: boolean\n versionChangePhase: \"installing\" | \"restarting\" | \"verifying\" | null\n wifiConnected: boolean\n wifiStatusKnown: boolean\n hotspotSupported: boolean\n hotspotPhase: MentraLiveOtaHotspotPhase\n hotspotArtifactPercent: number | null\n phase: MentraLiveOtaInstallPhase | null\n step: MentraLiveOtaStep | null\n currentStep: number | null\n totalSteps: number | null\n progress: number | null\n installingApkOnly: boolean\n firmwareRestarting: boolean\n error: MentraLiveOtaError | null\n canInstall: boolean\n canRetry: boolean\n canFinish: boolean\n canDismiss: boolean\n canDiscard: boolean\n canOpenWifiSetup: boolean\n continueDisabled: boolean\n}\n\nexport type UseMentraLiveOtaOptions = {\n /** Entry page. `progress` exists for interrupted-session recovery. */\n initialPage?: MentraLiveOtaFlowPage\n /** Start Engine's OTA-only projections. Full Engine hosts should pass false. */\n initializeRuntime?: boolean\n /** Called after the final check or when an optional update is dismissed. */\n onFinished?: () => void\n /** Host-owned Wi-Fi setup for glasses without hotspot OTA support. */\n onOpenWifiSetup?: () => void\n /** Lets a host coordinate its connection overlay with OTA firmware restarts. */\n onFirmwareRestartingChange?: (restarting: boolean, progressActive: boolean) => void\n}\n\nexport type MentraLiveOtaController = {\n state: MentraLiveOtaState\n check: () => void\n retryCheck: () => void\n install: () => void\n retryInstall: () => void\n finish: () => void\n discard: () => void\n openWifiSetup: () => void\n}\n\ntype CheckState = \"checking\" | \"update_available\" | \"no_update\" | \"dev_build\" | \"error\"\n\nconst AUTO_CHAIN_NETWORK_RETRY_DELAY_MS = 5000\nconst AUTO_CHAIN_COMPLETE_DELAY_MS = 750\n\nfunction installProgress(snapshot: OtaInstallSnapshot): number | null {\n if (snapshot.displayState !== \"updating\") return null\n const {otaStatus} = snapshot\n const isDownload = otaStatus?.phase === \"download\"\n const totalSteps = otaStatus?.totalSteps ?? 1\n const rawPercent = isDownload\n ? (otaStatus?.stepPercent ?? 0)\n : totalSteps >= 2\n ? (otaStatus?.overallPercent ?? 0)\n : (otaStatus?.stepPercent ?? 0)\n return Math.min(Math.max(rawPercent, snapshot.mtkInstallStallSimulatedPercent ?? 0, 0), 100)\n}\n\nfunction progressScreen(snapshot: OtaInstallSnapshot): MentraLiveOtaScreen {\n if (snapshot.versionChangePhase === \"restarting\") return \"restarting\"\n if (snapshot.versionChangePhase === \"verifying\") return \"verifying\"\n switch (snapshot.displayState) {\n case \"starting\":\n return snapshot.hotspotPhase === \"idle\" || snapshot.hotspotPhase === \"serving\" ? \"starting\" : \"preparing_hotspot\"\n case \"updating\":\n return \"updating\"\n case \"restarting\":\n return \"restarting\"\n case \"complete\":\n return \"complete\"\n case \"failed\":\n return \"failed\"\n default:\n return \"disconnected\"\n }\n}\n\n/**\n * Headless Mentra Live OTA flow. Engine owns checking, hotspot staging,\n * APK/MTK/BES sequencing, restart recovery, retries, and verification; the host\n * renders semantic state and invokes these idempotent actions.\n */\nexport function useMentraLiveOta(options: UseMentraLiveOtaOptions = {}): MentraLiveOtaController {\n const {\n initialPage = \"check\",\n initializeRuntime = true,\n onFinished,\n onFirmwareRestartingChange,\n onOpenWifiSetup,\n } = options\n const otaSnapshot = useEngineSnapshot(ota.snapshot, ota.onSnapshot)\n const installSnapshot = useEngineSnapshot(ota.installSession.snapshot, ota.installSession.onSnapshot)\n const [page, setPage] = useState<MentraLiveOtaFlowPage>(initialPage)\n const [runtimeReady, setRuntimeReady] = useState(!initializeRuntime)\n const [checkState, setCheckState] = useState<CheckState>(\"checking\")\n const [isUpdateRequired, setIsUpdateRequired] = useState(true)\n const [isVersionChange, setIsVersionChange] = useState(false)\n const [errorKind, setErrorKind] = useState<\"network\" | \"pin_unavailable\">(\"network\")\n const [updateFingerprint, setUpdateFingerprint] = useState<string | null>(null)\n const [checkGeneration, setCheckGeneration] = useState(0)\n const performCheckGenerationRef = useRef(0)\n const activeCheckKeyRef = useRef<string | null>(null)\n const checkStartedRef = useRef(false)\n const checkCompletedRef = useRef(false)\n const selectedCheckResultRef = useRef<OtaCheckCurrentGlassesResult | null>(null)\n const autoChainAdvancedRef = useRef(false)\n const installActionPendingRef = useRef(false)\n const onFinishedRef = useRef(onFinished)\n const onOpenWifiSetupRef = useRef(onOpenWifiSetup)\n const onFirmwareRestartingChangeRef = useRef(onFirmwareRestartingChange)\n onFinishedRef.current = onFinished\n onOpenWifiSetupRef.current = onOpenWifiSetup\n onFirmwareRestartingChangeRef.current = onFirmwareRestartingChange\n\n useEffect(() => {\n if (!initializeRuntime) {\n setRuntimeReady(true)\n return\n }\n let cancelled = false\n setRuntimeReady(false)\n void ota.initialize().finally(() => {\n if (!cancelled) setRuntimeReady(true)\n })\n return () => {\n cancelled = true\n }\n }, [initializeRuntime])\n\n const returnToCheck = useCallback(() => {\n installActionPendingRef.current = false\n autoChainAdvancedRef.current = false\n setPage(\"check\")\n setCheckGeneration((generation) => generation + 1)\n }, [])\n\n const navigateToProgress = useCallback(() => {\n installActionPendingRef.current = true\n ota.clearProgress()\n setPage(\"progress\")\n }, [])\n\n useEffect(() => {\n if (!runtimeReady || page !== \"check\") return\n const MIN_DISPLAY_TIME_MS = 1100\n const MAX_WAIT_FOR_VERSION_INFO_MS = 10_000\n const checkKey = String(checkGeneration)\n if (activeCheckKeyRef.current !== checkKey) {\n activeCheckKeyRef.current = checkKey\n checkStartedRef.current = false\n checkCompletedRef.current = false\n selectedCheckResultRef.current = null\n installActionPendingRef.current = false\n setCheckState(\"checking\")\n }\n\n const myGeneration = ++performCheckGenerationRef.current\n let cancelled = false\n let reconnectTimeout: ReturnType<typeof setTimeout> | null = null\n\n const performCheck = async () => {\n if (checkCompletedRef.current) return\n if (!otaSnapshot.connected) {\n if (isOtaAutoChainActive()) {\n const remainingMs = otaAutoChainReconnectWaitRemaining()\n if (remainingMs === null) return\n reconnectTimeout = setTimeout(() => {\n if (cancelled || myGeneration !== performCheckGenerationRef.current || ota.snapshot().connected) return\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setCheckState(\"error\")\n }, remainingMs)\n return\n }\n if (checkStartedRef.current) {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setCheckState(\"error\")\n return\n }\n checkCompletedRef.current = true\n onFinishedRef.current?.()\n return\n }\n\n clearOtaAutoChainReconnectWait()\n checkStartedRef.current = true\n const startTime = Date.now()\n try {\n const checkOptions = {\n waitForBuildNumberMs: MAX_WAIT_FOR_VERSION_INFO_MS,\n waitForBesVersionMs: 5000,\n waitForMtkVersionMs: 2000,\n refreshVersionInfo: true,\n fixClockBeforeCheck: false,\n }\n let result = await ota.checkForUpdates(checkOptions)\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n if (!result.hasCheckCompleted && result.checkFailureReason === \"network\" && isOtaAutoChainActive()) {\n await new Promise((resolve) => setTimeout(resolve, AUTO_CHAIN_NETWORK_RETRY_DELAY_MS))\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n result = await ota.checkForUpdates(checkOptions)\n }\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n selectedCheckResultRef.current = result\n await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))))\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n\n if (result.skippedReason === \"disconnected\") {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setCheckState(\"error\")\n return\n }\n if (result.skippedReason === \"missing_build\") {\n checkCompletedRef.current = true\n if (isOtaAutoChainActive()) {\n stopOtaAutoChain()\n setCheckState(\"error\")\n } else {\n onFinishedRef.current?.()\n }\n return\n }\n if (result.skippedReason === \"dev_build\") {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n ota.clearUpdateAvailable()\n setCheckState(\"dev_build\")\n return\n }\n if (!result.hasCheckCompleted) {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setErrorKind(result.checkFailureReason === \"pin_unavailable\" ? \"pin_unavailable\" : \"network\")\n setCheckState(\"error\")\n return\n }\n if (result.updateAvailable && result.updateInfo) {\n setIsUpdateRequired(result.isRequired)\n setIsVersionChange(result.updateInfo.isDowngrade === true)\n const fingerprint = otaAutoChainFingerprint(result)\n setUpdateFingerprint(fingerprint)\n if (isOtaAutoChainActive()) {\n const snapshot = ota.snapshot()\n if (!snapshot.wifiStatusKnown) return\n if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {\n stopOtaAutoChain()\n } else {\n const admission = tryAdvanceOtaAutoChain(fingerprint, result.updateInfo.isDowngrade === true)\n if (admission.advance) {\n checkCompletedRef.current = true\n ota.installSession.prepare(result)\n navigateToProgress()\n return\n }\n }\n }\n checkCompletedRef.current = true\n setCheckState(\"update_available\")\n return\n }\n stopOtaAutoChain()\n checkCompletedRef.current = true\n ota.clearUpdateAvailable()\n setCheckState(\"no_update\")\n } catch (error) {\n console.error(\"OTA check failed:\", error)\n await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))))\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setErrorKind(\"network\")\n setCheckState(\"error\")\n }\n }\n\n void performCheck()\n return () => {\n cancelled = true\n if (reconnectTimeout) clearTimeout(reconnectTimeout)\n }\n }, [checkGeneration, navigateToProgress, otaSnapshot.connected, otaSnapshot.wifiStatusKnown, page, runtimeReady])\n\n useEffect(() => {\n if (!runtimeReady || page !== \"progress\") return\n ota.installSession.attach()\n return () => ota.installSession.detach()\n }, [page, runtimeReady])\n\n const firmwareRestarting =\n page === \"progress\" &&\n ((!installSnapshot.connected && installSnapshot.displayState === \"restarting\") ||\n installSnapshot.versionChangePhase === \"restarting\")\n\n useEffect(() => {\n if (page !== \"progress\") return\n onFirmwareRestartingChangeRef.current?.(firmwareRestarting, true)\n }, [firmwareRestarting, page])\n\n useEffect(() => {\n if (page !== \"progress\") return\n return () => {\n onFirmwareRestartingChangeRef.current?.(false, false)\n }\n }, [page])\n\n useEffect(() => {\n if (\n page !== \"progress\" ||\n installSnapshot.displayState !== \"complete\" ||\n !installSnapshot.connected ||\n !isOtaAutoChainActive() ||\n autoChainAdvancedRef.current\n ) {\n return\n }\n const timeout = setTimeout(async () => {\n if (!isOtaAutoChainActive()) return\n autoChainAdvancedRef.current = true\n await ota.installSession.finish()\n returnToCheck()\n }, AUTO_CHAIN_COMPLETE_DELAY_MS)\n return () => clearTimeout(timeout)\n }, [installSnapshot.connected, installSnapshot.displayState, page, returnToCheck])\n\n const check = useCallback(() => {\n setPage(\"check\")\n setCheckState(\"checking\")\n setCheckGeneration((generation) => generation + 1)\n }, [])\n\n const install = useCallback(() => {\n if (installActionPendingRef.current || page !== \"check\") return\n const result = selectedCheckResultRef.current\n if (!result) {\n setErrorKind(\"network\")\n setCheckState(\"error\")\n return\n }\n const snapshot = ota.snapshot()\n if (!snapshot.wifiStatusKnown) {\n check()\n return\n }\n if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {\n onOpenWifiSetupRef.current?.()\n return\n }\n ota.installSession.prepare(result)\n if (updateFingerprint) beginOtaAutoChain(updateFingerprint, isVersionChange)\n navigateToProgress()\n }, [check, isVersionChange, navigateToProgress, page, updateFingerprint])\n\n const retryInstall = useCallback(() => {\n if (page !== \"progress\") return\n onFirmwareRestartingChangeRef.current?.(false, true)\n ota.installSession.retry()\n }, [page])\n\n const finish = useCallback(async () => {\n if (page === \"check\") {\n onFinishedRef.current?.()\n return\n }\n if (installSnapshot.displayState === \"restarting\") stopOtaAutoChain()\n const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(\n installSnapshot.otaStatus,\n installSnapshot.otaProgress,\n installSnapshot.errorMsg,\n )\n if (requiresGlassesReboot) stopOtaAutoChain()\n await ota.installSession.finish()\n returnToCheck()\n }, [installSnapshot, page, returnToCheck])\n\n const discard = useCallback(async () => {\n if (page !== \"progress\") return\n stopOtaAutoChain()\n await ota.installSession.discard()\n returnToCheck()\n }, [page, returnToCheck])\n\n const openWifiSetup = useCallback(() => {\n if (page === \"progress\") stopOtaAutoChain()\n onOpenWifiSetupRef.current?.()\n }, [page])\n\n const state = useMemo<MentraLiveOtaState>(() => {\n const hotspotSupported = otaSnapshot.hotspotOtaVersion === 1\n const canInstall = otaSnapshot.wifiStatusKnown && (otaSnapshot.wifiConnected || hotspotSupported)\n if (!runtimeReady) {\n return {\n screen: \"initializing\",\n connected: otaSnapshot.connected,\n transport: null,\n updateRequired: isUpdateRequired,\n versionChange: isVersionChange,\n versionChangeConverged: false,\n versionChangePhase: null,\n wifiConnected: otaSnapshot.wifiConnected,\n wifiStatusKnown: otaSnapshot.wifiStatusKnown,\n hotspotSupported,\n hotspotPhase: \"idle\",\n hotspotArtifactPercent: null,\n phase: null,\n step: null,\n currentStep: null,\n totalSteps: null,\n progress: null,\n installingApkOnly: false,\n firmwareRestarting: false,\n error: null,\n canInstall: false,\n canRetry: false,\n canFinish: false,\n canDismiss: false,\n canDiscard: false,\n canOpenWifiSetup: false,\n continueDisabled: false,\n }\n }\n\n if (page === \"check\") {\n const wifiRequired = otaSnapshot.wifiStatusKnown && !otaSnapshot.wifiConnected && !hotspotSupported\n const screen: MentraLiveOtaScreen =\n checkState === \"checking\"\n ? \"checking\"\n : checkState === \"update_available\"\n ? wifiRequired\n ? \"wifi_required\"\n : \"update_available\"\n : checkState === \"no_update\"\n ? \"up_to_date\"\n : checkState === \"dev_build\"\n ? \"dev_build\"\n : errorKind === \"pin_unavailable\"\n ? \"update_info_unavailable\"\n : \"check_failed\"\n const error: MentraLiveOtaError | null =\n screen === \"check_failed\"\n ? {code: \"check_failed\", message: \"Couldn't check for updates. Please check your connection and try again.\"}\n : screen === \"update_info_unavailable\"\n ? {code: \"update_info_unavailable\", message: \"Update information for this app version is unavailable.\"}\n : null\n return {\n screen,\n connected: otaSnapshot.connected,\n transport: otaSnapshot.wifiConnected ? \"wifi\" : hotspotSupported ? \"hotspot\" : null,\n updateRequired: isUpdateRequired,\n versionChange: isVersionChange,\n versionChangeConverged: false,\n versionChangePhase: null,\n wifiConnected: otaSnapshot.wifiConnected,\n wifiStatusKnown: otaSnapshot.wifiStatusKnown,\n hotspotSupported,\n hotspotPhase: \"idle\",\n hotspotArtifactPercent: null,\n phase: null,\n step: null,\n currentStep: null,\n totalSteps: null,\n progress: null,\n installingApkOnly: false,\n firmwareRestarting: false,\n error,\n canInstall: screen === \"update_available\" && canInstall,\n canRetry: screen === \"check_failed\",\n canFinish: screen === \"up_to_date\" || screen === \"dev_build\" || screen === \"update_info_unavailable\",\n canDismiss: (screen === \"update_available\" || screen === \"wifi_required\") && !isUpdateRequired,\n canDiscard: false,\n canOpenWifiSetup: screen === \"wifi_required\",\n continueDisabled: false,\n }\n }\n\n const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(\n installSnapshot.otaStatus,\n installSnapshot.otaProgress,\n installSnapshot.errorMsg,\n )\n const showChangeWifi = shouldShowChangeWifiForOtaDownloadFailure(\n installSnapshot.otaStatus,\n installSnapshot.otaProgress,\n installSnapshot.errorMsg,\n )\n const displayedError = requiresGlassesReboot\n ? BES_INSTALL_RESTART_MESSAGE\n : installSnapshot.errorMsg || getOtaErrorMessage(installSnapshot.otaStatus?.error)\n const screen = progressScreen(installSnapshot)\n const error =\n screen === \"failed\"\n ? {\n code: requiresGlassesReboot ? (\"bes_restart_required\" as const) : (\"install_failed\" as const),\n message: displayedError,\n }\n : null\n const totalSteps = installSnapshot.otaStatus?.totalSteps ?? null\n return {\n screen,\n connected: installSnapshot.connected,\n transport: installSnapshot.transport,\n updateRequired: isUpdateRequired,\n versionChange: installSnapshot.isVersionChange,\n versionChangeConverged: installSnapshot.versionChangeConverged,\n versionChangePhase: installSnapshot.versionChangePhase,\n wifiConnected: otaSnapshot.wifiConnected,\n wifiStatusKnown: otaSnapshot.wifiStatusKnown,\n hotspotSupported,\n hotspotPhase: installSnapshot.hotspotPhase,\n hotspotArtifactPercent: installSnapshot.hotspotArtifactPercent,\n phase: installSnapshot.otaStatus?.phase ?? installSnapshot.otaProgress?.stage ?? null,\n step: installSnapshot.otaStatus?.stepType ?? null,\n currentStep: installSnapshot.otaStatus?.currentStep ?? null,\n totalSteps,\n progress: installProgress(installSnapshot),\n installingApkOnly:\n installSnapshot.otaStatus?.stepType === \"apk\" &&\n installSnapshot.otaStatus.phase === \"install\" &&\n totalSteps === 1,\n firmwareRestarting,\n error,\n canInstall: false,\n canRetry: screen === \"failed\" && !requiresGlassesReboot,\n canFinish: screen === \"complete\" || screen === \"restarting\" || (screen === \"failed\" && requiresGlassesReboot),\n canDismiss: false,\n canDiscard: screen === \"disconnected\",\n canOpenWifiSetup: screen === \"failed\" && showChangeWifi,\n continueDisabled: installSnapshot.continueButtonDisabled,\n }\n }, [\n checkState,\n errorKind,\n firmwareRestarting,\n installSnapshot,\n isUpdateRequired,\n isVersionChange,\n otaSnapshot,\n page,\n runtimeReady,\n ])\n\n return useMemo(\n () => ({state, check, retryCheck: check, install, retryInstall, finish, discard, openWifiSetup}),\n [check, discard, finish, install, openWifiSetup, retryInstall, state],\n )\n}\n"]}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Glasses status projection — engine-owned. Subscribes to the native bluetooth-sdk
|
|
3
|
+
* status events and projects them into the engine device stores, so engine's own
|
|
4
|
+
* services (which react to those stores) work for ANY host — not just the first-party
|
|
5
|
+
* Mentra app, where this used to live in MantleManager.
|
|
6
|
+
*
|
|
7
|
+
* This is the INBOUND mirror of GlassesSettingsSync: that pushes the settings store
|
|
8
|
+
* OUT to the device; this pulls device status IN to the stores. It's the feed that
|
|
9
|
+
* the rest of the engine runtime depends on (MicStateCoordinator, the settings-sync
|
|
10
|
+
* on-connect trigger, the facade read-models all read these stores).
|
|
11
|
+
*
|
|
12
|
+
* Started by `engine.start()`. Idempotent.
|
|
13
|
+
*/
|
|
14
|
+
import { type PublicGlassesStatus } from "@mentra/bluetooth-sdk";
|
|
15
|
+
export declare function startGlassesStatusProjection(forwarder?: (status: Partial<PublicGlassesStatus>) => void): Promise<void>;
|
|
3
16
|
export declare function stopGlassesStatusProjection(): void;
|
|
4
17
|
//# sourceMappingURL=GlassesStatusProjection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GlassesStatusProjection.d.ts","sourceRoot":"","sources":["../../src/services/GlassesStatusProjection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GlassesStatusProjection.d.ts","sourceRoot":"","sources":["../../src/services/GlassesStatusProjection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAqB,EAAC,KAAK,mBAAmB,EAAC,MAAM,uBAAuB,CAAA;AAS5E,wBAAgB,4BAA4B,CAC1C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,KAAK,IAAI,GACzD,OAAO,CAAC,IAAI,CAAC,CAiDf;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAMlD"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Started by `engine.start()`. Idempotent.
|
|
13
13
|
*/
|
|
14
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
14
|
+
import BluetoothSdk from "@mentra/bluetooth-sdk";
|
|
15
15
|
import { useCoreStore } from "../stores/core";
|
|
16
16
|
import { useGlassesStore } from "../stores/glasses";
|
|
17
17
|
let unsubs = [];
|
|
@@ -45,13 +45,13 @@ export function startGlassesStatusProjection(forwarder) {
|
|
|
45
45
|
console.warn("GlassesStatusProjection: getGlassesStatus failed", error);
|
|
46
46
|
});
|
|
47
47
|
// Bluetooth-adapter status -> core store.
|
|
48
|
-
unsubs.push(BluetoothSdk.
|
|
48
|
+
unsubs.push(BluetoothSdk.subscribeBluetoothStatus((changed) => {
|
|
49
49
|
bluetoothEventSeen = true;
|
|
50
50
|
useCoreStore.getState().setCoreInfo(changed);
|
|
51
51
|
}));
|
|
52
52
|
// Glasses status -> glasses store (+ optional full-runtime forwarding to local
|
|
53
53
|
// miniapps; clear any stale OTA-available flag on disconnect).
|
|
54
|
-
unsubs.push(BluetoothSdk.
|
|
54
|
+
unsubs.push(BluetoothSdk.subscribeGlassesStatus((changed) => {
|
|
55
55
|
glassesEventSeen = true;
|
|
56
56
|
useGlassesStore.getState().setGlassesInfo(changed);
|
|
57
57
|
glassesStatusForwarder?.(changed);
|