@mentra/engine 3.1.0-dev.4 → 3.1.0-dev.40
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 +5 -2
- package/build/engine.d.ts.map +1 -1
- package/build/facades/ota.d.ts +9 -6
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +6 -4
- package/build/facades/ota.js.map +1 -1
- package/build/facades/pairing.d.ts +4 -0
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +81 -7
- package/build/facades/pairing.js.map +1 -1
- package/build/generated/releaseMetadata.js +5 -5
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.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 +113 -352
- 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 +80 -0
- package/build/react/useMentraLiveOta.d.ts.map +1 -0
- package/build/react/useMentraLiveOta.js +550 -0
- package/build/react/useMentraLiveOta.js.map +1 -0
- package/build/services/BlobStore.d.ts +2 -0
- package/build/services/BlobStore.d.ts.map +1 -1
- package/build/services/BlobStore.js +63 -10
- package/build/services/BlobStore.js.map +1 -1
- 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/OtaAutoChain.d.ts +9 -2
- package/build/services/OtaAutoChain.d.ts.map +1 -1
- package/build/services/OtaAutoChain.js +10 -2
- package/build/services/OtaAutoChain.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 +4 -1
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +21 -5
- 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/services/otaReleaseVersion.d.ts +10 -0
- package/build/services/otaReleaseVersion.d.ts.map +1 -0
- package/build/services/otaReleaseVersion.js +14 -0
- package/build/services/otaReleaseVersion.js.map +1 -0
- package/build/stores/appVisibility.d.ts +3 -0
- package/build/stores/appVisibility.d.ts.map +1 -0
- package/build/stores/appVisibility.js +3 -0
- package/build/stores/appVisibility.js.map +1 -0
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +7 -1
- package/build/stores/apps.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 +16 -5
- package/src/facades/pairing.ts +88 -12
- package/src/generated/releaseMetadata.ts +5 -5
- package/src/index.ts +1 -0
- package/src/react/MentraLiveOtaFlow.tsx +178 -465
- package/src/react/index.ts +14 -0
- package/src/react/useMentraLiveOta.ts +707 -0
- package/src/services/BlobStore.ts +57 -10
- package/src/services/GlassesStatusProjection.ts +7 -6
- package/src/services/HotspotOtaTransport.ts +8 -7
- package/src/services/OtaAutoChain.ts +26 -2
- package/src/services/OtaInstallCoordinator.ts +16 -13
- package/src/services/OtaService.ts +1 -2
- package/src/services/OtaUpdateCheckService.ts +26 -8
- package/src/services/asg/localNetworkTransport.ts +20 -19
- package/src/services/glassesClockSync.ts +1 -1
- package/src/services/otaReleaseVersion.ts +22 -0
- package/src/stores/appVisibility.ts +3 -0
- package/src/stores/apps.ts +7 -1
- package/src/stores/core.ts +4 -4
- package/src/stores/glasses.ts +13 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OtaInstallCoordinator.js","sourceRoot":"","sources":["../../src/services/OtaInstallCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OtaInstallCoordinator — engine-owned OTA install state machine (WP 8B).\n *\n * Owns every timer/retry/sequencing rule that used to live in the host screen\n * `mobile/src/app/ota/progress.tsx`: the global session timeout, serialized\n * ota_start retries, the stuck-at-zero watchdog, the progress-stall watchdog keyed\n * on a staleness signature, connect-edge arbitration (initial mount vs\n * reconnect vs post-APK reboot), the ota_query_status reply fallback, the ping\n * keepalive, the ota_start_ack / mtk_update_complete listeners, and terminal\n * cleanup. The host progress screen is a pure renderer over\n * `snapshot()`/`onSnapshot()` plus the `attach()/detach()/retry()/finish()`\n * commands (exposed as `engine.ota.installSession`).\n *\n * The reaction pass mirrors the old component's effect ordering: a\n * pass diffs the store-derived inputs (connected / otaStatus / otaProgress /\n * displayState / stall signature) exactly like the old effect dep arrays, and\n * state written mid-pass queues a follow-up pass — the same way a setState\n * during React effects scheduled a re-render after the current effect batch.\n */\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport type {OtaProgress, OtaStatus} from \"@mentra/bluetooth-sdk\"\nimport GlobalEventEmitter from \"../utils/GlobalEventEmitter\"\nimport {isGlassesConnected, useGlassesStore} from \"../stores/glasses\"\nimport {resolveOtaManifestUrl} from \"./otaManifestUrl\"\nimport {hotspotOtaTransport, type HotspotOtaPhase} from \"./HotspotOtaTransport\"\nimport type {OtaCheckCurrentGlassesResult} from \"./OtaUpdateCheckService\"\nimport {deriveDisplayState, type DisplayState} from \"./otaDisplayState\"\nimport {\n BES_CONTINUE_LOCKOUT_MS,\n DOWNLOAD_STUCK_TIMEOUT_MS,\n GLOBAL_OTA_TIMEOUT_MS,\n LEGACY_APK_COMPLETION_SETTLE_MS,\n LEGACY_BES_CONTINUE_LOCKOUT_MS,\n LEGACY_DOWNLOAD_STUCK_TIMEOUT_MS,\n LEGACY_GLOBAL_OTA_TIMEOUT_MS,\n LEGACY_MTK_INSTALL_TIMEOUT_MS,\n LEGACY_MTK_SIM_CAP_PERCENT,\n LEGACY_MTK_SIM_FLOOR_PERCENT,\n LEGACY_MTK_SIM_TICK_MS,\n LEGACY_MTK_STALL_DETECT_MS,\n LEGACY_MTK_STALL_ZONE_MAX_PERCENT,\n LEGACY_MTK_STALL_ZONE_MIN_PERCENT,\n LEGACY_PING_INTERVAL_MS,\n LEGACY_PROGRESS_TIMEOUT_MS,\n LEGACY_RETRY_INTERVAL_MS,\n MAX_RETRIES,\n MTK_INSTALL_TIMEOUT_MS,\n OtaProgressMessages,\n PING_INTERVAL_MS,\n PROGRESS_TIMEOUT_MS,\n QUERY_REPLY_TIMEOUT_MS,\n RETRY_INTERVAL_MS,\n isLegacyShapedOtaSession,\n isLegacyShapedOtaStatus,\n selectOtaProtocolProfile,\n type OtaProtocolProfile,\n} from \"./otaInstallPolicy\"\n\nfunction isTerminalForWatchdog(d: DisplayState): boolean {\n return d === \"complete\" || d === \"failed\" || d === \"restarting\"\n}\n\nfunction hotspotPreflightErrorMessage(error: unknown): string {\n const code =\n typeof error === \"object\" && error !== null && \"code\" in error ? String((error as {code: unknown}).code) : \"\"\n switch (code) {\n case \"artifact_download_failed\":\n return OtaProgressMessages.hotspotArtifactDownloadFailed\n case \"artifact_verify_failed\":\n case \"manifest_invalid\":\n return OtaProgressMessages.hotspotArtifactVerifyFailed\n case \"hotspot_wifi_permission_denied\":\n return OtaProgressMessages.hotspotWifiPermissionDenied\n case \"hotspot_start_failed\":\n return OtaProgressMessages.hotspotStartFailed\n case \"hotspot_join_failed\":\n return OtaProgressMessages.hotspotJoinFailed\n case \"hotspot_server_failed\":\n return OtaProgressMessages.hotspotServerFailed\n default:\n return OtaProgressMessages.hotspotServerFailed\n }\n}\n\n/** Non-empty when glasses are actively reporting work — drives stall timeout reset. */\nfunction buildProgressStalenessSignature(\n otaStatus: OtaStatus | null,\n otaProgress: OtaProgress | null,\n displayState: DisplayState,\n): string {\n if (displayState !== \"starting\" && displayState !== \"updating\") return \"\"\n if (otaStatus && (otaStatus.status === \"in_progress\" || otaStatus.status === \"step_complete\")) {\n return `s:${otaStatus.sessionId}|${otaStatus.status}|${otaStatus.phase}|${otaStatus.stepType}|${otaStatus.stepPercent}|${otaStatus.overallPercent}`\n }\n // Legacy-shaped BES download FINISHED (WP 8C): the legacy screen kept a progress\n // watchdog armed while waiting for the BES install events to start; keep the stall\n // watchdog armed here too so a wedged flash still fails instead of hanging.\n if (\n isLegacyShapedOtaStatus(otaStatus) &&\n otaStatus?.stepType === \"bes\" &&\n otaStatus.phase === \"download\" &&\n otaStatus.status === \"complete\"\n ) {\n return \"s:legacy-bes-download-complete-await-install\"\n }\n if (otaProgress && (otaProgress.status === \"PROGRESS\" || otaProgress.status === \"STARTED\")) {\n return `p:${otaProgress.currentUpdate}|${otaProgress.stage}|${otaProgress.status}|${otaProgress.progress}`\n }\n return \"\"\n}\n\nfunction progressTimeoutDurationMs(\n otaStatus: OtaStatus | null,\n otaProgress: OtaProgress | null,\n legacySession: boolean,\n): number {\n if (otaStatus?.stepType === \"mtk\" && otaStatus.phase === \"install\") {\n return legacySession ? LEGACY_MTK_INSTALL_TIMEOUT_MS : MTK_INSTALL_TIMEOUT_MS\n }\n if (otaProgress?.currentUpdate === \"mtk\" && otaProgress.stage === \"install\") {\n return legacySession ? LEGACY_MTK_INSTALL_TIMEOUT_MS : MTK_INSTALL_TIMEOUT_MS\n }\n return legacySession ? LEGACY_PROGRESS_TIMEOUT_MS : PROGRESS_TIMEOUT_MS\n}\n\nfunction latestPercentForStuck(otaStatus: OtaStatus | null, otaProgress: OtaProgress | null): number {\n if (otaProgress?.progress != null) return otaProgress.progress\n if (otaStatus?.status === \"in_progress\" || otaStatus?.status === \"step_complete\") {\n return Math.max(otaStatus.overallPercent ?? 0, otaStatus.stepPercent ?? 0)\n }\n return 0\n}\n\n/**\n * \"idle\" ota_status means the glasses have no active session — that is NOT a\n * recovery signal, so the query-reply fallback must keep firing and retry\n * ota_start. Only treat real progress or a non-idle ota_status as a useful\n * reply that cancels the fallback.\n */\nfunction hasRecoveringOtaReply(otaStatus: OtaStatus | null, otaProgress: OtaProgress | null): boolean {\n if (otaProgress) return true\n return !!otaStatus && otaStatus.status !== \"idle\"\n}\n\n/** Read model the host progress screen renders from. */\nexport interface OtaInstallSnapshot {\n displayState: DisplayState\n errorMsg: string\n continueButtonDisabled: boolean\n connected: boolean\n otaStatus: OtaStatus | null\n otaProgress: OtaProgress | null\n /**\n * Display-only simulated percent for legacy (< 37) MTK install stalls (WP 8C-e), or\n * null. The MTK system install goes quiet around 49-50%; the legacy screen simulated\n * +1% ticks up to 60% purely to reassure the user. Render max(real, simulated).\n */\n mtkInstallStallSimulatedPercent: number | null\n /** True for a downgrade (version-change) session — the UI narrates it differently. */\n isVersionChange: boolean\n /** True once the glasses reported the exact pinned target (the downgrade truly completed). */\n versionChangeConverged: boolean\n /**\n * Sub-phase of the downgrade detour for the progress narrative, or null when not\n * in one: \"installing\" before the handoff, \"restarting\" while the glasses are dark\n * (uninstall / factory flicker / target install), \"verifying\" once reconnected and\n * checking the version. Completion is the \"complete\" displayState.\n */\n versionChangePhase: \"installing\" | \"restarting\" | \"verifying\" | null\n /** Pre-ota_start phone staging/join state for a hotspot attempt. */\n hotspotPhase: HotspotOtaPhase\n hotspotArtifactPercent: number | null\n}\n\ntype OtaStartOutcome = \"pending\" | \"acknowledged\" | \"rejected\"\n\ninterface OtaStartOwnership {\n outcome: OtaStartOutcome\n promise: Promise<void>\n}\n\nclass OtaInstallCoordinator {\n private attached = false\n private preparedCheckResult: OtaCheckCurrentGlassesResult | null = null\n private selectedTransport: \"wifi\" | \"hotspot\" = \"wifi\"\n private hotspotManifestUrl: string | null = null\n private hotspotPhase: HotspotOtaPhase = \"idle\"\n private hotspotArtifactPercent: number | null = null\n\n // Genuinely session-local state (was component state/refs).\n private errorMsg = \"\"\n private sawReconnectEdge = false\n private continueButtonDisabled = false\n // True once this session reported an APK step. After an APK install the ASG\n // process restarts with a new build number, so finish() must clear the stale\n // one before check-for-updates re-checks (mirrors the legacy screen).\n private apkStepSeen = false\n private prevConnected = false\n\n // Legacy (< 37) compatibility state, ported from progress-legacy.tsx (WP 8C).\n // Build number at session start — legacy APK completion is detected by the build\n // number increasing past it when the explicit reconnect status never arrives.\n private initialBuildNumber: string | null = null\n // Captured with initialBuildNumber: whether the selected update includes an APK step.\n private apkExpectedInSession = false\n // Latched when the legacy build-number completion fires; projected as \"complete\".\n private apkCompletedViaBuildIncrease = false\n // The split routes selected legacy/unified behavior before navigation. Keep\n // that choice sticky while an APK step upgrades ASG mid-flow.\n private protocolProfile: OtaProtocolProfile | null = null\n\n // BES reboot recovery. Native bridges normalize explicit BES success to a\n // terminal status; pre-37 flows additionally retain the legacy screen's\n // lost-FINISHED fallback. Completion still requires a BES-specific observed\n // disconnect -> reconnect lifecycle, never the generic session reconnect flag.\n private besRestartExpected = false\n private besRestartDisconnectObserved = false\n private besRestartRecovery: \"awaiting\" | \"complete\" | null = null\n\n // Downgrade detour (version-change mode). Captured at attach from the selected\n // update: the pinned target is a LOWER build, executed by the recovery worker via\n // uninstall->reinstall, so the phone must NOT drive ota_start on the intermediate\n // reconnect (the passive factory build) and completion is exact-version\n // convergence, not a build-number increase.\n private versionChangeSession = false\n private versionChangeTarget: number | null = null\n // Set once ASG reports the apk install has started (the handoff point after which\n // ASG dies and the recovery worker owns the transaction).\n private versionChangeInstallStarted = false\n // Latched when a reconnect reports buildNumber === versionChangeTarget.\n private versionChangeConverged = false\n // Holds a legacy apk install FINISHED out of \"complete\" for the settle window.\n private legacyApkSettleHold = false\n // Display-only legacy MTK install stall simulation.\n private mtkSimulatedPercent: number | null = null\n private lastRealMtkProgress = 0\n\n // Timer handles\n private globalTimeout: ReturnType<typeof setTimeout> | null = null\n private globalTimeoutStarted = false\n private retryTimeout: ReturnType<typeof setTimeout> | null = null\n private stuckTimeout: ReturnType<typeof setTimeout> | null = null\n private progressTimeout: ReturnType<typeof setTimeout> | null = null\n private pingInterval: ReturnType<typeof setInterval> | null = null\n private queryReplyTimeout: ReturnType<typeof setTimeout> | null = null\n private continueLockoutTimer: ReturnType<typeof setTimeout> | null = null\n private legacyApkSettleTimer: ReturnType<typeof setTimeout> | null = null\n private mtkStallDetectTimer: ReturnType<typeof setTimeout> | null = null\n private mtkSimTickTimer: ReturnType<typeof setInterval> | null = null\n\n // Request / retry bookkeeping (no glasses source)\n // At most one apk-install status poll in flight (native rejects concurrent queries).\n private apkInstallPollInFlight = false\n // The native SDK owns one ota_start request until its application-level ack or\n // timeout. Keep pending ownership across attach/detach, and retain the settled\n // outcome while attached so Retry/query fallback cannot reinterpret an accepted\n // command as permission to start a second OTA transaction.\n private otaStartOwnership: OtaStartOwnership | null = null\n private hasFirstActivity = false\n // Stuck-at-zero watchdog clears only on first NON-ZERO progress; \"first activity\"\n // alone (e.g. ota_status with stepPercent=0) used to clear it too eagerly.\n private hasFirstNonZeroProgress = false\n private retryCount = 0\n\n // Log displayState transitions only (not every pass).\n private prevDisplayState: DisplayState | null = null\n\n // Last-handled reaction inputs — the equivalents of the old effect dep arrays.\n private lastConnected = false\n private lastOtaStatus: OtaStatus | null = null\n private lastOtaProgress: OtaProgress | null = null\n private lastBuildNumber = \"\"\n private lastDisplayState: DisplayState | null = null\n private lastStallSig = \"\"\n\n // Reaction pass re-entrancy guard (mirrors React deferring a setState-during-\n // effects re-render until the current effect batch finished).\n private reacting = false\n private reactQueued = false\n\n private storeUnsubscribe: (() => void) | null = null\n private snapshotCheckers = new Set<() => void>()\n\n // --- public surface (engine.ota.installSession) ---\n\n /** Select the transport at the existing install entry point before the progress route attaches. */\n prepare(checkResult: OtaCheckCurrentGlassesResult): \"wifi\" | \"hotspot\" {\n const state = useGlassesStore.getState()\n if (!state.wifiStatusKnown) {\n throw new Error(\"Glasses Wi-Fi status is not available\")\n }\n const hotspotSupported = state.hotspotOtaVersion === 1\n const wifiConnected = state.wifi.state === \"connected\"\n if (!wifiConnected && !hotspotSupported) {\n throw new Error(\"Connected glasses require Wi-Fi for OTA\")\n }\n this.preparedCheckResult = checkResult\n this.selectedTransport = wifiConnected ? \"wifi\" : \"hotspot\"\n this.hotspotManifestUrl = null\n this.hotspotPhase = \"idle\"\n this.hotspotArtifactPercent = null\n return this.selectedTransport\n }\n\n /**\n * Bind the state machine to a mounted progress screen. Idempotent per\n * attach/detach cycle. Runs the initial-mount arbitration (send ota_start\n * when connected with no session; otherwise ota_query_status + reply\n * fallback) and starts reacting to store changes + BLE OTA events.\n */\n attach(): void {\n if (this.attached) return\n this.attached = true\n this.resetSessionState()\n const initialState = useGlassesStore.getState()\n this.protocolProfile = selectOtaProtocolProfile(\n initialState.otaStatus,\n initialState.otaProgress,\n initialState.buildNumber,\n )\n const selected = initialState.otaUpdateAvailable\n if (selected?.isDowngrade && typeof selected.versionCode === \"number\" && selected.versionCode > 0) {\n this.versionChangeSession = true\n this.versionChangeTarget = selected.versionCode\n console.log(`[OTA_PROGRESS] version-change (downgrade) session, target=${selected.versionCode}`)\n }\n this.prevConnected = isGlassesConnected(useGlassesStore.getState().connection)\n this.storeUnsubscribe = useGlassesStore.subscribe(() => this.react())\n // Mount pass: every reaction block runs once (like all effects on mount),\n // then any passes queued by state written during the blocks.\n this.reacting = true\n try {\n this.runPass(true)\n while (this.reactQueued) {\n this.reactQueued = false\n this.runPass(false)\n }\n } finally {\n this.reacting = false\n }\n }\n\n /**\n * Unbind on screen unmount: clears ALL timers/subscriptions/listeners and\n * resets the session-local state (the old component state died with the\n * component) so a re-attach is a fresh session.\n */\n detach(): void {\n if (!this.attached) return\n this.attached = false\n if (this.storeUnsubscribe) {\n this.storeUnsubscribe()\n this.storeUnsubscribe = null\n }\n GlobalEventEmitter.off(\"ota_start_ack\", this.handleAck)\n GlobalEventEmitter.off(\"mtk_update_complete\", this.handleMtkComplete)\n GlobalEventEmitter.off(\"glasses_session_changed\", this.handleGlassesSessionChanged)\n this.clearAllOtaTimers()\n this.clearContinueLockoutTimer()\n // Only native command ownership survives a remount. Once the command has\n // settled, the glasses store/durable ota_status is the session authority.\n if (this.otaStartOwnership?.outcome !== \"pending\") {\n this.otaStartOwnership = null\n }\n this.resetSessionState()\n }\n\n /** Retry after a failure: clear state and re-send ota_start (if connected). */\n retry(): void {\n // While the recovery worker owns the detour (apk install latched, not yet\n // converged), the phone must not drive: an ota_start now would push the\n // factory/surviving build into a parallel download-install, and a second\n // handoff would begin()/REPLACE the live transaction under the running\n // worker. Retry just re-enters the reconcile wait — convergence or the\n // session timeout decides the real outcome.\n if (this.isInVersionChangeDetour()) {\n console.log(\"[OTA_PROGRESS] retry during version-change detour — re-entering wait (no ota_start)\")\n this.setErrorMsg(\"\")\n this.emitInternalChange()\n return\n }\n const store = useGlassesStore.getState()\n const otaStatus = store.otaStatus\n const otaProgress = store.otaProgress\n const authoritativeFailure = otaStatus?.status === \"failed\" || otaProgress?.status === \"FAILED\"\n const hasUnfinishedSession =\n (!!otaStatus &&\n otaStatus.status !== \"idle\" &&\n otaStatus.status !== \"failed\" &&\n otaStatus.status !== \"complete\") ||\n (!!otaProgress && otaProgress.status !== \"FAILED\" && otaProgress.status !== \"FINISHED\")\n const shouldReconcile =\n this.otaStartOwnership?.outcome === \"pending\" ||\n (!authoritativeFailure &&\n (this.otaStartOwnership?.outcome === \"acknowledged\" || this.hasFirstActivity || hasUnfinishedSession))\n\n if (shouldReconcile) {\n console.log(\"[OTA_PROGRESS] retry pressed for an existing OTA session — reconciling without ota_start\")\n this.clearPerStepTimers()\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n this.clearContinueLockoutTimer()\n this.setErrorMsg(\"\")\n this.maybeStartGlobalTimeout()\n this.maybeArmStuckWatchdog()\n if (isGlassesConnected(store.connection)) {\n if (this.otaStartOwnership?.outcome === \"pending\") {\n void this.sendOtaStartWithWatchdogs()\n } else {\n void BluetoothSdk.sendOtaQueryStatus().catch(() => {})\n this.armQueryReplyFallback(\"retry\")\n }\n }\n return\n }\n\n console.log(\"[OTA_PROGRESS] retry pressed after a rejected or terminal attempt — starting a fresh ota_start\")\n // Batch like the old event handler: React ran the whole handler (including\n // the ota_start send) before re-rendering + re-running effects.\n const wasReacting = this.reacting\n this.reacting = true\n try {\n this.clearPerStepTimers()\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n this.clearContinueLockoutTimer()\n this.retryCount = 0\n if (!this.prepareFreshOtaStartAttempt()) return\n this.resetBesRestartAttempt()\n this.setSawReconnectEdge(false)\n this.setErrorMsg(\"\")\n this.setContinueButtonDisabled(false)\n this.setLegacyApkSettleHold(false)\n this.setMtkSimulatedPercent(null)\n this.lastRealMtkProgress = 0\n store.setOtaProgress(null)\n store.setOtaStatus(null)\n if (isGlassesConnected(useGlassesStore.getState().connection)) {\n void this.sendOtaStartWithWatchdogs()\n }\n } finally {\n this.reacting = wasReacting\n }\n if (!wasReacting) this.react()\n }\n\n /**\n * Terminal-state cleanup half of the old Continue/Done handlers (navigation\n * stays in the screen): clear the selected update, and after an APK step\n * clear the stale build number so the next check re-reads version_info.\n */\n finish(): void {\n if (this.otaStartOwnership?.outcome !== \"pending\") {\n this.otaStartOwnership = null\n }\n useGlassesStore.getState().setOtaUpdateAvailable(null)\n if (this.apkStepSeen) {\n BluetoothSdk.updateGlasses({buildNumber: \"\"})\n useGlassesStore.getState().setGlassesInfo({buildNumber: \"\"})\n }\n void this.teardownHotspotTransport()\n }\n\n /**\n * Abandon an interrupted session (the super-mode skip): terminal cleanup\n * plus dropping the session's status/progress read-state, so\n * deriveDisplayState doesn't resurrect the stale install when the host\n * navigates away and back through /ota routes.\n */\n discard(): void {\n this.finish()\n const store = useGlassesStore.getState()\n store.setOtaStatus(null)\n store.setOtaProgress(null)\n }\n\n snapshot(): OtaInstallSnapshot {\n const state = useGlassesStore.getState()\n const connected = isGlassesConnected(state.connection)\n const otaStatus = state.otaStatus\n const otaProgress = state.otaProgress\n return {\n displayState: deriveDisplayState({\n otaStatus,\n otaProgress,\n connected,\n errorMsg: this.errorMsg,\n sawReconnectEdge: this.sawReconnectEdge,\n legacyApkSettleHold: this.legacyApkSettleHold,\n apkCompletedViaBuildIncrease: this.apkCompletedViaBuildIncrease,\n besRestartRecovery: this.besRestartRecovery,\n versionChangeConverged: this.versionChangeConverged,\n versionChangeSession: this.versionChangeSession,\n }),\n errorMsg: this.errorMsg,\n // Keep Continue disabled while the expected BES reboot is still in flight.\n continueButtonDisabled: this.continueButtonDisabled || this.besRestartRecovery === \"awaiting\",\n connected,\n // Copies: the snapshot must not hand callers mutable references into the store.\n otaStatus: otaStatus ? {...otaStatus} : null,\n otaProgress: otaProgress ? {...otaProgress} : null,\n mtkInstallStallSimulatedPercent: this.mtkSimulatedPercent,\n isVersionChange: this.versionChangeSession,\n versionChangeConverged: this.versionChangeConverged,\n versionChangePhase: this.deriveVersionChangePhase(connected),\n hotspotPhase: this.hotspotPhase,\n hotspotArtifactPercent: this.hotspotArtifactPercent,\n }\n }\n\n /**\n * True while the recovery worker owns the downgrade transaction (after the apk install\n * started, before convergence). During this window ASG is being uninstalled/reinstalled and\n * cannot answer the phone, so the coordinator must not ping, poll ota_query_status, or arm the\n * progress-stall watchdog — doing so drives the passive factory build and fails the session\n * before the target reconnects. Completion is exact-version convergence, detected separately.\n */\n private isInVersionChangeDetour(): boolean {\n return this.versionChangeSession && this.versionChangeInstallStarted && !this.versionChangeConverged\n }\n\n /** Downgrade-detour sub-phase for the progress narrative (see OtaInstallSnapshot). */\n private deriveVersionChangePhase(connected: boolean): \"installing\" | \"restarting\" | \"verifying\" | null {\n if (!this.versionChangeSession || this.versionChangeConverged) return null\n if (!this.versionChangeInstallStarted) return \"installing\"\n return connected ? \"verifying\" : \"restarting\"\n }\n\n /**\n * Subscribe to install snapshot changes, deduped on the projected JSON.\n * Fires on glasses-store changes AND coordinator-internal state changes\n * (errorMsg / reconnect edge / continue lockout). Returns an unsubscribe.\n */\n onSnapshot(cb: (snapshot: OtaInstallSnapshot) => void): () => void {\n let last = JSON.stringify(this.snapshot())\n const check = () => {\n const snap = this.snapshot()\n const key = JSON.stringify(snap)\n if (key === last) return\n last = key\n cb(snap)\n }\n this.snapshotCheckers.add(check)\n const unsubscribeStore = useGlassesStore.subscribe(check)\n return () => {\n this.snapshotCheckers.delete(check)\n unsubscribeStore()\n }\n }\n\n // --- internal state plumbing ---\n\n private resetSessionState(): void {\n this.errorMsg = \"\"\n this.sawReconnectEdge = false\n this.continueButtonDisabled = false\n this.apkStepSeen = false\n this.prevConnected = false\n this.initialBuildNumber = null\n this.apkExpectedInSession = false\n this.apkCompletedViaBuildIncrease = false\n this.protocolProfile = null\n this.resetBesRestartAttempt()\n this.versionChangeSession = false\n this.versionChangeTarget = null\n this.versionChangeInstallStarted = false\n this.versionChangeConverged = false\n this.legacyApkSettleHold = false\n this.mtkSimulatedPercent = null\n this.lastRealMtkProgress = 0\n this.apkInstallPollInFlight = false\n this.hasFirstActivity = false\n this.hasFirstNonZeroProgress = false\n this.retryCount = 0\n this.globalTimeoutStarted = false\n this.prevDisplayState = null\n this.lastConnected = false\n this.lastOtaStatus = null\n this.lastOtaProgress = null\n this.lastBuildNumber = \"\"\n this.lastDisplayState = null\n this.lastStallSig = \"\"\n this.reactQueued = false\n }\n\n /** Begin a genuinely new command attempt only after native ownership has settled. */\n private prepareFreshOtaStartAttempt(): boolean {\n if (this.otaStartOwnership?.outcome === \"pending\") {\n console.error(\"[OTA_PROGRESS] refused fresh ota_start while native still owns the previous request\")\n return false\n }\n this.otaStartOwnership = null\n this.hasFirstActivity = false\n this.hasFirstNonZeroProgress = false\n this.setApkCompletedViaBuildIncrease(false)\n return true\n }\n\n /** Reset only the reboot lifecycle that belongs to one install attempt. */\n private resetBesRestartAttempt(): void {\n this.besRestartExpected = false\n this.besRestartDisconnectObserved = false\n this.besRestartRecovery = null\n }\n\n /** Notify snapshot subscribers of a coordinator-internal state change. */\n private emitInternalChange(): void {\n for (const check of Array.from(this.snapshotCheckers)) check()\n }\n\n // Setters mirror the old setState calls: bail on identical values (React's\n // setState bailout), notify snapshot subscribers, and queue a reaction pass.\n private setErrorMsg(next: string): void {\n if (this.errorMsg === next) return\n this.errorMsg = next\n this.emitInternalChange()\n this.react()\n }\n\n private setSawReconnectEdge(next: boolean): void {\n if (this.sawReconnectEdge === next) return\n this.sawReconnectEdge = next\n this.emitInternalChange()\n this.react()\n }\n\n private setContinueButtonDisabled(next: boolean): void {\n if (this.continueButtonDisabled === next) return\n this.continueButtonDisabled = next\n this.emitInternalChange()\n this.react()\n }\n\n private setApkCompletedViaBuildIncrease(next: boolean): void {\n if (this.apkCompletedViaBuildIncrease === next) return\n this.apkCompletedViaBuildIncrease = next\n this.emitInternalChange()\n this.react()\n }\n\n private setLegacyApkSettleHold(next: boolean): void {\n if (this.legacyApkSettleHold === next) return\n this.legacyApkSettleHold = next\n this.emitInternalChange()\n this.react()\n }\n\n /** Display-only (WP 8C-e): notifies snapshot subscribers but never queues a reaction pass. */\n private setMtkSimulatedPercent(next: number | null): void {\n if (this.mtkSimulatedPercent === next) return\n this.mtkSimulatedPercent = next\n this.emitInternalChange()\n }\n\n /** Legacy/unified policy is selected once, matching the old sticky route choice. */\n private isLegacySessionShapeNow(): boolean {\n if (this.protocolProfile) return this.protocolProfile === \"legacy\"\n const state = useGlassesStore.getState()\n const selected = selectOtaProtocolProfile(\n state.otaStatus,\n state.otaProgress,\n this.initialBuildNumber || state.buildNumber,\n )\n if (selected) {\n this.protocolProfile = selected\n console.log(`[OTA_PROGRESS] protocol profile selected: ${selected}`)\n return selected === \"legacy\"\n }\n return isLegacyShapedOtaSession(state.otaStatus, state.otaProgress, state.buildNumber)\n }\n\n private react(): void {\n if (!this.attached) return\n if (this.reacting) {\n this.reactQueued = true\n return\n }\n this.reacting = true\n try {\n do {\n this.reactQueued = false\n this.runPass(false)\n } while (this.reactQueued)\n } finally {\n this.reacting = false\n }\n }\n\n /**\n * One reaction pass = one render + its changed-dep effects of the old\n * component, in the old declaration order.\n */\n private runPass(isMount: boolean): void {\n const state = useGlassesStore.getState()\n const connected = isGlassesConnected(state.connection)\n const otaStatus = state.otaStatus\n const otaProgress = state.otaProgress\n const buildNumber = state.buildNumber\n\n const connectedChanged = isMount || connected !== this.lastConnected\n const otaStatusChanged = isMount || otaStatus !== this.lastOtaStatus\n const otaProgressChanged = isMount || otaProgress !== this.lastOtaProgress\n const buildNumberChanged = isMount || buildNumber !== this.lastBuildNumber\n\n // Session-start build capture (legacy build-number APK completion, WP 8C-c) —\n // mirrors the legacy screen capturing initialBuildNumber on its first truthy value,\n // marked for APK only when the selected update sequence includes an apk step.\n if (!this.initialBuildNumber && buildNumber) {\n this.initialBuildNumber = buildNumber\n this.apkExpectedInSession = !!state.otaUpdateAvailable?.updates?.includes(\"apk\")\n }\n\n // Legacy pre-derivation compat (WP 8C): must run BEFORE deriveDisplayState so a\n // legacy apk install \"complete\" is held by the settle window in the same pass it\n // lands (never leaking a premature terminal pass to the watchdog blocks below).\n if (otaStatusChanged) {\n this.handleLegacyInstallCompleteEdge(otaStatus)\n }\n\n const legacySession = this.isLegacySessionShapeNow()\n\n if (this.isBesRestartExpected(otaStatus, otaProgress, legacySession)) {\n this.besRestartExpected = true\n }\n\n // Port the legacy route's actual reboot invariant before deriving display\n // state, so reconnecting with stale BES in_progress@100 never renders updating.\n if (connectedChanged && !connected && this.besRestartExpected && this.besRestartRecovery === null) {\n this.besRestartDisconnectObserved = true\n this.besRestartRecovery = \"awaiting\"\n console.log(\"[OTA_PROGRESS] BES restart disconnect observed — awaiting reconnect verification\")\n }\n if (this.besRestartRecovery === \"awaiting\" && connected) this.completeBesRestartRecovery()\n\n // Derived UI state — the glasses data IS the source of truth.\n const displayState = deriveDisplayState({\n otaStatus,\n otaProgress,\n connected,\n errorMsg: this.errorMsg,\n sawReconnectEdge: this.sawReconnectEdge,\n legacyApkSettleHold: this.legacyApkSettleHold,\n apkCompletedViaBuildIncrease: this.apkCompletedViaBuildIncrease,\n besRestartRecovery: this.besRestartRecovery,\n versionChangeConverged: this.versionChangeConverged,\n versionChangeSession: this.versionChangeSession,\n })\n const stallSig = buildProgressStalenessSignature(otaStatus, otaProgress, displayState)\n const stallDuration = progressTimeoutDurationMs(otaStatus, otaProgress, legacySession)\n\n const displayStateChanged = isMount || displayState !== this.lastDisplayState\n const stallSigChanged = isMount || stallSig !== this.lastStallSig\n\n // Commit this pass's inputs BEFORE running the blocks so state written\n // mid-pass (which queues a follow-up pass) diffs against what this pass\n // already handled — like React committing the render before its effects.\n this.lastConnected = connected\n this.lastOtaStatus = otaStatus\n this.lastOtaProgress = otaProgress\n this.lastBuildNumber = buildNumber\n this.lastDisplayState = displayState\n this.lastStallSig = stallSig\n\n if (this.prevDisplayState !== displayState) {\n console.log(\n `[OTA_PROGRESS] displayState ${this.prevDisplayState ?? \"<init>\"} -> ${displayState}`,\n JSON.stringify({\n connected,\n sawReconnectEdge: this.sawReconnectEdge,\n errorMsg: this.errorMsg || null,\n otaStatus: otaStatus\n ? {\n stepType: otaStatus.stepType,\n phase: otaStatus.phase,\n status: otaStatus.status,\n step: `${otaStatus.currentStep}/${otaStatus.totalSteps}`,\n pct: otaStatus.overallPercent,\n }\n : null,\n otaProgress: otaProgress\n ? {\n currentUpdate: otaProgress.currentUpdate,\n stage: otaProgress.stage,\n status: otaProgress.status,\n progress: otaProgress.progress,\n }\n : null,\n }),\n )\n this.prevDisplayState = displayState\n }\n\n // APK-step latch (was the [otaStatus] effect above the timers).\n if (otaStatusChanged && otaStatus?.stepType === \"apk\") {\n this.apkStepSeen = true\n }\n\n // Legacy MTK completion side effect (WP 8C-a): old builds never send the\n // mtk_update_complete BLE event; their install FINISHED is the completion signal,\n // and the legacy screen marked MTK as updated this session right there.\n if (\n otaStatusChanged &&\n isLegacyShapedOtaStatus(otaStatus) &&\n otaStatus?.stepType === \"mtk\" &&\n otaStatus.phase === \"install\" &&\n otaStatus.status === \"complete\"\n ) {\n console.log(\"[OTA_PROGRESS] legacy mtk install complete — marking MTK updated this session\")\n useGlassesStore.getState().setMtkUpdatedThisSession(true)\n }\n\n // Version-change (downgrade) install started: once ASG reports the apk install\n // phase, the handoff to the recovery worker has happened. From here the phone\n // stops driving ota_start (see runConnectEdge) and waits for exact-version\n // convergence — the wipe means no resumable ASG session and no build increase.\n if (\n this.versionChangeSession &&\n !this.versionChangeInstallStarted &&\n // Only latch from a status that belongs to THIS session: an install/apk status is a\n // response to our own acknowledged ota_start, so a leftover from a prior session\n // sitting in the store at mount cannot prematurely enter the detour wait (which would\n // suppress ota_start and hang the fresh downgrade until the global timeout).\n this.otaStartOwnership?.outcome === \"acknowledged\" &&\n otaStatus?.stepType === \"apk\" &&\n otaStatus.phase === \"install\"\n ) {\n console.log(\"[OTA_PROGRESS] version-change: apk install started — entering detour wait\")\n this.versionChangeInstallStarted = true\n this.emitInternalChange()\n }\n\n // Ownership refuted: ASG emits install/STARTED BEFORE handing off, so the latch above can\n // be set even when no transaction ends up owning the detour. Recovery answers every\n // handoff synchronously, so exactly three error codes prove non-ownership and release the\n // latch: downgrade_handoff_refused (recovery's explicit verdict),\n // downgrade_handoff_failed (no verdict at all — recovery dead/missing, so it never began),\n // and downgrade_transaction_stalled (the long-stop past recovery's own stale give-up).\n // An accepted-but-slow transaction emits NONE of these (acceptance cancels the short\n // watchdog), so the latch is never released while a live worker owns the staged artifact\n // — which recovery additionally claims by rename at acceptance.\n if (\n this.versionChangeInstallStarted &&\n !this.versionChangeConverged &&\n otaStatus?.status === \"failed\" &&\n (otaStatus.error === \"downgrade_handoff_refused\" ||\n otaStatus.error === \"downgrade_handoff_failed\" ||\n otaStatus.error === \"downgrade_transaction_stalled\")\n ) {\n console.log(\n `[OTA_PROGRESS] version-change: no transaction owns the detour (${otaStatus.error}) — releasing latch`,\n )\n this.versionChangeInstallStarted = false\n this.emitInternalChange()\n }\n\n // Version-change convergence: the reconnected glasses report exactly the pinned\n // target. This is the ONLY completion signal for a downgrade (lower build, no\n // increase, wiped session). Mirrors the legacy build-increase latch but by equality.\n if (\n this.versionChangeSession &&\n this.versionChangeInstallStarted &&\n !this.versionChangeConverged &&\n this.versionChangeTarget !== null &&\n buildNumberChanged &&\n buildNumber\n ) {\n const currentBuild = Number.parseInt(buildNumber, 10)\n if (Number.isFinite(currentBuild) && currentBuild === this.versionChangeTarget) {\n console.log(`[OTA_PROGRESS] version-change converged: glasses report target ${currentBuild}, completing`)\n this.clearPerStepTimers()\n this.clearGlobalTimeout()\n this.apkStepSeen = true\n this.setErrorMsg(\"\")\n this.versionChangeConverged = true\n this.emitInternalChange()\n }\n }\n\n // Legacy APK completion by build-number increase (WP 8C-c): old builds reboot into\n // the new build without a reliable explicit reconnect status; the fresh version_info\n // build number is the completion signal (ported from progress-legacy.tsx, which\n // completed from installing-with-apk and from starting/failed).\n if (\n buildNumberChanged &&\n !this.apkCompletedViaBuildIncrease &&\n this.apkExpectedInSession &&\n legacySession &&\n this.initialBuildNumber\n ) {\n const currentBuild = Number.parseInt(buildNumber, 10)\n const initialBuild = Number.parseInt(this.initialBuildNumber, 10)\n const increased = Number.isFinite(currentBuild) && Number.isFinite(initialBuild) && currentBuild > initialBuild\n const apkStepCurrent = otaStatus?.stepType === \"apk\" || otaProgress?.currentUpdate === \"apk\"\n const detectable =\n displayState === \"starting\" || displayState === \"failed\" || (displayState === \"updating\" && apkStepCurrent)\n if (increased && detectable) {\n console.log(\n `[OTA_PROGRESS] legacy apk complete via build-number increase (${initialBuild} -> ${currentBuild}), completing session`,\n )\n this.clearPerStepTimers()\n this.clearLegacyApkSettleTimer()\n this.setLegacyApkSettleHold(false)\n this.apkStepSeen = true\n this.setErrorMsg(\"\")\n this.setApkCompletedViaBuildIncrease(true)\n }\n }\n\n // Cancel the query-reply fallback as soon as the glasses reply with a useful\n // status (in_progress / step_complete / complete / failed) or any progress\n // event. An \"idle\" ota_status means glasses have no active session, so we\n // must keep the fallback armed and let it retry ota_start.\n if (otaStatusChanged || otaProgressChanged) {\n if (this.queryReplyTimeout && hasRecoveringOtaReply(otaStatus, otaProgress)) {\n this.clearQueryReplyTimeout()\n }\n }\n\n /**\n * Connect-edge — the only place that decides to send ota_start /\n * ota_query_status and flips sawReconnectEdge\n * on the false -> true transition that signals the BES reboot completed.\n */\n if (connectedChanged) {\n this.runConnectEdge(connected)\n }\n\n if (displayStateChanged && isTerminalForWatchdog(displayState)) {\n this.clearGlobalTimeout()\n }\n\n if (isMount) {\n GlobalEventEmitter.on(\"ota_start_ack\", this.handleAck)\n GlobalEventEmitter.on(\"mtk_update_complete\", this.handleMtkComplete)\n GlobalEventEmitter.on(\"glasses_session_changed\", this.handleGlassesSessionChanged)\n }\n\n // Ping keepalive while an OTA is actively running (legacy sessions pinged on the\n // padded interval — old builds slept less eagerly and pings are costlier for them).\n if (connectedChanged || displayStateChanged) {\n this.clearPingInterval()\n const active =\n connected && (displayState === \"starting\" || displayState === \"updating\") && !this.isInVersionChangeDetour()\n if (active) {\n void BluetoothSdk.ping().catch(() => {})\n const pingIntervalMs = legacySession ? LEGACY_PING_INTERVAL_MS : PING_INTERVAL_MS\n this.pingInterval = setInterval(() => {\n void BluetoothSdk.ping().catch(() => {})\n this.maybePollApkInstallStatus()\n }, pingIntervalMs)\n }\n }\n\n // Any glasses activity proves the logical ota_start was accepted.\n if ((otaStatusChanged || otaProgressChanged) && (otaStatus || otaProgress)) {\n this.onFirstActivity()\n }\n\n // The stuck-at-zero watchdog clears only on the FIRST real (>0%) progress.\n // Without this distinction, an ota_status reply with stepPercent=0 would\n // disable the watchdog before any download had actually started, hiding\n // wedged downloads from the user.\n if (otaStatusChanged || otaProgressChanged) {\n const stepPct = otaStatus?.stepPercent ?? 0\n const overallPct = otaStatus?.overallPercent ?? 0\n const legacyPct = otaProgress?.progress ?? 0\n if (stepPct > 0 || overallPct > 0 || legacyPct > 0) {\n this.onFirstNonZeroProgress()\n }\n }\n\n // Progress stall watchdog — fails the update if glasses go silent mid-step.\n // Keyed on the staleness SIGNATURE string (not the object refs) so a store\n // update that doesn't change the signature keeps the same timer running\n // instead of forever re-extending the deadline.\n if (stallSigChanged || displayStateChanged) {\n if (this.isInVersionChangeDetour()) {\n // Recovery worker owns the transaction; there are no progress events to stall on.\n this.clearProgressTimeout()\n } else if (displayState !== \"starting\" && displayState !== \"updating\") {\n this.clearProgressTimeout()\n } else if (!stallSig) {\n this.clearProgressTimeout()\n } else {\n const duration = stallDuration\n this.clearProgressTimeout()\n this.progressTimeout = setTimeout(() => {\n this.progressTimeout = null\n if (isTerminalForWatchdog(this.computeDisplayStateNow())) return\n console.log(`[OTA_PROGRESS] watchdog: progress stalled for ${duration}ms, failing`)\n this.setErrorMsg(OtaProgressMessages.stalledOrStuck)\n }, duration)\n }\n }\n\n // Lockout on Continue button after BES restart to prevent accidental tap\n // (15s unified, 35s for legacy-shaped sessions — WP 8C-f).\n if (displayStateChanged && displayState === \"restarting\") {\n this.clearContinueLockoutTimer()\n const lockoutMs = legacySession ? LEGACY_BES_CONTINUE_LOCKOUT_MS : BES_CONTINUE_LOCKOUT_MS\n this.setContinueButtonDisabled(true)\n this.continueLockoutTimer = setTimeout(() => {\n this.continueLockoutTimer = null\n this.setContinueButtonDisabled(false)\n }, lockoutMs)\n }\n\n // Legacy MTK install stall simulation (WP 8C-e): display-only. The simulation\n // timers only ever touch the projected snapshot percent — they never feed back\n // into arbitration (no reaction pass, no watchdog resets).\n if (otaProgressChanged) {\n this.runMtkStallSimulationPass(otaProgress, legacySession)\n }\n\n // Clear the selected update once this session reaches any terminal UI state.\n // Catches paths the MantleManager ota_status listener misses — notably BES success\n // (which terminates as `step_complete`, not `complete`) and APK build-number fallback\n // completions (which never produce a `complete` ota_status).\n if (\n displayStateChanged &&\n (displayState === \"complete\" || displayState === \"restarting\" || displayState === \"failed\")\n ) {\n if (displayState === \"failed\") {\n this.clearPerStepTimers()\n }\n useGlassesStore.getState().setOtaUpdateAvailable(null)\n if (displayState === \"complete\" || displayState === \"failed\") {\n void this.teardownHotspotTransport()\n }\n }\n }\n\n /**\n * Reconnect arbitration shared by the physical BLE connect edge and the\n * glasses_session_changed signal. The latter exists because the BES keeps the BLE\n * link alive across asg_client restarts (APK OTA): no physical edge ever fires, so\n * the changed process session id is the only reconnect signal the coordinator gets\n * (incident rep_01KY6BJ0B7A4RBMQ7VN39KAE5E). Always returns true (the caller's\n * edge handling is complete).\n */\n private runReconnectArbitration(label: string): boolean {\n console.log(`[OTA_PROGRESS] ${label}: false->true, flipping sawReconnectEdge=true`)\n // A physical reconnect passed through the disconnect branch first, which cleared\n // these timers; a session-change edge never disconnects, so a fallback armed by an\n // earlier mount/query could otherwise fire alongside the arbitration below and send\n // a duplicate ota_start. Clearing here is a no-op on the physical path.\n this.clearQueryReplyTimeout()\n this.setSawReconnectEdge(true)\n\n if (this.besRestartDisconnectObserved) {\n console.log(`[OTA_PROGRESS] ${label}: BES reboot reconnect observed — no ota_query_status`)\n this.completeBesRestartRecovery()\n return true\n }\n\n // Legacy apk settle window (WP 8C): the glasses restarting into the new build is\n // the EXPECTED reconnect here — the legacy screen took no action on it. Skip the\n // query/fallback; the settle timer (or the build-number increase) completes.\n if (this.legacyApkSettleHold) {\n console.log(`[OTA_PROGRESS] ${label}: reconnect during legacy apk settle hold — no query`)\n return true\n }\n\n console.log(`[OTA_PROGRESS] ${label}: reconnected, sending ota_query_status`)\n if (this.otaStartOwnership?.outcome === \"pending\") {\n void this.sendOtaStartWithWatchdogs()\n }\n void BluetoothSdk.sendOtaQueryStatus()\n this.armQueryReplyFallback(\"reconnect\")\n return true\n }\n\n private runConnectEdge(connected: boolean): void {\n const prev = this.prevConnected\n this.prevConnected = connected\n\n if (!connected) {\n console.log(\"[OTA_PROGRESS] connect-edge: disconnected\")\n // Also drop pending query/retry sends: firing ota_start into a dead link\n // can only produce a false \"failed\" state. Reconnect arbitration first\n // queries durable status and re-arms the one permitted fallback.\n this.clearQueryReplyTimeout()\n this.clearRetryTimeout()\n return\n }\n\n const becameConnected = prev === false && connected === true\n if (becameConnected && this.runReconnectArbitration(\"connect-edge\")) {\n return\n }\n\n // Version-change detour: after the install started, EVERY reconnect is expected\n // (the passive factory build, then the target). Do NOT send ota_start/query — the\n // factory build would treat the pin as a plain upgrade and start a redundant\n // download racing the recovery worker. Convergence (buildNumber === target) is\n // detected in the reaction pass; here we simply take no action.\n if (this.versionChangeSession && this.versionChangeInstallStarted && !this.versionChangeConverged) {\n console.log(\"[OTA_PROGRESS] connect-edge: reconnect during version-change detour — no query (expected)\")\n return\n }\n\n const storeState = useGlassesStore.getState()\n\n // Initial mount (prev === current === true). If no session yet, kick off ota_start.\n // An idle ota_status has an empty sessionId; treat it as no session so ota_start\n // still begins an explicit install.\n const isIdleStatus = !!storeState.otaStatus && storeState.otaStatus.sessionId === \"\"\n const noSessionYet = (!storeState.otaStatus && !storeState.otaProgress) || isIdleStatus\n if (noSessionYet) {\n if (!isIdleStatus && this.otaStartOwnership?.outcome === \"acknowledged\") {\n console.log(\"[OTA_PROGRESS] initial mount, acknowledged session has no cached status — reconciling\")\n void BluetoothSdk.sendOtaQueryStatus().catch(() => {})\n this.armQueryReplyFallback(\"initial-mount\")\n return\n }\n console.log(\n isIdleStatus\n ? \"[OTA_PROGRESS] initial mount, idle status (no sessionId), sending ota_start\"\n : \"[OTA_PROGRESS] initial mount, no session in store, sending ota_start\",\n )\n this.retryCount = 0\n if (isIdleStatus && this.otaStartOwnership?.outcome !== \"pending\" && !this.prepareFreshOtaStartAttempt()) {\n return\n }\n void this.sendOtaStartWithWatchdogs()\n } else {\n console.log(\"[OTA_PROGRESS] initial mount, session exists, sending ota_query_status\")\n void BluetoothSdk.sendOtaQueryStatus()\n this.armQueryReplyFallback(\"initial-mount\")\n }\n }\n\n // --- BLE OTA event listeners (engine GlobalEventEmitter, fed by OtaService) ---\n\n private readonly handleAck = (): void => {\n const ownership = this.otaStartOwnership\n if (!ownership || ownership.outcome === \"rejected\") return\n if (ownership.outcome === \"acknowledged\") return\n console.log(\"[OTA_PROGRESS] ota_start_ack received\")\n ownership.outcome = \"acknowledged\"\n this.clearRetryTimeout()\n }\n\n /**\n * The asg process restarted while the BES kept the BLE link up (sid change observed\n * by the bridge): treat it exactly like a physical reconnect edge.\n */\n private readonly handleGlassesSessionChanged = (): void => {\n this.runReconnectArbitration(\"session-change\")\n }\n\n private readonly handleMtkComplete = (): void => {\n console.log(\"[OTA_PROGRESS] mtk_update_complete received\")\n this.clearProgressTimeout()\n this.onFirstActivity()\n this.onFirstNonZeroProgress()\n void BluetoothSdk.sendOtaQueryStatus()\n useGlassesStore.getState().setMtkUpdatedThisSession(true)\n }\n\n // --- legacy (< 37) compatibility, ported from progress-legacy.tsx (WP 8C) ---\n\n /**\n * Reacts to a NEW legacy-shaped install-phase \"complete\" (an old build's\n * `install FINISHED`). Two ports from the legacy screen:\n * - last-write-wins: completion arriving after a watchdog failure overrides it\n * (the old screen completed from \"failed\" too);\n * - apk settle window: an apk install FINISHED observed in flight is held out of\n * \"complete\" for LEGACY_APK_COMPLETION_SETTLE_MS so the ASG process restart\n * settles (and fresh version_info lands) before the user can continue. From\n * starting/failed (post-reboot explicit signal) completion is immediate.\n */\n private handleLegacyInstallCompleteEdge(otaStatus: OtaStatus | null): void {\n if (!isLegacyShapedOtaStatus(otaStatus) || otaStatus?.phase !== \"install\" || otaStatus.status !== \"complete\") {\n return\n }\n\n if (this.errorMsg) {\n console.log(\n \"[OTA_PROGRESS] legacy install complete arrived after a failure — completing (legacy last-write-wins)\",\n )\n this.setErrorMsg(\"\")\n this.clearLegacyApkSettleTimer()\n this.setLegacyApkSettleHold(false)\n return\n }\n\n if (\n otaStatus.stepType === \"apk\" &&\n !this.apkCompletedViaBuildIncrease &&\n !this.legacyApkSettleHold &&\n this.legacyApkSettleTimer === null &&\n this.lastDisplayState === \"updating\"\n ) {\n console.log(\n `[OTA_PROGRESS] legacy apk install complete — holding complete for ${LEGACY_APK_COMPLETION_SETTLE_MS}ms settle window`,\n )\n this.setLegacyApkSettleHold(true)\n this.legacyApkSettleTimer = setTimeout(() => {\n this.legacyApkSettleTimer = null\n console.log(\"[OTA_PROGRESS] legacy apk settle window elapsed — releasing complete\")\n this.setLegacyApkSettleHold(false)\n }, LEGACY_APK_COMPLETION_SETTLE_MS)\n }\n }\n\n private isBesRestartExpected(\n otaStatus: OtaStatus | null,\n otaProgress: OtaProgress | null,\n legacySession: boolean,\n ): boolean {\n const statusReadyToRestart =\n otaStatus?.stepType === \"bes\" &&\n otaStatus.phase === \"install\" &&\n (otaStatus.status === \"step_complete\" || otaStatus.status === \"complete\")\n const progressReadyToRestart =\n legacySession &&\n otaProgress?.currentUpdate === \"bes\" &&\n otaProgress.stage === \"install\" &&\n otaProgress.status === \"FINISHED\"\n\n // progress-legacy treated a BES disconnect during active installation as the\n // expected power cycle even when its terminal FINISHED event was lost. Keep\n // that fallback only for the sticky pre-37 profile selected when the flow began.\n const legacyInstallInProgress =\n legacySession &&\n ((otaStatus?.stepType === \"bes\" && otaStatus.phase === \"install\" && otaStatus.status === \"in_progress\") ||\n (otaProgress?.currentUpdate === \"bes\" &&\n otaProgress.stage === \"install\" &&\n (otaProgress.status === \"STARTED\" || otaProgress.status === \"PROGRESS\")))\n return statusReadyToRestart || progressReadyToRestart || legacyInstallInProgress\n }\n\n /** Complete only after a protocol-authorized BES restart traverses disconnect -> reconnect. */\n private completeBesRestartRecovery(): void {\n if (!this.besRestartDisconnectObserved || this.besRestartRecovery !== \"awaiting\") return\n console.log(\"[OTA_PROGRESS] BES restart reconnected — completing by reboot edge\")\n this.clearPerStepTimers()\n this.setErrorMsg(\"\")\n this.besRestartRecovery = \"complete\"\n this.emitInternalChange()\n }\n\n /**\n * Legacy MTK install stall simulation (WP 8C-e), ported verbatim: the MTK system\n * install typically stalls around 49-50%. Every real event restarts stall detection;\n * after LEGACY_MTK_STALL_DETECT_MS of silence inside the [45, 55) zone, simulate +1%\n * every LEGACY_MTK_SIM_TICK_MS from max(stall+1, 51), capped at 60. Real progress\n * beyond the simulated value clears it. Display-only by construction: the timers call\n * only {@link setMtkSimulatedPercent}, which never queues a reaction pass.\n */\n private runMtkStallSimulationPass(otaProgress: OtaProgress | null, legacySession: boolean): void {\n const isLegacyMtkInstall =\n legacySession &&\n otaProgress?.currentUpdate === \"mtk\" &&\n otaProgress.stage === \"install\" &&\n (otaProgress.status === \"STARTED\" || otaProgress.status === \"PROGRESS\")\n\n if (!isLegacyMtkInstall) {\n this.clearMtkSimulationTimers()\n this.setMtkSimulatedPercent(null)\n return\n }\n\n const realProgress = otaProgress.progress ?? 0\n if (realProgress > 0 && realProgress !== this.lastRealMtkProgress) {\n this.lastRealMtkProgress = realProgress\n if (this.mtkSimulatedPercent !== null && realProgress > this.mtkSimulatedPercent) {\n this.setMtkSimulatedPercent(null)\n }\n }\n\n // A real event arrived: restart stall detection (and stop any running ticker).\n this.clearMtkSimulationTimers()\n const inStallZone =\n realProgress >= LEGACY_MTK_STALL_ZONE_MIN_PERCENT && realProgress < LEGACY_MTK_STALL_ZONE_MAX_PERCENT\n if (!inStallZone) return\n\n this.mtkStallDetectTimer = setTimeout(() => {\n this.mtkStallDetectTimer = null\n const stalledAt = this.lastRealMtkProgress\n const prev = this.mtkSimulatedPercent\n const target = Math.max(\n prev !== null ? Math.max(prev, stalledAt + 1) : stalledAt + 1,\n LEGACY_MTK_SIM_FLOOR_PERCENT,\n )\n console.log(\n `[OTA_PROGRESS] legacy mtk install stalled at ${stalledAt}%, simulating display progress from ${target}%`,\n )\n this.setMtkSimulatedPercent(target)\n this.mtkSimTickTimer = setInterval(() => {\n const current = this.mtkSimulatedPercent ?? stalledAt + 1\n const capped = Math.min(current + 1, LEGACY_MTK_SIM_CAP_PERCENT)\n this.setMtkSimulatedPercent(capped)\n if (capped >= LEGACY_MTK_SIM_CAP_PERCENT && this.mtkSimTickTimer) {\n clearInterval(this.mtkSimTickTimer)\n this.mtkSimTickTimer = null\n }\n }, LEGACY_MTK_SIM_TICK_MS)\n }, LEGACY_MTK_STALL_DETECT_MS)\n }\n\n // --- watchdogs / send path ---\n\n /**\n * Read the current derived display state from the store + internal state\n * synchronously — used inside setTimeout callbacks.\n */\n private computeDisplayStateNow(): DisplayState {\n const state = useGlassesStore.getState()\n return deriveDisplayState({\n otaStatus: state.otaStatus,\n otaProgress: state.otaProgress,\n connected: isGlassesConnected(state.connection),\n errorMsg: this.errorMsg,\n sawReconnectEdge: this.sawReconnectEdge,\n legacyApkSettleHold: this.legacyApkSettleHold,\n apkCompletedViaBuildIncrease: this.apkCompletedViaBuildIncrease,\n besRestartRecovery: this.besRestartRecovery,\n versionChangeConverged: this.versionChangeConverged,\n versionChangeSession: this.versionChangeSession,\n })\n }\n\n /**\n * During an APK install the package installer kills and restarts the glasses\n * process, and the new process's completion push can lose its startup race\n * against the UART transport (incident rep_01KY31HEMTSBSMK8DVMNXJ5XGG: the\n * phone sat on a stale \"install in_progress 0%\" until the stall watchdog\n * failed a successful update). The persisted session on the glasses always\n * knows the truth, so poll ota_query_status on the keepalive tick while an\n * apk step sits in its install phase — the reply either confirms progress or\n * delivers the missed completion. Gated to the apk install phase so a stray\n * idle reply can't disturb an active download; legacy (< 37) builds ignore\n * the query, which is harmless.\n *\n * The native query pends up to 15s and rejects a concurrent call with\n * request_in_flight — longer than the 10s tick — so exactly one poll is kept\n * in flight (the glasses being slow to answer IS the silent-restart window\n * this poll exists for) and rejections are swallowed: the next tick retries.\n */\n private maybePollApkInstallStatus(): void {\n if (this.isInVersionChangeDetour()) return\n if (this.apkInstallPollInFlight) return\n const s = useGlassesStore.getState().otaStatus\n if (s?.stepType === \"apk\" && s.phase === \"install\" && s.status === \"in_progress\") {\n this.apkInstallPollInFlight = true\n void BluetoothSdk.sendOtaQueryStatus()\n .catch(() => {})\n .finally(() => {\n this.apkInstallPollInFlight = false\n })\n }\n }\n\n /**\n * \"Glasses are talking to us\" — suppresses retry if the native request later rejects.\n * Important: this does NOT clear the stuck-at-zero watchdog; that one fires\n * on real progress > 0% (see {@link onFirstNonZeroProgress}).\n */\n private onFirstActivity(): void {\n if (this.hasFirstActivity) return\n this.hasFirstActivity = true\n if (this.otaStartOwnership?.outcome === \"pending\") {\n this.otaStartOwnership.outcome = \"acknowledged\"\n }\n this.clearRetryTimeout()\n }\n\n /**\n * \"Real download progress arrived\" — clears the stuck-at-zero watchdog. We\n * deliberately wait for non-zero progress before clearing this so that an\n * ota_status reply with stepPercent: 0 (which is \"first activity\" but not\n * \"real progress\") doesn't disable the only watchdog that catches a wedged\n * download.\n */\n private onFirstNonZeroProgress(): void {\n if (this.hasFirstNonZeroProgress) return\n this.hasFirstNonZeroProgress = true\n this.clearStuckTimeout()\n }\n\n private maybeStartGlobalTimeout(): void {\n if (this.globalTimeoutStarted) return\n this.globalTimeoutStarted = true\n // Legacy-shape check happens once, when the session cap is armed at the first\n // ota_start send (WP 8C-b): old builds get the padded legacy cap for the whole\n // session; a session that starts unified keeps the unified cap.\n const globalTimeoutMs =\n this.versionChangeSession || this.isLegacySessionShapeNow() ? LEGACY_GLOBAL_OTA_TIMEOUT_MS : GLOBAL_OTA_TIMEOUT_MS\n this.globalTimeout = setTimeout(() => {\n this.globalTimeout = null\n this.globalTimeoutStarted = false\n if (isTerminalForWatchdog(this.computeDisplayStateNow())) return\n console.log(\"[OTA_PROGRESS] watchdog: global timeout fired, failing session\")\n this.clearPerStepTimers()\n // Legacy parity: the old screen's global-timeout handler also killed the apk\n // completion timer and the MTK stall simulation (the flags/percent stay put —\n // errorMsg outranks them in the projection, and retry()/last-write-wins reset them).\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n this.setErrorMsg(OtaProgressMessages.globalTimeout)\n }, globalTimeoutMs)\n }\n\n private armStuckWatchdogOnly(): void {\n this.clearStuckTimeout()\n\n // Durations resolved at arm time (WP 8C-b): legacy-shaped sessions get the\n // padded values progress-legacy.tsx used for old (< 37) builds.\n const legacySession = this.isLegacySessionShapeNow()\n const stuckTimeoutMs = legacySession ? LEGACY_DOWNLOAD_STUCK_TIMEOUT_MS : DOWNLOAD_STUCK_TIMEOUT_MS\n\n this.stuckTimeout = setTimeout(() => {\n this.stuckTimeout = null\n const d = this.computeDisplayStateNow()\n const state = useGlassesStore.getState()\n if (d !== \"starting\" && !(d === \"updating\" && state.otaStatus?.phase === \"download\")) {\n return\n }\n const pct = latestPercentForStuck(state.otaStatus, state.otaProgress)\n if (pct !== 0) return\n console.log(`[OTA_PROGRESS] watchdog: stuck at 0% for ${stuckTimeoutMs}ms, failing`)\n this.clearRetryTimeout()\n this.setErrorMsg(OtaProgressMessages.stalledOrStuck)\n }, stuckTimeoutMs)\n }\n\n /** Arm the 0%-stuck watchdog only when this logical session has none. */\n private maybeArmStuckWatchdog(): void {\n if (this.stuckTimeout || this.hasFirstNonZeroProgress) return\n this.armStuckWatchdogOnly()\n }\n\n private sendOtaStartWithWatchdogs(): Promise<void> {\n // INVARIANT BACKSTOP — not normal control flow. Every entry point that can drive the\n // glasses (connect-edge, query fallback, retry, mount) carries its own detour gate with the\n // right behavior for that site; this final check only exists so that a FUTURE entry point\n // that forgets its gate degrades to a refused send + loud log instead of a corrupted\n // transaction (an ota_start mid-detour starts a parallel install on the factory build and\n // can trigger a second handoff). If this ever fires, a missed site gate exists — fix it.\n if (this.isInVersionChangeDetour()) {\n console.error(\n \"[OTA_PROGRESS] BACKSTOP: refused ota_start during a latched version-change detour — a caller is missing its detour gate\",\n )\n return Promise.resolve()\n }\n const existingOwnership = this.otaStartOwnership\n if (existingOwnership?.outcome === \"pending\") {\n this.maybeStartGlobalTimeout()\n if (this.selectedTransport === \"wifi\" || this.hotspotManifestUrl) this.maybeArmStuckWatchdog()\n console.log(\"[OTA_PROGRESS] ota_start already pending — adopting existing native request\")\n return existingOwnership.promise\n }\n if (existingOwnership?.outcome === \"acknowledged\") {\n this.maybeStartGlobalTimeout()\n this.maybeArmStuckWatchdog()\n console.log(\"[OTA_PROGRESS] ota_start already acknowledged — refusing duplicate start\")\n return Promise.resolve()\n }\n if (existingOwnership?.outcome === \"rejected\" && !this.prepareFreshOtaStartAttempt()) {\n return Promise.resolve()\n }\n this.maybeStartGlobalTimeout()\n if (this.selectedTransport === \"wifi\" || this.hotspotManifestUrl) this.maybeArmStuckWatchdog()\n\n const ownership: OtaStartOwnership = {\n outcome: \"pending\",\n promise: Promise.resolve(),\n }\n ownership.promise = this.performOtaStart(ownership)\n this.otaStartOwnership = ownership\n return ownership.promise\n }\n\n private async performOtaStart(ownership: OtaStartOwnership): Promise<void> {\n let nativeStartAttempted = false\n try {\n const state = useGlassesStore.getState()\n let otaVersionUrl = resolveOtaManifestUrl(state.otaVersionUrl, state.buildNumber)\n if (this.selectedTransport === \"hotspot\") {\n if (!this.hotspotManifestUrl) {\n if (!this.preparedCheckResult) {\n throw new Error(\"No selected OTA check is available for hotspot staging\")\n }\n this.hotspotManifestUrl = await hotspotOtaTransport.prepare(this.preparedCheckResult, (progress) => {\n this.hotspotPhase = progress.phase\n this.hotspotArtifactPercent = progress.artifact?.artifactPercent ?? null\n this.emitInternalChange()\n })\n }\n otaVersionUrl = this.hotspotManifestUrl\n this.maybeArmStuckWatchdog()\n }\n if (!otaVersionUrl) {\n throw new Error(\"OTA is disabled because this build has no immutable manifest pin\")\n }\n console.log(`[OTA_PROGRESS] sending ota_start with ${this.selectedTransport} manifest URL: ${otaVersionUrl}`)\n nativeStartAttempted = true\n await BluetoothSdk.startOtaUpdate(otaVersionUrl)\n if (this.otaStartOwnership !== ownership) return\n // The public SDK promise resolves only from ota_start_ack. Treat that\n // resolution as the acknowledgement even if the parallel event dispatch\n // reaches the coordinator later (or is dropped by a remount).\n this.handleAck()\n } catch (err) {\n console.warn(\"[OTA_PROGRESS] sendOtaStart threw\", err)\n\n if (this.otaStartOwnership !== ownership) return\n\n if (this.selectedTransport === \"hotspot\" && !nativeStartAttempted) {\n ownership.outcome = \"rejected\"\n this.clearStuckTimeout()\n await this.teardownHotspotTransport()\n if (this.attached) this.setErrorMsg(hotspotPreflightErrorMessage(err))\n return\n }\n\n // A received ota_status/legacy progress event, or the exact legacy APK\n // build-number proof, proves that this logical start was accepted. Its\n // application-level ack may be lost while the update continues; never\n // create another transaction or fail a live, restarting, or completed\n // session because that stale promise timed out.\n if (this.hasFirstActivity || this.apkCompletedViaBuildIncrease) {\n ownership.outcome = \"acknowledged\"\n console.log(\"[OTA_PROGRESS] ota_start rejection arrived after acceptance proof — ignoring stale rejection\")\n return\n }\n\n ownership.outcome = \"rejected\"\n if (!this.attached) return\n this.clearStuckTimeout()\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\n \"[OTA_PROGRESS] ota_start request ended while disconnected; deferring retry to reconnect arbitration\",\n )\n return\n }\n if (this.retryCount < MAX_RETRIES - 1) {\n this.retryCount += 1\n const retryIntervalMs = this.isLegacySessionShapeNow() ? LEGACY_RETRY_INTERVAL_MS : RETRY_INTERVAL_MS\n console.log(\n `[OTA_PROGRESS] ota_start request ended without ack or activity; retrying after ${retryIntervalMs}ms (attempt ${\n this.retryCount + 1\n }/${MAX_RETRIES})`,\n )\n this.retryTimeout = setTimeout(() => {\n this.retryTimeout = null\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\"[OTA_PROGRESS] ota_start retry paused while disconnected; reconnect arbitration will resume\")\n return\n }\n void this.sendOtaStartWithWatchdogs()\n }, retryIntervalMs)\n } else {\n console.log(\"[OTA_PROGRESS] sendOtaStart failed after max retries, failing session\")\n this.setErrorMsg(OtaProgressMessages.sendOtaStartFailed)\n }\n }\n }\n\n private async teardownHotspotTransport(): Promise<void> {\n if (this.selectedTransport !== \"hotspot\" && !this.hotspotManifestUrl) return\n await hotspotOtaTransport.teardown()\n this.hotspotManifestUrl = null\n this.hotspotPhase = \"idle\"\n this.hotspotArtifactPercent = null\n this.emitInternalChange()\n }\n\n /**\n * After sending ota_query_status, wait QUERY_REPLY_TIMEOUT_MS for the glasses\n * to reply with a useful ota_status. A unified session may start again only\n * after an explicit \"idle\" reply, or after a locally rejected ota_start has\n * produced no activity and no authoritative reply across reconnect. Legacy\n * builds ignore ota_query_status, so their established timeout fallback\n * remains the compatibility path.\n *\n * Cleared as soon as a non-idle otaStatus or any otaProgress lands in the\n * store (see the reaction block above). An idle reply intentionally does NOT\n * cancel the fallback, so reconnects against a wiped/lost session still recover.\n */\n private armQueryReplyFallback(reason: \"reconnect\" | \"initial-mount\" | \"retry\"): void {\n this.clearQueryReplyTimeout()\n this.queryReplyTimeout = setTimeout(() => {\n this.queryReplyTimeout = null\n const state = useGlassesStore.getState()\n // If we already got a useful reply, we'd have been cleared. Defensive\n // re-check: idle replies must not block the retry. Legacy-shaped state is\n // exempt (WP 8C-b): old (< 37) builds ignore ota_query_status entirely, so\n // whatever legacy-shaped status/progress sits in the store is a pre-query\n // leftover, not a reply — a NEW legacy event would have cleared this timer\n // through the reaction pass. Only a unified reply suppresses the fallback.\n const legacySession = this.isLegacySessionShapeNow()\n if (!legacySession && hasRecoveringOtaReply(state.otaStatus, state.otaProgress)) return\n const explicitIdle = state.otaStatus?.status === \"idle\"\n const rejectedStart = this.otaStartOwnership?.outcome === \"rejected\"\n if (!legacySession && !explicitIdle && !rejectedStart) {\n console.log(\n `[OTA_PROGRESS] watchdog: ota_query_status got no authoritative idle reply in ${QUERY_REPLY_TIMEOUT_MS}ms (reason=${reason}); preserving the existing session`,\n )\n return\n }\n // Don't fire if we've left the active phase (e.g. user backed out, error overlay).\n if (isTerminalForWatchdog(this.computeDisplayStateNow())) return\n let fallbackCause = \"legacy query timeout\"\n if (explicitIdle) fallbackCause = \"idle ota_status\"\n else if (rejectedStart) fallbackCause = \"rejected ota_start with no recovery reply\"\n console.log(`[OTA_PROGRESS] watchdog: ${fallbackCause} (reason=${reason}), falling back to ota_start`)\n this.retryCount = 0\n if (this.otaStartOwnership?.outcome !== \"pending\" && !this.prepareFreshOtaStartAttempt()) return\n void this.sendOtaStartWithWatchdogs()\n }, QUERY_REPLY_TIMEOUT_MS)\n }\n\n // --- timer cleanup helpers ---\n\n private clearProgressTimeout(): void {\n if (this.progressTimeout) {\n clearTimeout(this.progressTimeout)\n this.progressTimeout = null\n }\n }\n\n private clearRetryTimeout(): void {\n if (this.retryTimeout) {\n clearTimeout(this.retryTimeout)\n this.retryTimeout = null\n }\n }\n\n private clearStuckTimeout(): void {\n if (this.stuckTimeout) {\n clearTimeout(this.stuckTimeout)\n this.stuckTimeout = null\n }\n }\n\n private clearGlobalTimeout(): void {\n if (this.globalTimeout) {\n clearTimeout(this.globalTimeout)\n this.globalTimeout = null\n }\n this.globalTimeoutStarted = false\n }\n\n private clearPingInterval(): void {\n if (this.pingInterval) {\n clearInterval(this.pingInterval)\n this.pingInterval = null\n }\n }\n\n private clearQueryReplyTimeout(): void {\n if (this.queryReplyTimeout) {\n clearTimeout(this.queryReplyTimeout)\n this.queryReplyTimeout = null\n }\n }\n\n private clearContinueLockoutTimer(): void {\n if (this.continueLockoutTimer) {\n clearTimeout(this.continueLockoutTimer)\n this.continueLockoutTimer = null\n }\n }\n\n private clearLegacyApkSettleTimer(): void {\n if (this.legacyApkSettleTimer) {\n clearTimeout(this.legacyApkSettleTimer)\n this.legacyApkSettleTimer = null\n }\n }\n\n private clearMtkSimulationTimers(): void {\n if (this.mtkStallDetectTimer) {\n clearTimeout(this.mtkStallDetectTimer)\n this.mtkStallDetectTimer = null\n }\n if (this.mtkSimTickTimer) {\n clearInterval(this.mtkSimTickTimer)\n this.mtkSimTickTimer = null\n }\n }\n\n /**\n * NOTE (WP 8C): the legacy apk settle timer and the MTK stall simulation timers are\n * deliberately NOT per-step watchdogs — a per-step failure must not kill them (the\n * legacy screen kept the simulation ticking through a watchdog failure, and the\n * settle latch resolves completion, not liveness). They are cleared on detach,\n * retry(), global timeout, and their own supersession paths.\n */\n private clearPerStepTimers(): void {\n this.clearRetryTimeout()\n this.clearStuckTimeout()\n this.clearProgressTimeout()\n this.clearQueryReplyTimeout()\n }\n\n private clearAllOtaTimers(): void {\n this.clearPerStepTimers()\n this.clearGlobalTimeout()\n this.clearPingInterval()\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n }\n}\n\n/** Singleton — one install session machine per app process (matches the single progress screen). */\nexport const otaInstallCoordinator = new OtaInstallCoordinator()\n"]}
|
|
1
|
+
{"version":3,"file":"OtaInstallCoordinator.js","sourceRoot":"","sources":["../../src/services/OtaInstallCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OtaInstallCoordinator — engine-owned OTA install state machine (WP 8B).\n *\n * Owns every timer/retry/sequencing rule that used to live in the host screen\n * `mobile/src/app/ota/progress.tsx`: the global session timeout, serialized\n * ota_start retries, the stuck-at-zero watchdog, the progress-stall watchdog keyed\n * on a staleness signature, connect-edge arbitration (initial mount vs\n * reconnect vs post-APK reboot), the ota_query_status reply fallback, the ping\n * keepalive, the ota_start_ack / mtk_update_complete listeners, and terminal\n * cleanup. The host progress screen is a pure renderer over\n * `snapshot()`/`onSnapshot()` plus the `attach()/detach()/retry()/finish()`\n * commands (exposed as `engine.ota.installSession`).\n *\n * The reaction pass mirrors the old component's effect ordering: a\n * pass diffs the store-derived inputs (connected / otaStatus / otaProgress /\n * displayState / stall signature) exactly like the old effect dep arrays, and\n * state written mid-pass queues a follow-up pass — the same way a setState\n * during React effects scheduled a re-render after the current effect batch.\n */\nimport BluetoothSdk, {type OtaProgress, type OtaStatus} from \"@mentra/bluetooth-sdk\"\nimport GlobalEventEmitter from \"../utils/GlobalEventEmitter\"\nimport {isGlassesConnected, useGlassesStore} from \"../stores/glasses\"\nimport {resolveOtaManifestUrl} from \"./otaManifestUrl\"\nimport {hotspotOtaTransport, type HotspotOtaPhase} from \"./HotspotOtaTransport\"\nimport type {OtaCheckCurrentGlassesResult} from \"./OtaUpdateCheckService\"\nimport {deriveDisplayState, type DisplayState} from \"./otaDisplayState\"\nimport {\n BES_CONTINUE_LOCKOUT_MS,\n DOWNLOAD_STUCK_TIMEOUT_MS,\n GLOBAL_OTA_TIMEOUT_MS,\n LEGACY_APK_COMPLETION_SETTLE_MS,\n LEGACY_BES_CONTINUE_LOCKOUT_MS,\n LEGACY_DOWNLOAD_STUCK_TIMEOUT_MS,\n LEGACY_GLOBAL_OTA_TIMEOUT_MS,\n LEGACY_MTK_INSTALL_TIMEOUT_MS,\n LEGACY_MTK_SIM_CAP_PERCENT,\n LEGACY_MTK_SIM_FLOOR_PERCENT,\n LEGACY_MTK_SIM_TICK_MS,\n LEGACY_MTK_STALL_DETECT_MS,\n LEGACY_MTK_STALL_ZONE_MAX_PERCENT,\n LEGACY_MTK_STALL_ZONE_MIN_PERCENT,\n LEGACY_PING_INTERVAL_MS,\n LEGACY_PROGRESS_TIMEOUT_MS,\n LEGACY_RETRY_INTERVAL_MS,\n MAX_RETRIES,\n MTK_INSTALL_TIMEOUT_MS,\n OtaProgressMessages,\n PING_INTERVAL_MS,\n PROGRESS_TIMEOUT_MS,\n QUERY_REPLY_TIMEOUT_MS,\n RETRY_INTERVAL_MS,\n isLegacyShapedOtaSession,\n isLegacyShapedOtaStatus,\n selectOtaProtocolProfile,\n type OtaProtocolProfile,\n} from \"./otaInstallPolicy\"\n\nfunction isTerminalForWatchdog(d: DisplayState): boolean {\n return d === \"complete\" || d === \"failed\" || d === \"restarting\"\n}\n\nfunction hotspotPreflightErrorMessage(error: unknown): string {\n const code =\n typeof error === \"object\" && error !== null && \"code\" in error ? String((error as {code: unknown}).code) : \"\"\n switch (code) {\n case \"artifact_download_failed\":\n return OtaProgressMessages.hotspotArtifactDownloadFailed\n case \"artifact_verify_failed\":\n case \"manifest_invalid\":\n return OtaProgressMessages.hotspotArtifactVerifyFailed\n case \"hotspot_wifi_permission_denied\":\n return OtaProgressMessages.hotspotWifiPermissionDenied\n case \"hotspot_start_failed\":\n return OtaProgressMessages.hotspotStartFailed\n case \"hotspot_join_failed\":\n return OtaProgressMessages.hotspotJoinFailed\n case \"hotspot_server_failed\":\n return OtaProgressMessages.hotspotServerFailed\n default:\n return OtaProgressMessages.hotspotServerFailed\n }\n}\n\n/** Non-empty when glasses are actively reporting work — drives stall timeout reset. */\nfunction buildProgressStalenessSignature(\n otaStatus: OtaStatus | null,\n otaProgress: OtaProgress | null,\n displayState: DisplayState,\n): string {\n if (displayState !== \"starting\" && displayState !== \"updating\") return \"\"\n if (otaStatus && (otaStatus.status === \"in_progress\" || otaStatus.status === \"step_complete\")) {\n return `s:${otaStatus.sessionId}|${otaStatus.status}|${otaStatus.phase}|${otaStatus.stepType}|${otaStatus.stepPercent}|${otaStatus.overallPercent}`\n }\n // Legacy-shaped BES download FINISHED (WP 8C): the legacy screen kept a progress\n // watchdog armed while waiting for the BES install events to start; keep the stall\n // watchdog armed here too so a wedged flash still fails instead of hanging.\n if (\n isLegacyShapedOtaStatus(otaStatus) &&\n otaStatus?.stepType === \"bes\" &&\n otaStatus.phase === \"download\" &&\n otaStatus.status === \"complete\"\n ) {\n return \"s:legacy-bes-download-complete-await-install\"\n }\n if (otaProgress && (otaProgress.status === \"PROGRESS\" || otaProgress.status === \"STARTED\")) {\n return `p:${otaProgress.currentUpdate}|${otaProgress.stage}|${otaProgress.status}|${otaProgress.progress}`\n }\n return \"\"\n}\n\nfunction progressTimeoutDurationMs(\n otaStatus: OtaStatus | null,\n otaProgress: OtaProgress | null,\n legacySession: boolean,\n): number {\n if (otaStatus?.stepType === \"mtk\" && otaStatus.phase === \"install\") {\n return legacySession ? LEGACY_MTK_INSTALL_TIMEOUT_MS : MTK_INSTALL_TIMEOUT_MS\n }\n if (otaProgress?.currentUpdate === \"mtk\" && otaProgress.stage === \"install\") {\n return legacySession ? LEGACY_MTK_INSTALL_TIMEOUT_MS : MTK_INSTALL_TIMEOUT_MS\n }\n return legacySession ? LEGACY_PROGRESS_TIMEOUT_MS : PROGRESS_TIMEOUT_MS\n}\n\nfunction latestPercentForStuck(otaStatus: OtaStatus | null, otaProgress: OtaProgress | null): number {\n if (otaProgress?.progress != null) return otaProgress.progress\n if (otaStatus?.status === \"in_progress\" || otaStatus?.status === \"step_complete\") {\n return Math.max(otaStatus.overallPercent ?? 0, otaStatus.stepPercent ?? 0)\n }\n return 0\n}\n\n/**\n * \"idle\" ota_status means the glasses have no active session — that is NOT a\n * recovery signal, so the query-reply fallback must keep firing and retry\n * ota_start. Only treat real progress or a non-idle ota_status as a useful\n * reply that cancels the fallback.\n */\nfunction hasRecoveringOtaReply(otaStatus: OtaStatus | null, otaProgress: OtaProgress | null): boolean {\n if (otaProgress) return true\n return !!otaStatus && otaStatus.status !== \"idle\"\n}\n\n/** Read model the host progress screen renders from. */\nexport interface OtaInstallSnapshot {\n displayState: DisplayState\n errorMsg: string\n continueButtonDisabled: boolean\n connected: boolean\n otaStatus: OtaStatus | null\n otaProgress: OtaProgress | null\n /**\n * Display-only simulated percent for legacy (< 37) MTK install stalls (WP 8C-e), or\n * null. The MTK system install goes quiet around 49-50%; the legacy screen simulated\n * +1% ticks up to 60% purely to reassure the user. Render max(real, simulated).\n */\n mtkInstallStallSimulatedPercent: number | null\n /** True for a downgrade (version-change) session — the UI narrates it differently. */\n isVersionChange: boolean\n /** True once the glasses reported the exact pinned target (the downgrade truly completed). */\n versionChangeConverged: boolean\n /**\n * Sub-phase of the downgrade detour for the progress narrative, or null when not\n * in one: \"installing\" before the handoff, \"restarting\" while the glasses are dark\n * (uninstall / factory flicker / target install), \"verifying\" once reconnected and\n * checking the version. Completion is the \"complete\" displayState.\n */\n versionChangePhase: \"installing\" | \"restarting\" | \"verifying\" | null\n /** Pre-ota_start phone staging/join state for a hotspot attempt. */\n hotspotPhase: HotspotOtaPhase\n hotspotArtifactPercent: number | null\n /** Transport selected from the checked glasses capabilities and Wi-Fi state. */\n transport: \"wifi\" | \"hotspot\"\n}\n\ntype OtaStartOutcome = \"pending\" | \"acknowledged\" | \"rejected\"\n\ninterface OtaStartOwnership {\n outcome: OtaStartOutcome\n promise: Promise<void>\n}\n\nclass OtaInstallCoordinator {\n private attached = false\n private preparedCheckResult: OtaCheckCurrentGlassesResult | null = null\n private selectedTransport: \"wifi\" | \"hotspot\" = \"wifi\"\n private hotspotManifestUrl: string | null = null\n private hotspotPhase: HotspotOtaPhase = \"idle\"\n private hotspotArtifactPercent: number | null = null\n\n // Genuinely session-local state (was component state/refs).\n private errorMsg = \"\"\n private sawReconnectEdge = false\n private continueButtonDisabled = false\n // True once this session reported an APK step. After an APK install the ASG\n // process restarts with a new build number, so finish() must clear the stale\n // one before check-for-updates re-checks (mirrors the legacy screen).\n private apkStepSeen = false\n private prevConnected = false\n\n // Legacy (< 37) compatibility state, ported from progress-legacy.tsx (WP 8C).\n // Build number at session start — legacy APK completion is detected by the build\n // number increasing past it when the explicit reconnect status never arrives.\n private initialBuildNumber: string | null = null\n // Captured with initialBuildNumber: whether the selected update includes an APK step.\n private apkExpectedInSession = false\n // Latched when the legacy build-number completion fires; projected as \"complete\".\n private apkCompletedViaBuildIncrease = false\n // The split routes selected legacy/unified behavior before navigation. Keep\n // that choice sticky while an APK step upgrades ASG mid-flow.\n private protocolProfile: OtaProtocolProfile | null = null\n\n // BES reboot recovery. Native bridges normalize explicit BES success to a\n // terminal status; pre-37 flows additionally retain the legacy screen's\n // lost-FINISHED fallback. Completion still requires a BES-specific observed\n // disconnect -> reconnect lifecycle, never the generic session reconnect flag.\n private besRestartExpected = false\n private besRestartDisconnectObserved = false\n private besRestartRecovery: \"awaiting\" | \"complete\" | null = null\n\n // Downgrade detour (version-change mode). Captured at attach from the selected\n // update: the pinned target is a LOWER build, executed by the recovery worker via\n // uninstall->reinstall, so the phone must NOT drive ota_start on the intermediate\n // reconnect (the passive factory build) and completion is exact-version\n // convergence, not a build-number increase.\n private versionChangeSession = false\n private versionChangeTarget: number | null = null\n // Set once ASG reports the apk install has started (the handoff point after which\n // ASG dies and the recovery worker owns the transaction).\n private versionChangeInstallStarted = false\n // Latched when a reconnect reports buildNumber === versionChangeTarget.\n private versionChangeConverged = false\n // Holds a legacy apk install FINISHED out of \"complete\" for the settle window.\n private legacyApkSettleHold = false\n // Display-only legacy MTK install stall simulation.\n private mtkSimulatedPercent: number | null = null\n private lastRealMtkProgress = 0\n\n // Timer handles\n private globalTimeout: ReturnType<typeof setTimeout> | null = null\n private globalTimeoutStarted = false\n private retryTimeout: ReturnType<typeof setTimeout> | null = null\n private stuckTimeout: ReturnType<typeof setTimeout> | null = null\n private progressTimeout: ReturnType<typeof setTimeout> | null = null\n private pingInterval: ReturnType<typeof setInterval> | null = null\n private queryReplyTimeout: ReturnType<typeof setTimeout> | null = null\n private continueLockoutTimer: ReturnType<typeof setTimeout> | null = null\n private legacyApkSettleTimer: ReturnType<typeof setTimeout> | null = null\n private mtkStallDetectTimer: ReturnType<typeof setTimeout> | null = null\n private mtkSimTickTimer: ReturnType<typeof setInterval> | null = null\n\n // Request / retry bookkeeping (no glasses source)\n // At most one apk-install status poll in flight (native rejects concurrent queries).\n private apkInstallPollInFlight = false\n // The native SDK owns one ota_start request until its application-level ack or\n // timeout. Keep pending ownership across attach/detach, and retain the settled\n // outcome while attached so Retry/query fallback cannot reinterpret an accepted\n // command as permission to start a second OTA transaction.\n private otaStartOwnership: OtaStartOwnership | null = null\n private hasFirstActivity = false\n // Stuck-at-zero watchdog clears only on first NON-ZERO progress; \"first activity\"\n // alone (e.g. ota_status with stepPercent=0) used to clear it too eagerly.\n private hasFirstNonZeroProgress = false\n private retryCount = 0\n\n // Log displayState transitions only (not every pass).\n private prevDisplayState: DisplayState | null = null\n\n // Last-handled reaction inputs — the equivalents of the old effect dep arrays.\n private lastConnected = false\n private lastOtaStatus: OtaStatus | null = null\n private lastOtaProgress: OtaProgress | null = null\n private lastBuildNumber = \"\"\n private lastDisplayState: DisplayState | null = null\n private lastStallSig = \"\"\n\n // Reaction pass re-entrancy guard (mirrors React deferring a setState-during-\n // effects re-render until the current effect batch finished).\n private reacting = false\n private reactQueued = false\n\n private storeUnsubscribe: (() => void) | null = null\n private snapshotCheckers = new Set<() => void>()\n\n // --- public surface (engine.ota.installSession) ---\n\n /** Select the transport at the existing install entry point before the progress route attaches. */\n prepare(checkResult: OtaCheckCurrentGlassesResult): \"wifi\" | \"hotspot\" {\n const state = useGlassesStore.getState()\n if (!state.wifiStatusKnown) {\n throw new Error(\"Glasses Wi-Fi status is not available\")\n }\n const hotspotSupported = state.hotspotOtaVersion === 1\n const wifiConnected = state.wifi.state === \"connected\"\n if (!wifiConnected && !hotspotSupported) {\n throw new Error(\"Connected glasses require Wi-Fi for OTA\")\n }\n this.preparedCheckResult = checkResult\n this.selectedTransport = wifiConnected ? \"wifi\" : \"hotspot\"\n this.hotspotManifestUrl = null\n this.hotspotPhase = \"idle\"\n this.hotspotArtifactPercent = null\n return this.selectedTransport\n }\n\n /**\n * Bind the state machine to a mounted progress screen. Idempotent per\n * attach/detach cycle. Runs the initial-mount arbitration (send ota_start\n * when connected with no session; otherwise ota_query_status + reply\n * fallback) and starts reacting to store changes + BLE OTA events.\n */\n attach(): void {\n if (this.attached) return\n this.attached = true\n this.resetSessionState()\n const initialState = useGlassesStore.getState()\n this.protocolProfile = selectOtaProtocolProfile(\n initialState.otaStatus,\n initialState.otaProgress,\n initialState.buildNumber,\n )\n const selected = initialState.otaUpdateAvailable\n if (selected?.isDowngrade && typeof selected.versionCode === \"number\" && selected.versionCode > 0) {\n this.versionChangeSession = true\n this.versionChangeTarget = selected.versionCode\n console.log(`[OTA_PROGRESS] version-change (downgrade) session, target=${selected.versionCode}`)\n }\n this.prevConnected = isGlassesConnected(useGlassesStore.getState().connection)\n this.storeUnsubscribe = useGlassesStore.subscribe(() => this.react())\n // Mount pass: every reaction block runs once (like all effects on mount),\n // then any passes queued by state written during the blocks.\n this.reacting = true\n try {\n this.runPass(true)\n while (this.reactQueued) {\n this.reactQueued = false\n this.runPass(false)\n }\n } finally {\n this.reacting = false\n }\n }\n\n /**\n * Unbind on screen unmount: clears ALL timers/subscriptions/listeners and\n * resets the session-local state (the old component state died with the\n * component) so a re-attach is a fresh session.\n */\n detach(): void {\n if (!this.attached) return\n this.attached = false\n if (this.storeUnsubscribe) {\n this.storeUnsubscribe()\n this.storeUnsubscribe = null\n }\n GlobalEventEmitter.off(\"ota_start_ack\", this.handleAck)\n GlobalEventEmitter.off(\"mtk_update_complete\", this.handleMtkComplete)\n GlobalEventEmitter.off(\"glasses_session_changed\", this.handleGlassesSessionChanged)\n this.clearAllOtaTimers()\n this.clearContinueLockoutTimer()\n // Only native command ownership survives a remount. Once the command has\n // settled, the glasses store/durable ota_status is the session authority.\n if (this.otaStartOwnership?.outcome !== \"pending\") {\n this.otaStartOwnership = null\n }\n this.resetSessionState()\n }\n\n /** Retry after a failure: clear state and re-send ota_start (if connected). */\n retry(): void {\n // While the recovery worker owns the detour (apk install latched, not yet\n // converged), the phone must not drive: an ota_start now would push the\n // factory/surviving build into a parallel download-install, and a second\n // handoff would begin()/REPLACE the live transaction under the running\n // worker. Retry just re-enters the reconcile wait — convergence or the\n // session timeout decides the real outcome.\n if (this.isInVersionChangeDetour()) {\n console.log(\"[OTA_PROGRESS] retry during version-change detour — re-entering wait (no ota_start)\")\n this.setErrorMsg(\"\")\n this.emitInternalChange()\n return\n }\n const store = useGlassesStore.getState()\n const otaStatus = store.otaStatus\n const otaProgress = store.otaProgress\n const authoritativeFailure = otaStatus?.status === \"failed\" || otaProgress?.status === \"FAILED\"\n const hasUnfinishedSession =\n (!!otaStatus &&\n otaStatus.status !== \"idle\" &&\n otaStatus.status !== \"failed\" &&\n otaStatus.status !== \"complete\") ||\n (!!otaProgress && otaProgress.status !== \"FAILED\" && otaProgress.status !== \"FINISHED\")\n const shouldReconcile =\n this.otaStartOwnership?.outcome === \"pending\" ||\n (!authoritativeFailure &&\n (this.otaStartOwnership?.outcome === \"acknowledged\" || this.hasFirstActivity || hasUnfinishedSession))\n\n if (shouldReconcile) {\n console.log(\"[OTA_PROGRESS] retry pressed for an existing OTA session — reconciling without ota_start\")\n this.clearPerStepTimers()\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n this.clearContinueLockoutTimer()\n this.setErrorMsg(\"\")\n this.maybeStartGlobalTimeout()\n this.maybeArmStuckWatchdog()\n if (isGlassesConnected(store.connection)) {\n if (this.otaStartOwnership?.outcome === \"pending\") {\n void this.sendOtaStartWithWatchdogs()\n } else {\n void BluetoothSdk.queryOtaStatus().catch(() => {})\n this.armQueryReplyFallback(\"retry\")\n }\n }\n return\n }\n\n console.log(\"[OTA_PROGRESS] retry pressed after a rejected or terminal attempt — starting a fresh ota_start\")\n // Batch like the old event handler: React ran the whole handler (including\n // the ota_start send) before re-rendering + re-running effects.\n const wasReacting = this.reacting\n this.reacting = true\n try {\n this.clearPerStepTimers()\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n this.clearContinueLockoutTimer()\n this.retryCount = 0\n if (!this.prepareFreshOtaStartAttempt()) return\n this.resetBesRestartAttempt()\n this.setSawReconnectEdge(false)\n this.setErrorMsg(\"\")\n this.setContinueButtonDisabled(false)\n this.setLegacyApkSettleHold(false)\n this.setMtkSimulatedPercent(null)\n this.lastRealMtkProgress = 0\n store.setOtaProgress(null)\n store.setOtaStatus(null)\n if (isGlassesConnected(useGlassesStore.getState().connection)) {\n void this.sendOtaStartWithWatchdogs()\n }\n } finally {\n this.reacting = wasReacting\n }\n if (!wasReacting) this.react()\n }\n\n /**\n * Terminal-state cleanup half of the old Continue/Done handlers (navigation\n * stays in the screen): clear the selected update, and after an APK step\n * clear the stale build number so the next check re-reads version_info.\n */\n async finish(): Promise<void> {\n if (this.otaStartOwnership?.outcome !== \"pending\") {\n this.otaStartOwnership = null\n }\n useGlassesStore.getState().setOtaUpdateAvailable(null)\n if (this.apkStepSeen) {\n useGlassesStore.getState().setGlassesInfo({buildNumber: \"\"})\n }\n // The post-install check needs internet again. Do not let callers leave the\n // terminal screen while Android still owns the no-internet hotspot route.\n await this.teardownHotspotTransport()\n }\n\n /**\n * Abandon an interrupted session (the super-mode skip): terminal cleanup\n * plus dropping the session's status/progress read-state, so\n * deriveDisplayState doesn't resurrect the stale install when the host\n * navigates away and back through /ota routes.\n */\n async discard(): Promise<void> {\n await this.finish()\n const store = useGlassesStore.getState()\n store.setOtaStatus(null)\n store.setOtaProgress(null)\n }\n\n snapshot(): OtaInstallSnapshot {\n const state = useGlassesStore.getState()\n const connected = isGlassesConnected(state.connection)\n const otaStatus = state.otaStatus\n const otaProgress = state.otaProgress\n return {\n displayState: deriveDisplayState({\n otaStatus,\n otaProgress,\n connected,\n errorMsg: this.errorMsg,\n sawReconnectEdge: this.sawReconnectEdge,\n legacyApkSettleHold: this.legacyApkSettleHold,\n apkCompletedViaBuildIncrease: this.apkCompletedViaBuildIncrease,\n besRestartRecovery: this.besRestartRecovery,\n versionChangeConverged: this.versionChangeConverged,\n versionChangeSession: this.versionChangeSession,\n }),\n errorMsg: this.errorMsg,\n // Keep Continue disabled while the expected BES reboot is still in flight.\n continueButtonDisabled: this.continueButtonDisabled || this.besRestartRecovery === \"awaiting\",\n connected,\n // Copies: the snapshot must not hand callers mutable references into the store.\n otaStatus: otaStatus ? {...otaStatus} : null,\n otaProgress: otaProgress ? {...otaProgress} : null,\n mtkInstallStallSimulatedPercent: this.mtkSimulatedPercent,\n isVersionChange: this.versionChangeSession,\n versionChangeConverged: this.versionChangeConverged,\n versionChangePhase: this.deriveVersionChangePhase(connected),\n hotspotPhase: this.hotspotPhase,\n hotspotArtifactPercent: this.hotspotArtifactPercent,\n transport: this.selectedTransport,\n }\n }\n\n /**\n * True while the recovery worker owns the downgrade transaction (after the apk install\n * started, before convergence). During this window ASG is being uninstalled/reinstalled and\n * cannot answer the phone, so the coordinator must not ping, poll ota_query_status, or arm the\n * progress-stall watchdog — doing so drives the passive factory build and fails the session\n * before the target reconnects. Completion is exact-version convergence, detected separately.\n */\n private isInVersionChangeDetour(): boolean {\n return this.versionChangeSession && this.versionChangeInstallStarted && !this.versionChangeConverged\n }\n\n /** Downgrade-detour sub-phase for the progress narrative (see OtaInstallSnapshot). */\n private deriveVersionChangePhase(connected: boolean): \"installing\" | \"restarting\" | \"verifying\" | null {\n if (!this.versionChangeSession || this.versionChangeConverged) return null\n if (!this.versionChangeInstallStarted) return \"installing\"\n return connected ? \"verifying\" : \"restarting\"\n }\n\n /**\n * Subscribe to install snapshot changes, deduped on the projected JSON.\n * Fires on glasses-store changes AND coordinator-internal state changes\n * (errorMsg / reconnect edge / continue lockout). Returns an unsubscribe.\n */\n onSnapshot(cb: (snapshot: OtaInstallSnapshot) => void): () => void {\n let last = JSON.stringify(this.snapshot())\n const check = () => {\n const snap = this.snapshot()\n const key = JSON.stringify(snap)\n if (key === last) return\n last = key\n cb(snap)\n }\n this.snapshotCheckers.add(check)\n const unsubscribeStore = useGlassesStore.subscribe(check)\n return () => {\n this.snapshotCheckers.delete(check)\n unsubscribeStore()\n }\n }\n\n // --- internal state plumbing ---\n\n private resetSessionState(): void {\n this.errorMsg = \"\"\n this.sawReconnectEdge = false\n this.continueButtonDisabled = false\n this.apkStepSeen = false\n this.prevConnected = false\n this.initialBuildNumber = null\n this.apkExpectedInSession = false\n this.apkCompletedViaBuildIncrease = false\n this.protocolProfile = null\n this.resetBesRestartAttempt()\n this.versionChangeSession = false\n this.versionChangeTarget = null\n this.versionChangeInstallStarted = false\n this.versionChangeConverged = false\n this.legacyApkSettleHold = false\n this.mtkSimulatedPercent = null\n this.lastRealMtkProgress = 0\n this.apkInstallPollInFlight = false\n this.hasFirstActivity = false\n this.hasFirstNonZeroProgress = false\n this.retryCount = 0\n this.globalTimeoutStarted = false\n this.prevDisplayState = null\n this.lastConnected = false\n this.lastOtaStatus = null\n this.lastOtaProgress = null\n this.lastBuildNumber = \"\"\n this.lastDisplayState = null\n this.lastStallSig = \"\"\n this.reactQueued = false\n }\n\n /** Begin a genuinely new command attempt only after native ownership has settled. */\n private prepareFreshOtaStartAttempt(): boolean {\n if (this.otaStartOwnership?.outcome === \"pending\") {\n console.error(\"[OTA_PROGRESS] refused fresh ota_start while native still owns the previous request\")\n return false\n }\n this.otaStartOwnership = null\n this.hasFirstActivity = false\n this.hasFirstNonZeroProgress = false\n this.setApkCompletedViaBuildIncrease(false)\n return true\n }\n\n /** Reset only the reboot lifecycle that belongs to one install attempt. */\n private resetBesRestartAttempt(): void {\n this.besRestartExpected = false\n this.besRestartDisconnectObserved = false\n this.besRestartRecovery = null\n }\n\n /** Notify snapshot subscribers of a coordinator-internal state change. */\n private emitInternalChange(): void {\n for (const check of Array.from(this.snapshotCheckers)) check()\n }\n\n // Setters mirror the old setState calls: bail on identical values (React's\n // setState bailout), notify snapshot subscribers, and queue a reaction pass.\n private setErrorMsg(next: string): void {\n if (this.errorMsg === next) return\n this.errorMsg = next\n this.emitInternalChange()\n this.react()\n }\n\n private setSawReconnectEdge(next: boolean): void {\n if (this.sawReconnectEdge === next) return\n this.sawReconnectEdge = next\n this.emitInternalChange()\n this.react()\n }\n\n private setContinueButtonDisabled(next: boolean): void {\n if (this.continueButtonDisabled === next) return\n this.continueButtonDisabled = next\n this.emitInternalChange()\n this.react()\n }\n\n private setApkCompletedViaBuildIncrease(next: boolean): void {\n if (this.apkCompletedViaBuildIncrease === next) return\n this.apkCompletedViaBuildIncrease = next\n this.emitInternalChange()\n this.react()\n }\n\n private setLegacyApkSettleHold(next: boolean): void {\n if (this.legacyApkSettleHold === next) return\n this.legacyApkSettleHold = next\n this.emitInternalChange()\n this.react()\n }\n\n /** Display-only (WP 8C-e): notifies snapshot subscribers but never queues a reaction pass. */\n private setMtkSimulatedPercent(next: number | null): void {\n if (this.mtkSimulatedPercent === next) return\n this.mtkSimulatedPercent = next\n this.emitInternalChange()\n }\n\n /** Legacy/unified policy is selected once, matching the old sticky route choice. */\n private isLegacySessionShapeNow(): boolean {\n if (this.protocolProfile) return this.protocolProfile === \"legacy\"\n const state = useGlassesStore.getState()\n const selected = selectOtaProtocolProfile(\n state.otaStatus,\n state.otaProgress,\n this.initialBuildNumber || state.buildNumber,\n )\n if (selected) {\n this.protocolProfile = selected\n console.log(`[OTA_PROGRESS] protocol profile selected: ${selected}`)\n return selected === \"legacy\"\n }\n return isLegacyShapedOtaSession(state.otaStatus, state.otaProgress, state.buildNumber)\n }\n\n private react(): void {\n if (!this.attached) return\n if (this.reacting) {\n this.reactQueued = true\n return\n }\n this.reacting = true\n try {\n do {\n this.reactQueued = false\n this.runPass(false)\n } while (this.reactQueued)\n } finally {\n this.reacting = false\n }\n }\n\n /**\n * One reaction pass = one render + its changed-dep effects of the old\n * component, in the old declaration order.\n */\n private runPass(isMount: boolean): void {\n const state = useGlassesStore.getState()\n const connected = isGlassesConnected(state.connection)\n const otaStatus = state.otaStatus\n const otaProgress = state.otaProgress\n const buildNumber = state.buildNumber\n\n const connectedChanged = isMount || connected !== this.lastConnected\n const otaStatusChanged = isMount || otaStatus !== this.lastOtaStatus\n const otaProgressChanged = isMount || otaProgress !== this.lastOtaProgress\n const buildNumberChanged = isMount || buildNumber !== this.lastBuildNumber\n\n // Session-start build capture (legacy build-number APK completion, WP 8C-c) —\n // mirrors the legacy screen capturing initialBuildNumber on its first truthy value,\n // marked for APK only when the selected update sequence includes an apk step.\n if (!this.initialBuildNumber && buildNumber) {\n this.initialBuildNumber = buildNumber\n this.apkExpectedInSession = !!state.otaUpdateAvailable?.updates?.includes(\"apk\")\n }\n\n // Legacy pre-derivation compat (WP 8C): must run BEFORE deriveDisplayState so a\n // legacy apk install \"complete\" is held by the settle window in the same pass it\n // lands (never leaking a premature terminal pass to the watchdog blocks below).\n if (otaStatusChanged) {\n this.handleLegacyInstallCompleteEdge(otaStatus)\n }\n\n const legacySession = this.isLegacySessionShapeNow()\n\n if (this.isBesRestartExpected(otaStatus, otaProgress, legacySession)) {\n this.besRestartExpected = true\n }\n\n // Port the legacy route's actual reboot invariant before deriving display\n // state, so reconnecting with stale BES in_progress@100 never renders updating.\n if (connectedChanged && !connected && this.besRestartExpected && this.besRestartRecovery === null) {\n this.besRestartDisconnectObserved = true\n this.besRestartRecovery = \"awaiting\"\n console.log(\"[OTA_PROGRESS] BES restart disconnect observed — awaiting reconnect verification\")\n }\n if (this.besRestartRecovery === \"awaiting\" && connected) this.completeBesRestartRecovery()\n\n // Derived UI state — the glasses data IS the source of truth.\n const displayState = deriveDisplayState({\n otaStatus,\n otaProgress,\n connected,\n errorMsg: this.errorMsg,\n sawReconnectEdge: this.sawReconnectEdge,\n legacyApkSettleHold: this.legacyApkSettleHold,\n apkCompletedViaBuildIncrease: this.apkCompletedViaBuildIncrease,\n besRestartRecovery: this.besRestartRecovery,\n versionChangeConverged: this.versionChangeConverged,\n versionChangeSession: this.versionChangeSession,\n })\n const stallSig = buildProgressStalenessSignature(otaStatus, otaProgress, displayState)\n const stallDuration = progressTimeoutDurationMs(otaStatus, otaProgress, legacySession)\n\n const displayStateChanged = isMount || displayState !== this.lastDisplayState\n const stallSigChanged = isMount || stallSig !== this.lastStallSig\n\n // Commit this pass's inputs BEFORE running the blocks so state written\n // mid-pass (which queues a follow-up pass) diffs against what this pass\n // already handled — like React committing the render before its effects.\n this.lastConnected = connected\n this.lastOtaStatus = otaStatus\n this.lastOtaProgress = otaProgress\n this.lastBuildNumber = buildNumber\n this.lastDisplayState = displayState\n this.lastStallSig = stallSig\n\n if (this.prevDisplayState !== displayState) {\n console.log(\n `[OTA_PROGRESS] displayState ${this.prevDisplayState ?? \"<init>\"} -> ${displayState}`,\n JSON.stringify({\n connected,\n sawReconnectEdge: this.sawReconnectEdge,\n errorMsg: this.errorMsg || null,\n otaStatus: otaStatus\n ? {\n stepType: otaStatus.stepType,\n phase: otaStatus.phase,\n status: otaStatus.status,\n step: `${otaStatus.currentStep}/${otaStatus.totalSteps}`,\n pct: otaStatus.overallPercent,\n }\n : null,\n otaProgress: otaProgress\n ? {\n currentUpdate: otaProgress.currentUpdate,\n stage: otaProgress.stage,\n status: otaProgress.status,\n progress: otaProgress.progress,\n }\n : null,\n }),\n )\n this.prevDisplayState = displayState\n }\n\n // APK-step latch (was the [otaStatus] effect above the timers).\n if (otaStatusChanged && otaStatus?.stepType === \"apk\") {\n this.apkStepSeen = true\n }\n\n // Legacy MTK completion side effect (WP 8C-a): old builds never send the\n // mtk_update_complete BLE event; their install FINISHED is the completion signal,\n // and the legacy screen marked MTK as updated this session right there.\n if (\n otaStatusChanged &&\n isLegacyShapedOtaStatus(otaStatus) &&\n otaStatus?.stepType === \"mtk\" &&\n otaStatus.phase === \"install\" &&\n otaStatus.status === \"complete\"\n ) {\n console.log(\"[OTA_PROGRESS] legacy mtk install complete — marking MTK updated this session\")\n useGlassesStore.getState().setMtkUpdatedThisSession(true)\n }\n\n // Version-change (downgrade) install started: once ASG reports the apk install\n // phase, the handoff to the recovery worker has happened. From here the phone\n // stops driving ota_start (see runConnectEdge) and waits for exact-version\n // convergence — the wipe means no resumable ASG session and no build increase.\n if (\n this.versionChangeSession &&\n !this.versionChangeInstallStarted &&\n // Only latch from a status that belongs to THIS session: an install/apk status is a\n // response to our own acknowledged ota_start, so a leftover from a prior session\n // sitting in the store at mount cannot prematurely enter the detour wait (which would\n // suppress ota_start and hang the fresh downgrade until the global timeout).\n this.otaStartOwnership?.outcome === \"acknowledged\" &&\n otaStatus?.stepType === \"apk\" &&\n otaStatus.phase === \"install\"\n ) {\n console.log(\"[OTA_PROGRESS] version-change: apk install started — entering detour wait\")\n this.versionChangeInstallStarted = true\n this.emitInternalChange()\n }\n\n // Ownership refuted: ASG emits install/STARTED BEFORE handing off, so the latch above can\n // be set even when no transaction ends up owning the detour. Recovery answers every\n // handoff synchronously, so exactly three error codes prove non-ownership and release the\n // latch: downgrade_handoff_refused (recovery's explicit verdict),\n // downgrade_handoff_failed (no verdict at all — recovery dead/missing, so it never began),\n // and downgrade_transaction_stalled (the long-stop past recovery's own stale give-up).\n // An accepted-but-slow transaction emits NONE of these (acceptance cancels the short\n // watchdog), so the latch is never released while a live worker owns the staged artifact\n // — which recovery additionally claims by rename at acceptance.\n if (\n this.versionChangeInstallStarted &&\n !this.versionChangeConverged &&\n otaStatus?.status === \"failed\" &&\n (otaStatus.error === \"downgrade_handoff_refused\" ||\n otaStatus.error === \"downgrade_handoff_failed\" ||\n otaStatus.error === \"downgrade_transaction_stalled\")\n ) {\n console.log(\n `[OTA_PROGRESS] version-change: no transaction owns the detour (${otaStatus.error}) — releasing latch`,\n )\n this.versionChangeInstallStarted = false\n this.emitInternalChange()\n }\n\n // Version-change convergence: the reconnected glasses report exactly the pinned\n // target. This is the ONLY completion signal for a downgrade (lower build, no\n // increase, wiped session). Mirrors the legacy build-increase latch but by equality.\n if (\n this.versionChangeSession &&\n this.versionChangeInstallStarted &&\n !this.versionChangeConverged &&\n this.versionChangeTarget !== null &&\n buildNumberChanged &&\n buildNumber\n ) {\n const currentBuild = Number.parseInt(buildNumber, 10)\n if (Number.isFinite(currentBuild) && currentBuild === this.versionChangeTarget) {\n console.log(`[OTA_PROGRESS] version-change converged: glasses report target ${currentBuild}, completing`)\n this.clearPerStepTimers()\n this.clearGlobalTimeout()\n this.apkStepSeen = true\n this.setErrorMsg(\"\")\n this.versionChangeConverged = true\n this.emitInternalChange()\n }\n }\n\n // Legacy APK completion by build-number increase (WP 8C-c): old builds reboot into\n // the new build without a reliable explicit reconnect status; the fresh version_info\n // build number is the completion signal (ported from progress-legacy.tsx, which\n // completed from installing-with-apk and from starting/failed).\n if (\n buildNumberChanged &&\n !this.apkCompletedViaBuildIncrease &&\n this.apkExpectedInSession &&\n legacySession &&\n this.initialBuildNumber\n ) {\n const currentBuild = Number.parseInt(buildNumber, 10)\n const initialBuild = Number.parseInt(this.initialBuildNumber, 10)\n const increased = Number.isFinite(currentBuild) && Number.isFinite(initialBuild) && currentBuild > initialBuild\n const apkStepCurrent = otaStatus?.stepType === \"apk\" || otaProgress?.currentUpdate === \"apk\"\n const detectable =\n displayState === \"starting\" || displayState === \"failed\" || (displayState === \"updating\" && apkStepCurrent)\n if (increased && detectable) {\n console.log(\n `[OTA_PROGRESS] legacy apk complete via build-number increase (${initialBuild} -> ${currentBuild}), completing session`,\n )\n this.clearPerStepTimers()\n this.clearLegacyApkSettleTimer()\n this.setLegacyApkSettleHold(false)\n this.apkStepSeen = true\n this.setErrorMsg(\"\")\n this.setApkCompletedViaBuildIncrease(true)\n }\n }\n\n // Cancel the query-reply fallback as soon as the glasses reply with a useful\n // status (in_progress / step_complete / complete / failed) or any progress\n // event. An \"idle\" ota_status means glasses have no active session, so we\n // must keep the fallback armed and let it retry ota_start.\n if (otaStatusChanged || otaProgressChanged) {\n if (this.queryReplyTimeout && hasRecoveringOtaReply(otaStatus, otaProgress)) {\n this.clearQueryReplyTimeout()\n }\n }\n\n /**\n * Connect-edge — the only place that decides to send ota_start /\n * ota_query_status and flips sawReconnectEdge\n * on the false -> true transition that signals the BES reboot completed.\n */\n if (connectedChanged) {\n this.runConnectEdge(connected)\n }\n\n if (displayStateChanged && isTerminalForWatchdog(displayState)) {\n this.clearGlobalTimeout()\n }\n\n if (isMount) {\n GlobalEventEmitter.on(\"ota_start_ack\", this.handleAck)\n GlobalEventEmitter.on(\"mtk_update_complete\", this.handleMtkComplete)\n GlobalEventEmitter.on(\"glasses_session_changed\", this.handleGlassesSessionChanged)\n }\n\n // Ping keepalive while an OTA is actively running (legacy sessions pinged on the\n // padded interval — old builds slept less eagerly and pings are costlier for them).\n if (connectedChanged || displayStateChanged) {\n this.clearPingInterval()\n const active =\n connected && (displayState === \"starting\" || displayState === \"updating\") && !this.isInVersionChangeDetour()\n if (active) {\n void BluetoothSdk.ping().catch(() => {})\n const pingIntervalMs = legacySession ? LEGACY_PING_INTERVAL_MS : PING_INTERVAL_MS\n this.pingInterval = setInterval(() => {\n void BluetoothSdk.ping().catch(() => {})\n this.maybePollApkInstallStatus()\n }, pingIntervalMs)\n }\n }\n\n // Any glasses activity proves the logical ota_start was accepted.\n if ((otaStatusChanged || otaProgressChanged) && (otaStatus || otaProgress)) {\n this.onFirstActivity()\n }\n\n // The stuck-at-zero watchdog clears only on the FIRST real (>0%) progress.\n // Without this distinction, an ota_status reply with stepPercent=0 would\n // disable the watchdog before any download had actually started, hiding\n // wedged downloads from the user.\n if (otaStatusChanged || otaProgressChanged) {\n const stepPct = otaStatus?.stepPercent ?? 0\n const overallPct = otaStatus?.overallPercent ?? 0\n const legacyPct = otaProgress?.progress ?? 0\n if (stepPct > 0 || overallPct > 0 || legacyPct > 0) {\n this.onFirstNonZeroProgress()\n }\n }\n\n // Progress stall watchdog — fails the update if glasses go silent mid-step.\n // Keyed on the staleness SIGNATURE string (not the object refs) so a store\n // update that doesn't change the signature keeps the same timer running\n // instead of forever re-extending the deadline.\n if (stallSigChanged || displayStateChanged) {\n if (this.isInVersionChangeDetour()) {\n // Recovery worker owns the transaction; there are no progress events to stall on.\n this.clearProgressTimeout()\n } else if (displayState !== \"starting\" && displayState !== \"updating\") {\n this.clearProgressTimeout()\n } else if (!stallSig) {\n this.clearProgressTimeout()\n } else {\n const duration = stallDuration\n this.clearProgressTimeout()\n this.progressTimeout = setTimeout(() => {\n this.progressTimeout = null\n if (isTerminalForWatchdog(this.computeDisplayStateNow())) return\n console.log(`[OTA_PROGRESS] watchdog: progress stalled for ${duration}ms, failing`)\n this.setErrorMsg(OtaProgressMessages.stalledOrStuck)\n }, duration)\n }\n }\n\n // Lockout on Continue button after BES restart to prevent accidental tap\n // (15s unified, 35s for legacy-shaped sessions — WP 8C-f).\n if (displayStateChanged && displayState === \"restarting\") {\n this.clearContinueLockoutTimer()\n const lockoutMs = legacySession ? LEGACY_BES_CONTINUE_LOCKOUT_MS : BES_CONTINUE_LOCKOUT_MS\n this.setContinueButtonDisabled(true)\n this.continueLockoutTimer = setTimeout(() => {\n this.continueLockoutTimer = null\n this.setContinueButtonDisabled(false)\n }, lockoutMs)\n }\n\n // Legacy MTK install stall simulation (WP 8C-e): display-only. The simulation\n // timers only ever touch the projected snapshot percent — they never feed back\n // into arbitration (no reaction pass, no watchdog resets).\n if (otaProgressChanged) {\n this.runMtkStallSimulationPass(otaProgress, legacySession)\n }\n\n // Clear the selected update once this session reaches any terminal UI state.\n // Catches paths the MantleManager ota_status listener misses — notably BES success\n // (which terminates as `step_complete`, not `complete`) and APK build-number fallback\n // completions (which never produce a `complete` ota_status).\n if (\n displayStateChanged &&\n (displayState === \"complete\" || displayState === \"restarting\" || displayState === \"failed\")\n ) {\n if (displayState === \"failed\") {\n this.clearPerStepTimers()\n }\n useGlassesStore.getState().setOtaUpdateAvailable(null)\n if (displayState === \"complete\" || displayState === \"failed\") {\n void this.teardownHotspotTransport()\n }\n }\n }\n\n /**\n * Reconnect arbitration shared by the physical BLE connect edge and the\n * glasses_session_changed signal. The latter exists because the BES keeps the BLE\n * link alive across asg_client restarts (APK OTA): no physical edge ever fires, so\n * the changed process session id is the only reconnect signal the coordinator gets\n * (incident rep_01KY6BJ0B7A4RBMQ7VN39KAE5E). Always returns true (the caller's\n * edge handling is complete).\n */\n private runReconnectArbitration(label: string): boolean {\n console.log(`[OTA_PROGRESS] ${label}: false->true, flipping sawReconnectEdge=true`)\n // A physical reconnect passed through the disconnect branch first, which cleared\n // these timers; a session-change edge never disconnects, so a fallback armed by an\n // earlier mount/query could otherwise fire alongside the arbitration below and send\n // a duplicate ota_start. Clearing here is a no-op on the physical path.\n this.clearQueryReplyTimeout()\n this.setSawReconnectEdge(true)\n\n if (this.besRestartDisconnectObserved) {\n console.log(`[OTA_PROGRESS] ${label}: BES reboot reconnect observed — no ota_query_status`)\n this.completeBesRestartRecovery()\n return true\n }\n\n // Legacy apk settle window (WP 8C): the glasses restarting into the new build is\n // the EXPECTED reconnect here — the legacy screen took no action on it. Skip the\n // query/fallback; the settle timer (or the build-number increase) completes.\n if (this.legacyApkSettleHold) {\n console.log(`[OTA_PROGRESS] ${label}: reconnect during legacy apk settle hold — no query`)\n return true\n }\n\n console.log(`[OTA_PROGRESS] ${label}: reconnected, sending ota_query_status`)\n if (this.otaStartOwnership?.outcome === \"pending\") {\n void this.sendOtaStartWithWatchdogs()\n }\n void BluetoothSdk.queryOtaStatus().catch(() => {})\n this.armQueryReplyFallback(\"reconnect\")\n return true\n }\n\n private runConnectEdge(connected: boolean): void {\n const prev = this.prevConnected\n this.prevConnected = connected\n\n if (!connected) {\n console.log(\"[OTA_PROGRESS] connect-edge: disconnected\")\n // Also drop pending query/retry sends: firing ota_start into a dead link\n // can only produce a false \"failed\" state. Reconnect arbitration first\n // queries durable status and re-arms the one permitted fallback.\n this.clearQueryReplyTimeout()\n this.clearRetryTimeout()\n return\n }\n\n const becameConnected = prev === false && connected === true\n if (becameConnected && this.runReconnectArbitration(\"connect-edge\")) {\n return\n }\n\n // Version-change detour: after the install started, EVERY reconnect is expected\n // (the passive factory build, then the target). Do NOT send ota_start/query — the\n // factory build would treat the pin as a plain upgrade and start a redundant\n // download racing the recovery worker. Convergence (buildNumber === target) is\n // detected in the reaction pass; here we simply take no action.\n if (this.versionChangeSession && this.versionChangeInstallStarted && !this.versionChangeConverged) {\n console.log(\"[OTA_PROGRESS] connect-edge: reconnect during version-change detour — no query (expected)\")\n return\n }\n\n const storeState = useGlassesStore.getState()\n\n // Initial mount (prev === current === true). If no session yet, kick off ota_start.\n // An idle ota_status has an empty sessionId; treat it as no session so ota_start\n // still begins an explicit install.\n const isIdleStatus = !!storeState.otaStatus && storeState.otaStatus.sessionId === \"\"\n const noSessionYet = (!storeState.otaStatus && !storeState.otaProgress) || isIdleStatus\n if (noSessionYet) {\n if (!isIdleStatus && this.otaStartOwnership?.outcome === \"acknowledged\") {\n console.log(\"[OTA_PROGRESS] initial mount, acknowledged session has no cached status — reconciling\")\n void BluetoothSdk.queryOtaStatus().catch(() => {})\n this.armQueryReplyFallback(\"initial-mount\")\n return\n }\n console.log(\n isIdleStatus\n ? \"[OTA_PROGRESS] initial mount, idle status (no sessionId), sending ota_start\"\n : \"[OTA_PROGRESS] initial mount, no session in store, sending ota_start\",\n )\n this.retryCount = 0\n if (isIdleStatus && this.otaStartOwnership?.outcome !== \"pending\" && !this.prepareFreshOtaStartAttempt()) {\n return\n }\n void this.sendOtaStartWithWatchdogs()\n } else {\n console.log(\"[OTA_PROGRESS] initial mount, session exists, sending ota_query_status\")\n void BluetoothSdk.queryOtaStatus().catch(() => {})\n this.armQueryReplyFallback(\"initial-mount\")\n }\n }\n\n // --- BLE OTA event listeners (engine GlobalEventEmitter, fed by OtaService) ---\n\n private readonly handleAck = (): void => {\n const ownership = this.otaStartOwnership\n if (!ownership || ownership.outcome === \"rejected\") return\n if (ownership.outcome === \"acknowledged\") return\n console.log(\"[OTA_PROGRESS] ota_start_ack received\")\n ownership.outcome = \"acknowledged\"\n this.clearRetryTimeout()\n }\n\n /**\n * The asg process restarted while the BES kept the BLE link up (sid change observed\n * by the bridge): treat it exactly like a physical reconnect edge.\n */\n private readonly handleGlassesSessionChanged = (): void => {\n this.runReconnectArbitration(\"session-change\")\n }\n\n private readonly handleMtkComplete = (): void => {\n console.log(\"[OTA_PROGRESS] mtk_update_complete received\")\n this.clearProgressTimeout()\n this.onFirstActivity()\n this.onFirstNonZeroProgress()\n void BluetoothSdk.queryOtaStatus().catch(() => {})\n useGlassesStore.getState().setMtkUpdatedThisSession(true)\n }\n\n // --- legacy (< 37) compatibility, ported from progress-legacy.tsx (WP 8C) ---\n\n /**\n * Reacts to a NEW legacy-shaped install-phase \"complete\" (an old build's\n * `install FINISHED`). Two ports from the legacy screen:\n * - last-write-wins: completion arriving after a watchdog failure overrides it\n * (the old screen completed from \"failed\" too);\n * - apk settle window: an apk install FINISHED observed in flight is held out of\n * \"complete\" for LEGACY_APK_COMPLETION_SETTLE_MS so the ASG process restart\n * settles (and fresh version_info lands) before the user can continue. From\n * starting/failed (post-reboot explicit signal) completion is immediate.\n */\n private handleLegacyInstallCompleteEdge(otaStatus: OtaStatus | null): void {\n if (!isLegacyShapedOtaStatus(otaStatus) || otaStatus?.phase !== \"install\" || otaStatus.status !== \"complete\") {\n return\n }\n\n if (this.errorMsg) {\n console.log(\n \"[OTA_PROGRESS] legacy install complete arrived after a failure — completing (legacy last-write-wins)\",\n )\n this.setErrorMsg(\"\")\n this.clearLegacyApkSettleTimer()\n this.setLegacyApkSettleHold(false)\n return\n }\n\n if (\n otaStatus.stepType === \"apk\" &&\n !this.apkCompletedViaBuildIncrease &&\n !this.legacyApkSettleHold &&\n this.legacyApkSettleTimer === null &&\n this.lastDisplayState === \"updating\"\n ) {\n console.log(\n `[OTA_PROGRESS] legacy apk install complete — holding complete for ${LEGACY_APK_COMPLETION_SETTLE_MS}ms settle window`,\n )\n this.setLegacyApkSettleHold(true)\n this.legacyApkSettleTimer = setTimeout(() => {\n this.legacyApkSettleTimer = null\n console.log(\"[OTA_PROGRESS] legacy apk settle window elapsed — releasing complete\")\n this.setLegacyApkSettleHold(false)\n }, LEGACY_APK_COMPLETION_SETTLE_MS)\n }\n }\n\n private isBesRestartExpected(\n otaStatus: OtaStatus | null,\n otaProgress: OtaProgress | null,\n legacySession: boolean,\n ): boolean {\n const statusReadyToRestart =\n otaStatus?.stepType === \"bes\" &&\n otaStatus.phase === \"install\" &&\n (otaStatus.status === \"step_complete\" || otaStatus.status === \"complete\")\n const progressReadyToRestart =\n legacySession &&\n otaProgress?.currentUpdate === \"bes\" &&\n otaProgress.stage === \"install\" &&\n otaProgress.status === \"FINISHED\"\n\n // progress-legacy treated a BES disconnect during active installation as the\n // expected power cycle even when its terminal FINISHED event was lost. Keep\n // that fallback only for the sticky pre-37 profile selected when the flow began.\n const legacyInstallInProgress =\n legacySession &&\n ((otaStatus?.stepType === \"bes\" && otaStatus.phase === \"install\" && otaStatus.status === \"in_progress\") ||\n (otaProgress?.currentUpdate === \"bes\" &&\n otaProgress.stage === \"install\" &&\n (otaProgress.status === \"STARTED\" || otaProgress.status === \"PROGRESS\")))\n return statusReadyToRestart || progressReadyToRestart || legacyInstallInProgress\n }\n\n /** Complete only after a protocol-authorized BES restart traverses disconnect -> reconnect. */\n private completeBesRestartRecovery(): void {\n if (!this.besRestartDisconnectObserved || this.besRestartRecovery !== \"awaiting\") return\n console.log(\"[OTA_PROGRESS] BES restart reconnected — completing by reboot edge\")\n this.clearPerStepTimers()\n this.setErrorMsg(\"\")\n this.besRestartRecovery = \"complete\"\n this.emitInternalChange()\n }\n\n /**\n * Legacy MTK install stall simulation (WP 8C-e), ported verbatim: the MTK system\n * install typically stalls around 49-50%. Every real event restarts stall detection;\n * after LEGACY_MTK_STALL_DETECT_MS of silence inside the [45, 55) zone, simulate +1%\n * every LEGACY_MTK_SIM_TICK_MS from max(stall+1, 51), capped at 60. Real progress\n * beyond the simulated value clears it. Display-only by construction: the timers call\n * only {@link setMtkSimulatedPercent}, which never queues a reaction pass.\n */\n private runMtkStallSimulationPass(otaProgress: OtaProgress | null, legacySession: boolean): void {\n const isLegacyMtkInstall =\n legacySession &&\n otaProgress?.currentUpdate === \"mtk\" &&\n otaProgress.stage === \"install\" &&\n (otaProgress.status === \"STARTED\" || otaProgress.status === \"PROGRESS\")\n\n if (!isLegacyMtkInstall) {\n this.clearMtkSimulationTimers()\n this.setMtkSimulatedPercent(null)\n return\n }\n\n const realProgress = otaProgress.progress ?? 0\n if (realProgress > 0 && realProgress !== this.lastRealMtkProgress) {\n this.lastRealMtkProgress = realProgress\n if (this.mtkSimulatedPercent !== null && realProgress > this.mtkSimulatedPercent) {\n this.setMtkSimulatedPercent(null)\n }\n }\n\n // A real event arrived: restart stall detection (and stop any running ticker).\n this.clearMtkSimulationTimers()\n const inStallZone =\n realProgress >= LEGACY_MTK_STALL_ZONE_MIN_PERCENT && realProgress < LEGACY_MTK_STALL_ZONE_MAX_PERCENT\n if (!inStallZone) return\n\n this.mtkStallDetectTimer = setTimeout(() => {\n this.mtkStallDetectTimer = null\n const stalledAt = this.lastRealMtkProgress\n const prev = this.mtkSimulatedPercent\n const target = Math.max(\n prev !== null ? Math.max(prev, stalledAt + 1) : stalledAt + 1,\n LEGACY_MTK_SIM_FLOOR_PERCENT,\n )\n console.log(\n `[OTA_PROGRESS] legacy mtk install stalled at ${stalledAt}%, simulating display progress from ${target}%`,\n )\n this.setMtkSimulatedPercent(target)\n this.mtkSimTickTimer = setInterval(() => {\n const current = this.mtkSimulatedPercent ?? stalledAt + 1\n const capped = Math.min(current + 1, LEGACY_MTK_SIM_CAP_PERCENT)\n this.setMtkSimulatedPercent(capped)\n if (capped >= LEGACY_MTK_SIM_CAP_PERCENT && this.mtkSimTickTimer) {\n clearInterval(this.mtkSimTickTimer)\n this.mtkSimTickTimer = null\n }\n }, LEGACY_MTK_SIM_TICK_MS)\n }, LEGACY_MTK_STALL_DETECT_MS)\n }\n\n // --- watchdogs / send path ---\n\n /**\n * Read the current derived display state from the store + internal state\n * synchronously — used inside setTimeout callbacks.\n */\n private computeDisplayStateNow(): DisplayState {\n const state = useGlassesStore.getState()\n return deriveDisplayState({\n otaStatus: state.otaStatus,\n otaProgress: state.otaProgress,\n connected: isGlassesConnected(state.connection),\n errorMsg: this.errorMsg,\n sawReconnectEdge: this.sawReconnectEdge,\n legacyApkSettleHold: this.legacyApkSettleHold,\n apkCompletedViaBuildIncrease: this.apkCompletedViaBuildIncrease,\n besRestartRecovery: this.besRestartRecovery,\n versionChangeConverged: this.versionChangeConverged,\n versionChangeSession: this.versionChangeSession,\n })\n }\n\n /**\n * During an APK install the package installer kills and restarts the glasses\n * process, and the new process's completion push can lose its startup race\n * against the UART transport (incident rep_01KY31HEMTSBSMK8DVMNXJ5XGG: the\n * phone sat on a stale \"install in_progress 0%\" until the stall watchdog\n * failed a successful update). The persisted session on the glasses always\n * knows the truth, so poll ota_query_status on the keepalive tick while an\n * apk step sits in its install phase — the reply either confirms progress or\n * delivers the missed completion. Gated to the apk install phase so a stray\n * idle reply can't disturb an active download; legacy (< 37) builds ignore\n * the query, which is harmless.\n *\n * The native query pends up to 15s and rejects a concurrent call with\n * request_in_flight — longer than the 10s tick — so exactly one poll is kept\n * in flight (the glasses being slow to answer IS the silent-restart window\n * this poll exists for) and rejections are swallowed: the next tick retries.\n */\n private maybePollApkInstallStatus(): void {\n if (this.isInVersionChangeDetour()) return\n if (this.apkInstallPollInFlight) return\n const s = useGlassesStore.getState().otaStatus\n if (s?.stepType === \"apk\" && s.phase === \"install\" && s.status === \"in_progress\") {\n this.apkInstallPollInFlight = true\n void BluetoothSdk.queryOtaStatus()\n .catch(() => {})\n .finally(() => {\n this.apkInstallPollInFlight = false\n })\n }\n }\n\n /**\n * \"Glasses are talking to us\" — suppresses retry if the native request later rejects.\n * Important: this does NOT clear the stuck-at-zero watchdog; that one fires\n * on real progress > 0% (see {@link onFirstNonZeroProgress}).\n */\n private onFirstActivity(): void {\n if (this.hasFirstActivity) return\n this.hasFirstActivity = true\n if (this.otaStartOwnership?.outcome === \"pending\") {\n this.otaStartOwnership.outcome = \"acknowledged\"\n }\n this.clearRetryTimeout()\n }\n\n /**\n * \"Real download progress arrived\" — clears the stuck-at-zero watchdog. We\n * deliberately wait for non-zero progress before clearing this so that an\n * ota_status reply with stepPercent: 0 (which is \"first activity\" but not\n * \"real progress\") doesn't disable the only watchdog that catches a wedged\n * download.\n */\n private onFirstNonZeroProgress(): void {\n if (this.hasFirstNonZeroProgress) return\n this.hasFirstNonZeroProgress = true\n this.clearStuckTimeout()\n }\n\n private maybeStartGlobalTimeout(): void {\n if (this.globalTimeoutStarted) return\n this.globalTimeoutStarted = true\n // Legacy-shape check happens once, when the session cap is armed at the first\n // ota_start send (WP 8C-b): old builds get the padded legacy cap for the whole\n // session; a session that starts unified keeps the unified cap.\n const globalTimeoutMs =\n this.versionChangeSession || this.isLegacySessionShapeNow() ? LEGACY_GLOBAL_OTA_TIMEOUT_MS : GLOBAL_OTA_TIMEOUT_MS\n this.globalTimeout = setTimeout(() => {\n this.globalTimeout = null\n this.globalTimeoutStarted = false\n if (isTerminalForWatchdog(this.computeDisplayStateNow())) return\n console.log(\"[OTA_PROGRESS] watchdog: global timeout fired, failing session\")\n this.clearPerStepTimers()\n // Legacy parity: the old screen's global-timeout handler also killed the apk\n // completion timer and the MTK stall simulation (the flags/percent stay put —\n // errorMsg outranks them in the projection, and retry()/last-write-wins reset them).\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n this.setErrorMsg(OtaProgressMessages.globalTimeout)\n }, globalTimeoutMs)\n }\n\n private armStuckWatchdogOnly(): void {\n this.clearStuckTimeout()\n\n // Durations resolved at arm time (WP 8C-b): legacy-shaped sessions get the\n // padded values progress-legacy.tsx used for old (< 37) builds.\n const legacySession = this.isLegacySessionShapeNow()\n const stuckTimeoutMs = legacySession ? LEGACY_DOWNLOAD_STUCK_TIMEOUT_MS : DOWNLOAD_STUCK_TIMEOUT_MS\n\n this.stuckTimeout = setTimeout(() => {\n this.stuckTimeout = null\n const d = this.computeDisplayStateNow()\n const state = useGlassesStore.getState()\n if (d !== \"starting\" && !(d === \"updating\" && state.otaStatus?.phase === \"download\")) {\n return\n }\n const pct = latestPercentForStuck(state.otaStatus, state.otaProgress)\n if (pct !== 0) return\n console.log(`[OTA_PROGRESS] watchdog: stuck at 0% for ${stuckTimeoutMs}ms, failing`)\n this.clearRetryTimeout()\n this.setErrorMsg(OtaProgressMessages.stalledOrStuck)\n }, stuckTimeoutMs)\n }\n\n /** Arm the 0%-stuck watchdog only when this logical session has none. */\n private maybeArmStuckWatchdog(): void {\n if (this.stuckTimeout || this.hasFirstNonZeroProgress) return\n this.armStuckWatchdogOnly()\n }\n\n private sendOtaStartWithWatchdogs(): Promise<void> {\n // INVARIANT BACKSTOP — not normal control flow. Every entry point that can drive the\n // glasses (connect-edge, query fallback, retry, mount) carries its own detour gate with the\n // right behavior for that site; this final check only exists so that a FUTURE entry point\n // that forgets its gate degrades to a refused send + loud log instead of a corrupted\n // transaction (an ota_start mid-detour starts a parallel install on the factory build and\n // can trigger a second handoff). If this ever fires, a missed site gate exists — fix it.\n if (this.isInVersionChangeDetour()) {\n console.error(\n \"[OTA_PROGRESS] BACKSTOP: refused ota_start during a latched version-change detour — a caller is missing its detour gate\",\n )\n return Promise.resolve()\n }\n const existingOwnership = this.otaStartOwnership\n if (existingOwnership?.outcome === \"pending\") {\n this.maybeStartGlobalTimeout()\n if (this.selectedTransport === \"wifi\" || this.hotspotManifestUrl) this.maybeArmStuckWatchdog()\n console.log(\"[OTA_PROGRESS] ota_start already pending — adopting existing native request\")\n return existingOwnership.promise\n }\n if (existingOwnership?.outcome === \"acknowledged\") {\n this.maybeStartGlobalTimeout()\n this.maybeArmStuckWatchdog()\n console.log(\"[OTA_PROGRESS] ota_start already acknowledged — refusing duplicate start\")\n return Promise.resolve()\n }\n if (existingOwnership?.outcome === \"rejected\" && !this.prepareFreshOtaStartAttempt()) {\n return Promise.resolve()\n }\n this.maybeStartGlobalTimeout()\n if (this.selectedTransport === \"wifi\" || this.hotspotManifestUrl) this.maybeArmStuckWatchdog()\n\n const ownership: OtaStartOwnership = {\n outcome: \"pending\",\n promise: Promise.resolve(),\n }\n ownership.promise = this.performOtaStart(ownership)\n this.otaStartOwnership = ownership\n return ownership.promise\n }\n\n private async performOtaStart(ownership: OtaStartOwnership): Promise<void> {\n let nativeStartAttempted = false\n try {\n const state = useGlassesStore.getState()\n let otaVersionUrl = resolveOtaManifestUrl(state.otaVersionUrl, state.buildNumber)\n if (this.selectedTransport === \"hotspot\") {\n if (!this.hotspotManifestUrl) {\n if (!this.preparedCheckResult) {\n throw new Error(\"No selected OTA check is available for hotspot staging\")\n }\n this.hotspotManifestUrl = await hotspotOtaTransport.prepare(this.preparedCheckResult, (progress) => {\n this.hotspotPhase = progress.phase\n this.hotspotArtifactPercent = progress.artifact?.artifactPercent ?? null\n this.emitInternalChange()\n })\n }\n otaVersionUrl = this.hotspotManifestUrl\n this.maybeArmStuckWatchdog()\n }\n if (!otaVersionUrl) {\n throw new Error(\"OTA is disabled because this build has no immutable manifest pin\")\n }\n console.log(`[OTA_PROGRESS] sending ota_start with ${this.selectedTransport} manifest URL: ${otaVersionUrl}`)\n nativeStartAttempted = true\n await BluetoothSdk.startOtaUpdate(otaVersionUrl)\n if (this.otaStartOwnership !== ownership) return\n // The public SDK promise resolves only from ota_start_ack. Treat that\n // resolution as the acknowledgement even if the parallel event dispatch\n // reaches the coordinator later (or is dropped by a remount).\n this.handleAck()\n } catch (err) {\n console.warn(\"[OTA_PROGRESS] sendOtaStart threw\", err)\n\n if (this.otaStartOwnership !== ownership) return\n\n if (this.selectedTransport === \"hotspot\" && !nativeStartAttempted) {\n ownership.outcome = \"rejected\"\n this.clearStuckTimeout()\n await this.teardownHotspotTransport()\n if (this.attached) this.setErrorMsg(hotspotPreflightErrorMessage(err))\n return\n }\n\n // A received ota_status/legacy progress event, or the exact legacy APK\n // build-number proof, proves that this logical start was accepted. Its\n // application-level ack may be lost while the update continues; never\n // create another transaction or fail a live, restarting, or completed\n // session because that stale promise timed out.\n if (this.hasFirstActivity || this.apkCompletedViaBuildIncrease) {\n ownership.outcome = \"acknowledged\"\n console.log(\"[OTA_PROGRESS] ota_start rejection arrived after acceptance proof — ignoring stale rejection\")\n return\n }\n\n ownership.outcome = \"rejected\"\n if (!this.attached) return\n this.clearStuckTimeout()\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\n \"[OTA_PROGRESS] ota_start request ended while disconnected; deferring retry to reconnect arbitration\",\n )\n return\n }\n if (this.retryCount < MAX_RETRIES - 1) {\n this.retryCount += 1\n const retryIntervalMs = this.isLegacySessionShapeNow() ? LEGACY_RETRY_INTERVAL_MS : RETRY_INTERVAL_MS\n console.log(\n `[OTA_PROGRESS] ota_start request ended without ack or activity; retrying after ${retryIntervalMs}ms (attempt ${\n this.retryCount + 1\n }/${MAX_RETRIES})`,\n )\n this.retryTimeout = setTimeout(() => {\n this.retryTimeout = null\n if (!isGlassesConnected(useGlassesStore.getState().connection)) {\n console.log(\"[OTA_PROGRESS] ota_start retry paused while disconnected; reconnect arbitration will resume\")\n return\n }\n void this.sendOtaStartWithWatchdogs()\n }, retryIntervalMs)\n } else {\n console.log(\"[OTA_PROGRESS] sendOtaStart failed after max retries, failing session\")\n this.setErrorMsg(OtaProgressMessages.sendOtaStartFailed)\n }\n }\n }\n\n private async teardownHotspotTransport(): Promise<void> {\n if (this.selectedTransport !== \"hotspot\" && !this.hotspotManifestUrl) return\n await hotspotOtaTransport.teardown()\n this.hotspotManifestUrl = null\n this.hotspotPhase = \"idle\"\n this.hotspotArtifactPercent = null\n this.emitInternalChange()\n }\n\n /**\n * After sending ota_query_status, wait QUERY_REPLY_TIMEOUT_MS for the glasses\n * to reply with a useful ota_status. A unified session may start again only\n * after an explicit \"idle\" reply, or after a locally rejected ota_start has\n * produced no activity and no authoritative reply across reconnect. Legacy\n * builds ignore ota_query_status, so their established timeout fallback\n * remains the compatibility path.\n *\n * Cleared as soon as a non-idle otaStatus or any otaProgress lands in the\n * store (see the reaction block above). An idle reply intentionally does NOT\n * cancel the fallback, so reconnects against a wiped/lost session still recover.\n */\n private armQueryReplyFallback(reason: \"reconnect\" | \"initial-mount\" | \"retry\"): void {\n this.clearQueryReplyTimeout()\n this.queryReplyTimeout = setTimeout(() => {\n this.queryReplyTimeout = null\n const state = useGlassesStore.getState()\n // If we already got a useful reply, we'd have been cleared. Defensive\n // re-check: idle replies must not block the retry. Legacy-shaped state is\n // exempt (WP 8C-b): old (< 37) builds ignore ota_query_status entirely, so\n // whatever legacy-shaped status/progress sits in the store is a pre-query\n // leftover, not a reply — a NEW legacy event would have cleared this timer\n // through the reaction pass. Only a unified reply suppresses the fallback.\n const legacySession = this.isLegacySessionShapeNow()\n if (!legacySession && hasRecoveringOtaReply(state.otaStatus, state.otaProgress)) return\n const explicitIdle = state.otaStatus?.status === \"idle\"\n const rejectedStart = this.otaStartOwnership?.outcome === \"rejected\"\n if (!legacySession && !explicitIdle && !rejectedStart) {\n console.log(\n `[OTA_PROGRESS] watchdog: ota_query_status got no authoritative idle reply in ${QUERY_REPLY_TIMEOUT_MS}ms (reason=${reason}); preserving the existing session`,\n )\n return\n }\n // Don't fire if we've left the active phase (e.g. user backed out, error overlay).\n if (isTerminalForWatchdog(this.computeDisplayStateNow())) return\n let fallbackCause = \"legacy query timeout\"\n if (explicitIdle) fallbackCause = \"idle ota_status\"\n else if (rejectedStart) fallbackCause = \"rejected ota_start with no recovery reply\"\n console.log(`[OTA_PROGRESS] watchdog: ${fallbackCause} (reason=${reason}), falling back to ota_start`)\n this.retryCount = 0\n if (this.otaStartOwnership?.outcome !== \"pending\" && !this.prepareFreshOtaStartAttempt()) return\n void this.sendOtaStartWithWatchdogs()\n }, QUERY_REPLY_TIMEOUT_MS)\n }\n\n // --- timer cleanup helpers ---\n\n private clearProgressTimeout(): void {\n if (this.progressTimeout) {\n clearTimeout(this.progressTimeout)\n this.progressTimeout = null\n }\n }\n\n private clearRetryTimeout(): void {\n if (this.retryTimeout) {\n clearTimeout(this.retryTimeout)\n this.retryTimeout = null\n }\n }\n\n private clearStuckTimeout(): void {\n if (this.stuckTimeout) {\n clearTimeout(this.stuckTimeout)\n this.stuckTimeout = null\n }\n }\n\n private clearGlobalTimeout(): void {\n if (this.globalTimeout) {\n clearTimeout(this.globalTimeout)\n this.globalTimeout = null\n }\n this.globalTimeoutStarted = false\n }\n\n private clearPingInterval(): void {\n if (this.pingInterval) {\n clearInterval(this.pingInterval)\n this.pingInterval = null\n }\n }\n\n private clearQueryReplyTimeout(): void {\n if (this.queryReplyTimeout) {\n clearTimeout(this.queryReplyTimeout)\n this.queryReplyTimeout = null\n }\n }\n\n private clearContinueLockoutTimer(): void {\n if (this.continueLockoutTimer) {\n clearTimeout(this.continueLockoutTimer)\n this.continueLockoutTimer = null\n }\n }\n\n private clearLegacyApkSettleTimer(): void {\n if (this.legacyApkSettleTimer) {\n clearTimeout(this.legacyApkSettleTimer)\n this.legacyApkSettleTimer = null\n }\n }\n\n private clearMtkSimulationTimers(): void {\n if (this.mtkStallDetectTimer) {\n clearTimeout(this.mtkStallDetectTimer)\n this.mtkStallDetectTimer = null\n }\n if (this.mtkSimTickTimer) {\n clearInterval(this.mtkSimTickTimer)\n this.mtkSimTickTimer = null\n }\n }\n\n /**\n * NOTE (WP 8C): the legacy apk settle timer and the MTK stall simulation timers are\n * deliberately NOT per-step watchdogs — a per-step failure must not kill them (the\n * legacy screen kept the simulation ticking through a watchdog failure, and the\n * settle latch resolves completion, not liveness). They are cleared on detach,\n * retry(), global timeout, and their own supersession paths.\n */\n private clearPerStepTimers(): void {\n this.clearRetryTimeout()\n this.clearStuckTimeout()\n this.clearProgressTimeout()\n this.clearQueryReplyTimeout()\n }\n\n private clearAllOtaTimers(): void {\n this.clearPerStepTimers()\n this.clearGlobalTimeout()\n this.clearPingInterval()\n this.clearLegacyApkSettleTimer()\n this.clearMtkSimulationTimers()\n }\n}\n\n/** Singleton — one install session machine per app process (matches the single progress screen). */\nexport const otaInstallCoordinator = new OtaInstallCoordinator()\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OtaService.d.ts","sourceRoot":"","sources":["../../src/services/OtaService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OtaService.d.ts","sourceRoot":"","sources":["../../src/services/OtaService.ts"],"names":[],"mappings":"AAoBA,wBAAgB,eAAe,IAAI,IAAI,CA8DtC;AAED,wBAAgB,cAAc,IAAI,IAAI,CAGrC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Started by `engine.start()`. Idempotent.
|
|
12
12
|
*/
|
|
13
|
-
import BluetoothSdk from "@mentra/bluetooth-sdk
|
|
13
|
+
import BluetoothSdk from "@mentra/bluetooth-sdk";
|
|
14
14
|
import GlobalEventEmitter from "../utils/GlobalEventEmitter";
|
|
15
15
|
import { useGlassesStore } from "../stores/glasses";
|
|
16
16
|
import { handleOtaClockSkewFromGlasses } from "./glassesClockSync";
|