@mentra/engine 3.2.1-dev.293 → 3.2.1-dev.294
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/build/generated/releaseMetadata.js +5 -5
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/services/AcsMeetingService.d.ts +2 -2
- package/build/services/AcsMeetingService.d.ts.map +1 -1
- package/build/services/AcsMeetingService.js +25 -7
- package/build/services/AcsMeetingService.js.map +1 -1
- package/build/services/LocalMiniappRuntime.js +1 -1
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/ManagedWebRtcRelay.d.ts +2 -0
- package/build/services/ManagedWebRtcRelay.d.ts.map +1 -1
- package/build/services/ManagedWebRtcRelay.js +30 -13
- package/build/services/ManagedWebRtcRelay.js.map +1 -1
- package/build/services/SoftapCallTransport.d.ts +1 -1
- package/build/services/SoftapCallTransport.d.ts.map +1 -1
- package/build/services/SoftapCallTransport.js +2 -2
- package/build/services/SoftapCallTransport.js.map +1 -1
- package/package.json +8 -8
- package/src/generated/releaseMetadata.ts +5 -5
- package/src/services/AcsMeetingService.ts +31 -6
- package/src/services/LocalMiniappRuntime.ts +2 -2
- package/src/services/ManagedWebRtcRelay.ts +29 -13
- package/src/services/SoftapCallTransport.ts +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AcsMeetingService.js","sourceRoot":"","sources":["../../src/services/AcsMeetingService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-side ACS meeting controller. One active meeting. Native module owns\n * WHEP + ACS; this service maps that into miniapp envelopes and pipes\n * incoming PCM into AudioPlaybackService (A2DP / PcmStreamPlayer).\n */\n\nimport {Platform} from \"react-native\"\n\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\n\nimport audioPlaybackService from \"./AudioPlaybackService\"\nimport {getCallGainSweep} from \"./CallGainSweep\"\nimport micStateCoordinator from \"./MicStateCoordinator\"\nimport micSessionManager, {type MicSession} from \"./MicSessionManager\"\nimport {ENGINE_OWNER_PREFIX} from \"./micPolicy\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\nimport {Pcm16LevelMeter, pcm16WindowStats} from \"../utils/pcm16\"\nimport {pcmToBase64} from \"../utils/pcmToBase64\"\nimport {softapTrace, softapTraceFailure, softapTraceId} from \"../utils/softapTrace\"\nimport {ACS_CALL_MIC, type AcsAudioSource, type ResolvedAudioSource, type SourceReason} from \"./acsAudioSource\"\nimport type {SoftapProgress} from \"./SoftapCallTransport\"\n\nexport {ACS_CALL_MIC}\nexport {pcmToBase64}\nexport type {ResolvedAudioSource, SourceReason}\n\ntype MeetingPhase = \"idle\" | \"connecting\" | \"lobby\" | \"connected\" | \"disconnected\" | \"error\"\n\nexport type AudioSafety = \"safe\" | \"degraded\" | \"unsafe\"\nexport type ActiveStream = \"none\" | \"virtual\" | \"local\"\n/**\n * Health of the glasses WHEP subscription that feeds the call. `failed` means ICE\n * dropped or the WHEP endpoint went away (glasses stopped publishing, phone changed\n * networks); the ACS call itself may still be `connected` with a frozen last frame.\n */\nexport type MediaSourceState = \"idle\" | \"connecting\" | \"live\" | \"failed\"\n\n/**\n * How the wearer's voice is reaching ACS.\n *\n * `ble-lc3` is the glasses microphone over Bluetooth, decoded on the phone and pushed into the ACS\n * raw outgoing stream. `whip` is the glasses microphone on the WebRTC track they publish (SoftAP or\n * Cloudflare). `phone` is the phone's own microphone. `none` means the source we committed to went\n * away mid-call, which is a reportable failure rather than a reason to open a different microphone.\n */\nexport type MicTransport = \"ble-lc3\" | \"whip\" | \"phone\" | \"none\"\n\n/** Error surfaced when the pinned glasses microphone stops producing audio during a call. */\nexport const GLASSES_MIC_UNAVAILABLE = \"GLASSES_MIC_UNAVAILABLE\"\n\nexport type MeetingParticipantState = \"idle\" | \"connecting\" | \"connected\" | \"lobby\" | \"hold\" | \"disconnected\"\n\nexport interface MeetingParticipant {\n id: string\n displayName: string | null\n state: MeetingParticipantState\n isMuted: boolean\n isSpeaking: boolean\n}\n\n/**\n * One runtime participant capability.\n *\n * `allowed` is nullable because \"denied\" and \"not known yet\" are different facts. ACS delivers\n * capabilities asynchronously, so every call is briefly unknown, and collapsing that into `false`\n * would hide controls on calls that do in fact permit them.\n */\nexport interface MeetingCapability {\n allowed: boolean | null\n reason: string | null\n}\n\nexport interface MeetingCapabilities {\n /** Whether this participant may end the Teams group call for everyone. Presenters only. */\n hangUpForEveryone: MeetingCapability\n manageLobby?: MeetingCapability\n}\n\nexport function parseMeetingCapabilities(raw: unknown): MeetingCapabilities | undefined {\n if (!raw || typeof raw !== \"object\") return undefined\n const value = (raw as Record<string, unknown>).hangUpForEveryone\n if (!value || typeof value !== \"object\") return undefined\n const capability = value as Record<string, unknown>\n const rawLobby = (raw as Record<string, unknown>).manageLobby\n const lobby = rawLobby && typeof rawLobby === \"object\" ? rawLobby as Record<string, unknown> : undefined\n return {\n ...(lobby ? {manageLobby: {\n allowed: typeof lobby.allowed === \"boolean\" ? lobby.allowed : null,\n reason: typeof lobby.reason === \"string\" && lobby.reason ? lobby.reason : null,\n }} : {}),\n hangUpForEveryone: {\n allowed: typeof capability.allowed === \"boolean\" ? capability.allowed : null,\n reason: typeof capability.reason === \"string\" && capability.reason ? capability.reason : null,\n },\n }\n}\n\n/**\n * Read the ACS `CallEndReason` off a native state event.\n *\n * Native flattens it into `endReason_code` / `endReason_subcode` / `endReason_message` rather than\n * a nested object, because the Expo bridge drops nested nulls. Anything non-numeric is discarded:\n * a code that arrived as a string would compare unequal to every entry in the lookup tables and\n * classify a known failure as unknown, which is worse than having no code at all.\n */\nexport function parseMeetingEndReason(event: Record<string, unknown>): MeetingEndReason | undefined {\n const num = (value: unknown): number | undefined => (typeof value === \"number\" && Number.isFinite(value) ? value : undefined)\n const code = num(event.endReason_code)\n const subcode = num(event.endReason_subcode)\n const message = typeof event.endReason_message === \"string\" ? event.endReason_message : undefined\n if (code === undefined && subcode === undefined && !message) return undefined\n return {...(code !== undefined ? {code} : {}), ...(subcode !== undefined ? {subcode} : {}), ...(message ? {message} : {})}\n}\n\nexport interface MeetingState {\n state: MeetingPhase\n muted: boolean\n error?: string\n meetingUrl?: string\n provider?: \"acs-teams\"\n audioSource?: \"glasses\" | \"phone\"\n audioSourceReason?: SourceReason\n activeStream?: ActiveStream\n audioSafety?: AudioSafety\n mediaSource?: MediaSourceState\n mediaSourceReason?: string\n callEndReason?: {code: number; subcode: number}\n participants?: MeetingParticipant[]\n /** Runtime capabilities. Omitted by natives that predate them; read that as unknown. */\n capabilities?: MeetingCapabilities\n /** Which microphone path is carrying the wearer's voice, decided at join time. */\n micTransport?: MicTransport\n /**\n * SoftAP join checklist, attached only to the state events the SoftAP orchestrator emits while\n * it walks hotspot → scoped join → ACS join → publish → live. Native ACS events never carry it,\n * so a consumer keeps the last one it saw rather than treating its absence as a reset.\n */\n softap?: SoftapProgress\n /**\n * ACS `CallEndReason`, forwarded numerically.\n *\n * It is the only machine-readable statement of *why* a join failed, and a miniapp cannot tell a\n * dead meeting link from a dropped network any other way — the human message is localised and\n * reworded between SDK releases, so matching on it would turn an outage into \"your link is\n * broken\" the first time Microsoft rephrases a sentence.\n */\n endReason?: MeetingEndReason\n}\n\n/** Numeric ACS `CallEndReason`. `message` is for logs and bug reports only, never for branching. */\nexport interface MeetingEndReason {\n code?: number\n subcode?: number\n message?: string\n}\n\n/**\n * The call microphone is [ACS_CALL_MIC], and `preferred_mic` governs MentraOS STT capture rather\n * than this call.\n *\n * `\"glasses\"` selects the wearer's own microphone. Which *transport* carries it is a separate\n * decision made per call by [glassesLc3UplinkSupported]: BLE LC3 into the ACS raw outgoing stream\n * where the host and native both support it, otherwise the glasses' published WebRTC audio track.\n * `\"phone\"` selects the phone's microphone via `PhoneMicCapturer`; do not route it through ACS\n * `LocalOutgoingAudioStream`, because that hands ACS the audio route\n * (MODE_IN_COMMUNICATION + forced speaker) and opens an echo loop.\n */\nexport function resolveAcsAudioSource(): ResolvedAudioSource {\n return {source: ACS_CALL_MIC, reason: \"explicit\"}\n}\n\n/**\n * Whether this call can take the wearer's voice off the glasses over BLE LC3.\n *\n * Every term is a hard requirement, and the answer has to be known *before* the glasses are told\n * what to publish — deciding afterwards is how a call ends up with either two copies of the wearer\n * or none. A host whose native module has no `pushOutgoingPcm` keeps the WHIP audio track it has\n * always used rather than silently joining a meeting nobody can be heard in.\n *\n * SoftAP takes BLE LC3 and publishes WHIP video only (`captureAudio=false`), so the glasses SoC\n * microphone is never opened for a call.\n *\n * This was switched off once on a misread: a soak logged `P4 pcm meanAbs` 8–39 and called it\n * digital silence. It was the room. The same LC3 path measured on the bench sits at `meanAbs`\n * ≈30–60 / `peak` ≈80–100 in a quiet room with nobody talking, and that soak had already\n * published with `captureAudio=false`, so the SoC mic was not the thief either. The uplink now\n * logs its own `meanAbs`/`peak` every window ([logMicUplink]) so the next soak reads the level,\n * not the frame rate. Disable only with a level log showing the floor *while the wearer talks*.\n */\nconst SOFTAP_BLE_LC3_UPLINK = true\n/**\n * How long native may take to finish a leave before it reports the cleanup as stuck.\n *\n * Generous on purpose: this is a diagnostic ceiling on a hang-up plus an agent disposal, not a\n * readiness deadline. The caller treats a timeout as \"cleanup failed\", never as \"safe to restart\".\n */\nconst ACS_LEAVE_WAIT_MS = 20_000\n/**\n * SoftAP video (camera → H.264 → WHIP → WHEP → ACS) is slower than BLE LC3.\n * Hold glasses PCM this long so the talk track does not lead the picture.\n * Set from SoftAP+LC3 clap correlator (2026-09-10): leads 70/201/173/300/142 ms,\n * median 173, rounded to 170. `AVSYNC clap audioLeadMs` is still the re-cal.\n */\nexport const SOFTAP_LC3_AUDIO_DELAY_MS = 170\nlet softapBleLc3UplinkForTests: boolean | null = null\n\nexport function glassesLc3UplinkSupported(args: {\n videoSource: AcsVideoSource\n audioSource: AcsAudioSource\n hasPushOutgoingPcm: boolean\n platform: string\n /** Somebody holds a glasses microphone session through MicSessionManager. */\n glassesSession: boolean\n}): boolean {\n if (!(softapBleLc3UplinkForTests ?? SOFTAP_BLE_LC3_UPLINK)) return false\n // The microphone belongs to whoever leased it. Without a lease nothing has pinned the glasses\n // or claimed raw PCM, so this call has no wearer audio to read off them.\n if (!args.glassesSession) return false\n // iOS has no `setMicSourcePin` yet, so it cannot promise the phone microphone stays shut.\n if (args.platform !== \"android\") return false\n // WHEP audio comes back from Cloudflare already mixed into the subscribed track; there is no\n // captureAudio flag on that path to turn off.\n if (args.videoSource.type !== \"softap\") return false\n if (args.audioSource !== \"glasses\") return false\n return args.hasPushOutgoingPcm\n}\n\nconst PARTICIPANT_STATES = new Set<MeetingParticipantState>([\n \"idle\",\n \"connecting\",\n \"connected\",\n \"lobby\",\n \"hold\",\n \"disconnected\",\n])\n\nexport function parseMeetingParticipants(raw: unknown): MeetingParticipant[] | undefined {\n if (!Array.isArray(raw)) return undefined\n const result: MeetingParticipant[] = []\n for (const entry of raw) {\n if (!entry || typeof entry !== \"object\") continue\n const value = entry as Record<string, unknown>\n if (typeof value.id !== \"string\" || !value.id) continue\n const state = PARTICIPANT_STATES.has(value.state as MeetingParticipantState)\n ? (value.state as MeetingParticipantState)\n : \"idle\"\n result.push({\n id: value.id,\n displayName: typeof value.displayName === \"string\" && value.displayName ? value.displayName : null,\n state,\n isMuted: Boolean(value.isMuted),\n isSpeaking: Boolean(value.isSpeaking),\n })\n }\n return result\n}\n\nexport type AcsOutgoingVideo = {\n width: number\n height: number\n fps: number\n maxBitrateBps: number\n}\n\n/** ACS VirtualOutgoingVideoStream documented 16:9 sizes. P540 is 960×540, not 540×960. */\nconst ACS_VIRTUAL_CAMERA_SIZES = new Set([\"1280x720\", \"960x540\", \"858x480\"])\n\nexport function parseAcsOutgoingVideo(raw: unknown): AcsOutgoingVideo | undefined {\n if (raw == null) return undefined\n if (typeof raw !== \"object\") throw new Error(\"video must be an object\")\n const value = raw as Record<string, unknown>\n const width = Number(value.width)\n const height = Number(value.height)\n const fps = Number(value.fps)\n const maxBitrateBps = Number(value.maxBitrateBps)\n if (![width, height, fps, maxBitrateBps].every(Number.isFinite)) {\n throw new Error(\"video requires width, height, fps, and maxBitrateBps\")\n }\n if (!ACS_VIRTUAL_CAMERA_SIZES.has(`${width}x${height}`) || fps < 1 || fps > 30 || maxBitrateBps <= 0) {\n throw new Error(`unsupported ACS video ${width}x${height}@${fps}`)\n }\n return {width, height, fps, maxBitrateBps}\n}\n\n/**\n * Where the glasses video comes from.\n *\n * A union rather than a nullable URL because the two transports need different inputs: WHEP is\n * given a URL, while SoftAP produces one only after the host binds a local listener. Collapsing\n * them into `whepUrl?: string` is what lets an empty string reach the subscriber and fail seconds\n * later as an opaque HTTP error.\n */\nexport type AcsVideoSource =\n | {type: \"whep\"; url: string}\n | {type: \"softap\"; ssid?: string; passphrase?: string; bindAddress?: string}\n\n/**\n * Validates a `videoSource` from a miniapp.\n *\n * Throws rather than defaulting to WHEP. A miniapp that asks for SoftAP and silently gets a\n * Cloudflare call — or vice versa — is a bug that shows up as unexplained latency or a black tile,\n * not as an error anyone can act on.\n */\nexport function parseAcsVideoSource(raw: unknown): AcsVideoSource {\n if (raw == null || typeof raw !== \"object\") {\n throw new Error(`videoSource must be {type: \"whep\", url} or {type: \"softap\"}`)\n }\n const value = raw as Record<string, unknown>\n\n if (value.type === \"whep\") {\n const url = typeof value.url === \"string\" ? value.url.trim() : \"\"\n if (!url) throw new Error(\"videoSource.url is required for a WHEP source\")\n return {type: \"whep\", url}\n }\n\n if (value.type === \"softap\") {\n const ssid = typeof value.ssid === \"string\" ? value.ssid.trim() : \"\"\n const passphrase = typeof value.passphrase === \"string\" ? value.passphrase : \"\"\n // Half a credential pair would otherwise present as a failed hotspot join much later.\n if (Boolean(ssid) !== Boolean(passphrase)) {\n throw new Error(\"videoSource.ssid and videoSource.passphrase must be provided together\")\n }\n return ssid ? {type: \"softap\", ssid, passphrase} : {type: \"softap\"}\n }\n\n throw new Error(`unsupported videoSource.type: ${String(value.type)}`)\n}\n\n/**\n * The app's default network after a hotspot join.\n *\n * `usable` is the only field to branch on; the rest is for the note the wearer sees and the trace.\n * A held cellular request brings the radio up but does not promise the default route has switched\n * or validated, so this is asked separately rather than inferred from the hold.\n */\nexport interface DefaultNetworkStatus {\n transport: string\n validated: boolean\n present: boolean\n usable: boolean\n detail: string\n}\n\n/**\n * Which path the wearer took into the call.\n *\n * Diagnostic only — nothing behaves differently — but it is carried all the way to the native\n * traces because the open question about video quality is exactly \"do these two differ\", and a\n * log that cannot separate them cannot answer it.\n */\nexport type AcsCallOrigin = \"created\" | \"joined\" | \"unknown\"\n\nexport function parseAcsCallOrigin(value: unknown): AcsCallOrigin {\n return value === \"created\" || value === \"joined\" ? value : \"unknown\"\n}\n\ntype NativeModule = {\n prepareAgent?(options: {token: string; displayName?: string}): Promise<MeetingState>\n join(options: {\n meetingUrl: string\n token: string\n /** Legacy field, still sent for whep so an older native keeps working. */\n whepUrl: string\n videoSource: AcsVideoSource\n displayName?: string\n dumpPcmWav?: boolean\n audioSource?: \"glasses\" | \"phone\"\n audioDelayMs?: number\n video?: AcsOutgoingVideo\n origin?: AcsCallOrigin\n }): Promise<MeetingState & {ingestUrl?: string}>\n leave(): Promise<void>\n /**\n * Leave, and resolve only once the hang-up, the agent disposal, and the network releases have\n * actually finished.\n *\n * [leave] queues its work on the session executor and returns immediately, so awaiting it proves\n * nothing about cleanup — which is what let a fast Stop/Start start a second call on top of the\n * first one's teardown. Absent on natives that predate the signal.\n */\n leaveAndAwait?(options: {timeoutMs: number}): Promise<{completed: boolean}>\n /**\n * Wait for the SoftAP WHIP listener's port. `closed: false` means it is still held.\n *\n * Separate from [leaveAndAwait] because the listener outlives the ACS teardown on purpose: it\n * answers `410` for a few seconds so an in-flight request from the glasses gets a status rather\n * than a reset. Absent on natives that predate the barrier.\n */\n awaitIngestClosed?(options: {timeoutMs: number}): Promise<{closed: boolean}>\n /** Drop the retiring WHIP listener now, skipping its grace period. */\n forceCloseIngest?(): Promise<void>\n /**\n * End the group call for everyone, then tear this device down. Rejects when the capability is\n * denied or ACS refuses — and has still left the call. Absent on natives that predate End.\n */\n endForEveryone?(): Promise<MeetingState>\n admitParticipant?(participantId: string): Promise<void>\n setMuted(muted: boolean): Promise<MeetingState>\n setAudioSource(source: \"glasses\" | \"phone\"): Promise<MeetingState>\n updateVideoSource(whepUrl: string): Promise<void>\n /** Force a WHEP rebuild on the current URL. Absent on natives that predate it. */\n restartVideoSource?(): Promise<void>\n /**\n * SoftAP: destroy the current ingest listener and bind a new one. Resolves with\n * the new URL. Absent on natives that predate rebind; disabled natives reject.\n */\n rebindSoftApIngest?(): Promise<string>\n /**\n * Join the glasses hotspot as a scoped, internet-less network; resolves with this phone's\n * address on it. Absent on natives that predate SoftAP.\n */\n joinScopedNetwork?(ssid: string, passphrase: string): Promise<string>\n joinScopedNetworkWithGateway?(ssid: string, passphrase: string, gateway: string): Promise<string>\n /** Is this phone's Wi-Fi radio on? Absent on natives that predate the preflight. */\n isWifiEnabled?(): Promise<boolean>\n beginTrace?(traceId: string): Promise<void>\n leaveScopedNetwork?(): Promise<void>\n cancelScopedNetworkJoin?(): Promise<void>\n awaitDefaultNetworkAfterHotspot?(): Promise<DefaultNetworkStatus>\n /**\n * TCP-probe the hotspot gateway over the scoped network. Absent on natives that predate it.\n * `detail` is a one-line human summary (address, port, latency or the failure).\n */\n probeScopedGateway?(): Promise<{reachable: boolean; detail: string}>\n /** The joined hotspot: `prefix` is what the media path must stay inside. */\n scopedNetworkInfo?(): Promise<{available: boolean; localIpv4: string | null; prefix: string | null}>\n /**\n * Wait for the app's default network to be validated, after the hotspot join changed it.\n * Absent on natives that predate the cellular transition handling.\n */\n awaitValidatedDefaultNetwork?(): Promise<DefaultNetworkStatus>\n getState(): Promise<MeetingState>\n /**\n * Hand one chunk of already-decoded microphone PCM to the ACS uplink. Synchronous on purpose:\n * this runs ~100×/s and a promise per chunk would cost more than the copy does.\n *\n * Absent on natives that predate the BLE LC3 uplink, which is exactly what\n * [glassesLc3UplinkSupported] tests for.\n */\n pushOutgoingPcm?(base64: string, sampleRate: number, channels: number): void\n addListener(event: string, listener: (event: Record<string, unknown>) => void): {remove: () => void}\n}\n\nlet nativeModule: NativeModule | null | undefined\n\nfunction getNative(): NativeModule | null {\n if (nativeModule !== undefined) return nativeModule\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n nativeModule = require(\"@mentra/acs-meeting\").default as NativeModule\n } catch {\n nativeModule = null\n }\n return nativeModule\n}\n\n/** Test seam: skip the native require and inject a fake ACS module. */\nexport function setAcsMeetingNativeForTests(mod: NativeModule | null | undefined): void {\n nativeModule = mod\n}\n\n/** Test seam: exercise the BLE LC3 path without flipping the production kill switch. */\nexport function setSoftapBleLc3UplinkForTests(enabled: boolean | null): void {\n softapBleLc3UplinkForTests = enabled\n}\n\n/**\n * Phone connectivity feed. Only the subset of `@react-native-community/netinfo`\n * this service needs, so tests can inject a fake and hosts without the package\n * (or a bare test runtime) degrade to \"no phone-network awareness\" instead of\n * failing to load the meeting service.\n */\nexport type PhoneNetworkInfo = {type: string; isConnected: boolean | null}\ntype PhoneNetworkSource = {\n addEventListener(listener: (state: PhoneNetworkInfo) => void): () => void\n}\n\nlet phoneNetwork: PhoneNetworkSource | null | undefined\n\nfunction getPhoneNetwork(): PhoneNetworkSource | null {\n if (phoneNetwork !== undefined) return phoneNetwork\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const netInfo = require(\"@react-native-community/netinfo\") as {default?: PhoneNetworkSource} & PhoneNetworkSource\n phoneNetwork = netInfo.default ?? netInfo\n } catch {\n phoneNetwork = null\n }\n return phoneNetwork\n}\n\n/** Test seam: inject a fake phone-network feed (or `null` to disable it). */\nexport function setAcsMeetingPhoneNetworkForTests(source: PhoneNetworkSource | null | undefined): void {\n phoneNetwork = source\n}\n\nfunction parseActiveStream(value: unknown): ActiveStream | undefined {\n if (value === \"none\" || value === \"virtual\" || value === \"local\") return value\n return undefined\n}\n\nfunction parseAudioSafety(value: unknown): AudioSafety | undefined {\n if (value === \"safe\" || value === \"degraded\" || value === \"unsafe\") return value\n return undefined\n}\n\nfunction parseMediaSource(value: unknown): MediaSourceState | undefined {\n if (value === \"idle\" || value === \"connecting\" || value === \"live\" || value === \"failed\") return value\n return undefined\n}\n\n/** Meeting phases during which the WHEP feed should be alive and is worth restarting. */\nconst MEDIA_ACTIVE_PHASES = new Set<MeetingPhase>([\"connecting\", \"lobby\", \"connected\"])\n/** Floor between WHEP restarts we trigger from the host, so a flapping network cannot thrash native. */\nconst MEDIA_RESTART_MIN_INTERVAL_MS = 3000\n\n/** Formats the native PcmStreamPlayer accepts (mono only). */\nconst PCM_SAMPLE_RATES = new Set([16000, 24000, 48000])\n\n/**\n * Playout headroom for the far end's voice.\n *\n * The native player defaults to half a second, which is right for a miniapp clip and wrong here:\n * a streaming track sits at its buffer size, so that default is 500ms of delay before the wearer\n * hears anyone, enough that both sides talk over each other. This trades cushion for immediacy —\n * still several BLE playout beats, but a conversation instead of a broadcast.\n */\nconst PCM_JITTER_MS = 120\n/**\n * Above this the backlog is real congestion rather than the configured cushion.\n *\n * Has to stay clear of [PCM_JITTER_MS], because the reported backlog *includes* the track's own\n * buffer and so never falls below it. A threshold at or under the cushion logs once per interval\n * for the whole call and says nothing.\n */\nconst PCM_BACKLOG_WARN_MS = PCM_JITTER_MS + 400\n\n/** The Bluetooth SDK mic identifier the call pins itself to. */\nconst GLASSES_MIC_SOURCE = \"glasses\"\n/**\n * How long the glasses may produce no PCM before the call reports its microphone gone.\n *\n * The pin makes a phone-mic fallback impossible, so the only honest response to a source that\n * stopped is to say so. One second is several BLE mic-beats: long enough that a reconnect blip\n * does not raise an error, short enough that the wearer is not talking into nothing for long.\n */\nconst GLASSES_MIC_GRACE_MS = 1000\n/** Cadence of the uplink health line, matching the native P8 ladder. */\nconst MIC_UPLINK_LOG_INTERVAL_MS = 5000\n/** During a gain sweep, one-second windows so each 25 s phase has enough speech samples. */\nconst MIC_UPLINK_SWEEP_LOG_INTERVAL_MS = 1000\n/** A 50 ms LC3 frame arriving more than this late is a missed beat, not jitter. */\nconst MIC_GAP_WARN_MS = 90\n\nclass AcsMeetingService {\n private owner: string | null = null\n private pcmStreamId: string | null = null\n private pcmFormat: {sampleRate: number; channels: number} | null = null\n private pcmReopen: Promise<void> | null = null\n private pcmWriteChain: Promise<void> = Promise.resolve()\n private lastBacklogWarnAt = 0\n private subscriptions: Array<{remove: () => void}> = []\n private lastState: MeetingState = {state: \"idle\", muted: false}\n private onState: ((packageName: string, state: MeetingState) => void) | null = null\n /** WHEP URL native is (or should be) subscribed to; what a host-triggered restart re-feeds. */\n private whepUrl: string | null = null\n /** Transport for the active call, so recovery picks the right repair. */\n private videoSource: AcsVideoSource | null = null\n /**\n * SoftAP only: the URL the glasses must publish to. An output of the join rather than an input,\n * because it is not known until native has bound a listener and been given a port.\n */\n private ingestUrl: string | null = null\n private phoneNetworkUnsub: (() => void) | null = null\n private lastPhoneNetworkKey: string | null = null\n private lastMediaRestartAt = 0\n /** Callers parked in [waitForFirstFrame], woken by the next `mediaSource` verdict. */\n private readonly firstFrameWaiters = new Set<(error?: Error) => void>()\n /**\n * Bumped by [invalidateDecodedMedia]. A `live` verdict only counts for the wait that\n * started after that bump if [liveEpoch] matches.\n */\n private decodedMediaEpoch = 0\n /** [decodedMediaEpoch] at the moment the phone last reported `mediaSource: live`. */\n private liveEpoch = -1\n /** Mid-call republish waiters: live resolves true, leave/timeout resolves false. Failed is ignored. */\n private readonly mediaLiveWaiters = new Set<(live: boolean) => void>()\n private scopedLostSub: {remove: () => void} | null = null\n private readonly scopedLostListeners = new Set<(error: {code: string; message: string}) => void>()\n /**\n * Set before the scoped network is released, so the loss we are about to cause is not reported as\n * one that happened to us. Android emits `onLost` for a deliberate release, and a naive wiring\n * turns every successful Leave and End into a mid-call network error.\n */\n private scopedTerminating = false\n /**\n * Bumped by every join and every release, and captured by everything that can outlive a call:\n * the `mic_pcm` listener and the in-flight `native.join`.\n *\n * A leave during a slow join is the case this exists for. Without it the join resolves into a\n * torn-down host, subscribes a microphone listener nobody will ever unsubscribe, and pushes the\n * wearer's voice at a native session that has already left the meeting.\n */\n private callGeneration = 0\n /** Stamped on the host-side state traces so they can be grouped the same way the native ones are. */\n private callOrigin: AcsCallOrigin = \"unknown\"\n private micTransport: MicTransport = \"whip\"\n private micSub: {remove: () => void} | null = null\n /** Backstop lease, held only while this call is actually reading the glasses mic. */\n private micSession: MicSession | null = null\n private micTuningSub: {remove: () => void} | null = null\n private micRmsSub: {remove: () => void} | null = null\n /** Only turn telemetry off again if this call is what turned it on. */\n private micRmsEnabled = false\n private gateSamples = 0\n private gateClosed = 0\n private gateElevated = 0\n private gateClosedElevated = 0\n private gateRmsMax = 0\n /** True between the pin/requirement being taken and released, so release is exactly once. */\n private micUplinkActive = false\n private micFramesForwarded = 0\n /** Frames since the last health line, so the rate and the call total stay separate facts. */\n private micFramesWindow = 0\n private micDropsStale = 0\n private micDropsNonGlasses = 0\n private micGaps = 0\n private micGapMsMax = 0\n private lastGlassesFrameAt = 0\n private lastMicUplinkLogAt = 0\n private lastMicDropLogAt = 0\n /** PCM level over the current health window; read and reset by [logMicUplink]. */\n private micLevel = new Pcm16LevelMeter()\n private lastMicLevel: {meanAbs: number; peak: number} | null = null\n /** Guards [releaseHostState] so a remote hang-up followed by an explicit leave releases once. */\n private hostStateReleased = true\n\n setStateHandler(handler: (packageName: string, state: MeetingState) => void): void {\n this.onState = handler\n }\n\n getState(): MeetingState {\n return {...this.lastState}\n }\n\n ownerPackage(): string | null {\n return this.owner\n }\n\n /**\n * The WHIP URL the glasses must POST their offer to, for a SoftAP call. Null for every other\n * transport and until the join has bound a listener; the orchestrator reads it between the ACS\n * join and telling the glasses to publish.\n */\n softApIngestUrl(): string | null {\n return this.ingestUrl\n }\n\n /**\n * Whether this call is taking the wearer's voice over BLE LC3, which means the glasses must\n * publish video only. Read by the SoftAP orchestrator between the meeting join and the publish.\n */\n glassesLc3UplinkActive(): boolean {\n return this.micTransport === \"ble-lc3\"\n }\n\n /**\n * Has the SoftAP video receiver released its port?\n *\n * A native that cannot answer reports `true`: it also predates the tombstone this waits out, so\n * there is nothing for the barrier to be waiting on.\n */\n async awaitIngestClosed(timeoutMs: number): Promise<boolean> {\n const native = getNative()\n if (!native?.awaitIngestClosed) return true\n const outcome = await native.awaitIngestClosed({timeoutMs})\n return outcome.closed\n }\n\n /** Close the retiring WHIP listener now. No-op on natives without it. */\n async forceCloseIngest(): Promise<void> {\n await getNative()?.forceCloseIngest?.()\n }\n\n /**\n * Destroy the current SoftAP ingest listener and bind a new one. The caller\n * rejoins the hotspot first; native reads the current scoped address.\n */\n async rebindSoftApIngest(): Promise<string> {\n const native = getNative()\n if (!native?.rebindSoftApIngest) {\n throw new Error(\"SoftAP ingest rebind is not available on this native\")\n }\n this.invalidateDecodedMedia()\n const url = await native.rebindSoftApIngest()\n this.ingestUrl = url\n return url\n }\n\n /**\n * Forget a previously decoded first frame. Recovery must wait for a frame\n * from the new ingest generation, not short-circuit on the last live verdict.\n */\n invalidateDecodedMedia(): void {\n this.decodedMediaEpoch++\n if (this.lastState.mediaSource === \"live\") {\n this.lastState = {...this.lastState, mediaSource: \"connecting\", mediaSourceReason: \"ingest_rebind\"}\n }\n }\n\n /**\n * Is this phone's Wi-Fi radio on?\n *\n * `null` means the question cannot be answered on this host — iOS, or a native that predates the\n * preflight — and callers must treat that as \"carry on\", not as \"off\". Refusing a call because\n * we could not ask would break every platform that never had the problem.\n */\n async isWifiEnabled(): Promise<boolean | null> {\n const native = getNative()\n if (!native?.isWifiEnabled) return null\n return await native.isWifiEnabled()\n }\n\n /**\n * Join the glasses hotspot as a scoped, internet-less network, returning this phone's address on\n * it. Called before the ACS join, because the local WHIP listener has to bind to that address.\n *\n * A host without the native function is not a host that silently skips the join — the SoftAP call\n * has no network to run on, so this reports the reason instead.\n */\n async joinScopedNetwork(ssid: string, passphrase: string, gateway?: string): Promise<string | undefined> {\n const native = getNative()\n if (!native?.joinScopedNetwork) {\n throw new Error(\"This host cannot join the glasses hotspot; SoftAP calling is unavailable\")\n }\n this.scopedTerminating = false\n this.bindScopedNetworkLost(native)\n await native.beginTrace?.(softapTraceId())\n if (this.scopedTerminating) throw new Error(\"Hotspot join cancelled\")\n if (native.joinScopedNetworkWithGateway) {\n if (!gateway) throw new Error(\"The glasses did not report a hotspot gateway\")\n return await native.joinScopedNetworkWithGateway(ssid, passphrase, gateway)\n }\n return await native.joinScopedNetwork(ssid, passphrase)\n }\n\n /**\n * Subscribe to \"the glasses hotspot went away while we still wanted it\".\n *\n * Only unexpected losses arrive here. Native drops the framework callback for a network it\n * released itself, and [leaveScopedNetwork] raises the terminal intent before releasing, so a\n * normal Leave or End cannot manufacture a mid-call failure.\n */\n onScopedNetworkLost(listener: (error: {code: string; message: string}) => void): () => void {\n this.scopedLostListeners.add(listener)\n return () => this.scopedLostListeners.delete(listener)\n }\n\n private bindScopedNetworkLost(native: NativeModule): void {\n if (this.scopedLostSub) return\n try {\n this.scopedLostSub = native.addListener(\"onScopedNetworkLost\", (event) => {\n if (this.scopedTerminating) {\n console.log(\"[AcsMeeting] phase=scoped-lost-expected\", {code: event.code})\n return\n }\n const error = {\n code: typeof event.code === \"string\" ? event.code : \"SOFTAP_NETWORK_LOST\",\n message: typeof event.message === \"string\" ? event.message : \"The glasses hotspot went away\",\n }\n console.warn(\"[AcsMeeting] phase=scoped-lost\", error)\n for (const listener of [...this.scopedLostListeners]) {\n try {\n listener(error)\n } catch (listenerError) {\n console.warn(\"[AcsMeeting] scoped-lost listener threw\", listenerError)\n }\n }\n })\n } catch (error) {\n // A native that predates the event simply never reports mid-call loss; that is a smaller\n // problem than failing the join over a missing listener.\n console.warn(\"[AcsMeeting] scoped network loss events unavailable\", error)\n this.scopedLostSub = null\n }\n }\n\n /** Raise the terminal intent so the release we are about to do is not read as a failure. */\n beginScopedTeardown(): void {\n this.scopedTerminating = true\n }\n\n /**\n * Wait until the phone's default network is validated again after the hotspot join.\n *\n * Joining the glasses hotspot takes the phone off Wi-Fi, and ACS needs the internet for the very\n * next step. Waiting is what turns a 40-second join timeout with device-wide DNS failures into a\n * short, named wait — or an honest failure. Null when the host cannot tell.\n */\n async awaitValidatedDefaultNetwork(): Promise<DefaultNetworkStatus | null> {\n const native = getNative()\n if (!native?.awaitValidatedDefaultNetwork) return null\n return await native.awaitValidatedDefaultNetwork()\n }\n\n /** Cleanup may restore home Wi-Fi; only the live SoftAP leg requires cellular on iOS. */\n async awaitDefaultNetworkAfterHotspot(): Promise<DefaultNetworkStatus | null> {\n const native = getNative()\n return native?.awaitDefaultNetworkAfterHotspot\n ? await native.awaitDefaultNetworkAfterHotspot()\n : await this.awaitValidatedDefaultNetwork()\n }\n\n async cancelScopedNetworkJoin(): Promise<void> {\n this.scopedTerminating = true\n await getNative()?.cancelScopedNetworkJoin?.()\n }\n\n /**\n * Can this phone reach the glasses over the hotspot it just joined? Null when the host cannot\n * tell (no native support), so the orchestrator narrates nothing rather than a guess.\n */\n async probeScopedGateway(): Promise<{reachable: boolean; detail: string} | null> {\n const native = getNative()\n if (!native?.probeScopedGateway) return null\n return await native.probeScopedGateway()\n }\n\n /** Safe to call when nothing was joined: teardown runs after failed starts too. */\n async leaveScopedNetwork(): Promise<void> {\n // Intent first, release second. The other order is the false-positive bug: Android reports the\n // loss we asked for, and the call reports a network failure as it is successfully ending.\n this.scopedTerminating = true\n try {\n await getNative()?.leaveScopedNetwork?.()\n } finally {\n this.scopedLostSub?.remove()\n this.scopedLostSub = null\n }\n }\n\n /**\n * Resolves when the phone decodes its first glasses frame. This confirms the local media leg;\n * Teams admission is a separate call state and may still be connecting or in the lobby.\n * Rejects if the feed fails first, and on timeout.\n *\n * @param timeoutMs how long to wait before treating the silence as a failure\n */\n waitForFirstFrame(timeoutMs: number, options: {fresh?: boolean} = {}): Promise<void> {\n const liveThisGeneration =\n this.lastState.mediaSource === \"live\" && this.liveEpoch === this.decodedMediaEpoch\n // Join short-circuits on any live. Recovery (`fresh`) short-circuits only on a live\n // from this ingest generation: the new WHIP first frame often lands during publish,\n // before this wait starts. Waiting for a later `onState` then times out while video\n // is already flowing, and the miniapp hangs up the ACS meeting.\n if (liveThisGeneration) {\n softapTrace(\n options.fresh ? \"glasses_first_frame_this_generation\" : \"glasses_first_frame_already_received\",\n {mediaSource: this.lastState.mediaSource, epoch: this.decodedMediaEpoch},\n )\n return Promise.resolve()\n }\n const startedAt = Date.now()\n softapTrace(\"acs_first_frame_wait\", {\n timeoutMs,\n mediaSource: this.lastState.mediaSource ?? \"unknown\",\n state: this.lastState.state,\n })\n return new Promise<void>((resolve, reject) => {\n const settle = (error?: Error) => {\n if (done) return\n done = true\n clearTimeout(timer)\n this.firstFrameWaiters.delete(settle)\n // The step this closes is the one that decides whether the call is usable, so its outcome\n // is named rather than inferred from whichever line happens to follow.\n if (error) {\n softapTraceFailure(\"acs_first_frame_wait_done\", {\n waitedMs: Date.now() - startedAt,\n reason: error.message,\n })\n reject(error)\n } else {\n softapTrace(\"acs_first_frame_wait_done\", {waitedMs: Date.now() - startedAt})\n resolve()\n }\n }\n let done = false\n const timer = setTimeout(\n () => settle(new Error(`No glasses video reached the phone within ${Math.round(timeoutMs / 1000)}s`)),\n timeoutMs,\n )\n this.firstFrameWaiters.add(settle)\n })\n }\n\n /** Wake every `waitForFirstFrame` caller with the outcome the host just reported. */\n private settleFirstFrameWaiters(mediaSource: MediaSourceState | undefined): void {\n if (mediaSource !== \"live\" && mediaSource !== \"failed\") return\n const error = mediaSource === \"failed\" ? new Error(\"The glasses video feed failed\") : undefined\n for (const settle of [...this.firstFrameWaiters]) settle(error)\n if (mediaSource === \"live\") this.settleMediaLiveWaiters(true)\n }\n\n private settleMediaLiveWaiters(live: boolean): void {\n for (const settle of [...this.mediaLiveWaiters]) settle(live)\n }\n\n /**\n * Mid-call SoftAP camera recovery. Resolves `true` only when ingest is live again.\n * A standing `failed` is why we republished, so it must not abort the wait the way\n * [waitForFirstFrame] does on join.\n */\n waitUntilMediaLive(timeoutMs: number): Promise<boolean> {\n if (this.lastState.mediaSource === \"live\") return Promise.resolve(true)\n const startedAt = Date.now()\n softapTrace(\"acs_media_live_wait\", {\n timeoutMs,\n mediaSource: this.lastState.mediaSource ?? \"unknown\",\n state: this.lastState.state,\n })\n return new Promise<boolean>((resolve) => {\n const settle = (live: boolean) => {\n if (done) return\n done = true\n clearTimeout(timer)\n this.mediaLiveWaiters.delete(settle)\n softapTrace(\"acs_media_live_wait_done\", {\n waitedMs: Date.now() - startedAt,\n live,\n })\n resolve(live)\n }\n let done = false\n const timer = setTimeout(() => settle(false), timeoutMs)\n this.mediaLiveWaiters.add(settle)\n })\n }\n\n /**\n * Sign in to ACS before the glasses hotspot exists.\n *\n * SoftAP DNS cannot resolve Teams hosts. Doing this on the phone's existing internet is what\n * stops `createCallAgent` from hanging until the hotspot is torn down.\n */\n async prepareAgent(args: {token: string; displayName?: string}): Promise<void> {\n const native = getNative()\n if (!native?.prepareAgent) {\n // A host that cannot pre-sign-in still joins; it just does the sign-in inside the SoftAP\n // join, which is the 20-second ACS_AGENT_TIMEOUT this step exists to avoid. Worth a line,\n // because from the trace alone that build looks like one whose sign-in was instant.\n softapTrace(\"acs_prepare_agent_skipped\", {reason: native ? \"unsupported build\" : \"no native module\"})\n return\n }\n console.log(\"[AcsMeeting] phase=prepare-agent\")\n const startedAt = Date.now()\n softapTrace(\"acs_native_prepare_agent\", {hasDisplayName: Boolean(args.displayName)})\n try {\n await native.prepareAgent({token: args.token, displayName: args.displayName})\n } catch (error) {\n softapTraceFailure(\"acs_native_prepare_agent_failed\", {\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n console.log(\"[AcsMeeting] phase=prepare-agent-ok\")\n softapTrace(\"acs_native_prepare_agent_ok\", {durationMs: Date.now() - startedAt})\n }\n\n async join(\n packageName: string,\n args: {\n meetingUrl: string\n token: string\n videoSource: AcsVideoSource\n displayName?: string\n video?: AcsOutgoingVideo\n origin?: AcsCallOrigin\n /**\n * Whether the caller holds a glasses microphone session. The uplink is the wearer's voice,\n * so it is only taken off the glasses when somebody has actually claimed that microphone\n * through MicSessionManager; this class never claims it itself.\n */\n glassesSession?: boolean\n },\n ): Promise<MeetingState> {\n const native = getNative()\n if (!native) {\n console.warn(\"[AcsMeeting] phase=join-native nativeLoaded=false\")\n throw new Error(\"ACS meeting module is not available on this host\")\n }\n if (this.owner && this.owner !== packageName) {\n throw new Error(\"Another miniapp already has an active meeting\")\n }\n // Validate before claiming ownership so a bad request cannot leave the slot taken.\n const video = args.video ? parseAcsOutgoingVideo(args.video) : undefined\n const resolved = resolveAcsAudioSource()\n const generation = ++this.callGeneration\n this.hostStateReleased = false\n this.owner = packageName\n // Only a whep source has a URL to re-feed on recovery; softap rebuilds instead.\n this.whepUrl = args.videoSource.type === \"whep\" ? args.videoSource.url : null\n this.videoSource = args.videoSource\n // Decided here, before the join, so the SoftAP orchestrator can read it between the join and\n // telling the glasses what to capture.\n const lc3Uplink = glassesLc3UplinkSupported({\n videoSource: args.videoSource,\n audioSource: resolved.source,\n hasPushOutgoingPcm: typeof native.pushOutgoingPcm === \"function\",\n platform: Platform.OS,\n glassesSession: args.glassesSession ?? false,\n })\n this.micTransport = lc3Uplink ? \"ble-lc3\" : resolved.source === \"phone\" ? \"phone\" : \"whip\"\n this.bindNative(native, packageName)\n console.log(\"[AcsMeeting] phase=join-native\", {\n packageName,\n nativeLoaded: true,\n hasToken: Boolean(args.token),\n transport: args.videoSource.type,\n audioSource: resolved.source,\n audioSourceReason: resolved.reason,\n micTransport: this.micTransport,\n preferredMic: useSettingsStore.getState().getSetting(SETTINGS.preferred_mic.key),\n })\n const joinStartedAt = Date.now()\n const origin = parseAcsCallOrigin(args.origin)\n this.callOrigin = origin\n softapTrace(\"acs_native_join\", {\n packageName,\n generation,\n transport: args.videoSource.type,\n audioSource: resolved.source,\n micTransport: this.micTransport,\n audioDelayMs: lc3Uplink ? SOFTAP_LC3_AUDIO_DELAY_MS : 0,\n video: video ? `${video.width}x${video.height}@${video.fps}` : \"default\",\n origin,\n })\n // Duplicated from the native `native_join_options` line on purpose: if the native trace is\n // missing from a capture — a bug report with only the JS log, a crash before export — this is\n // the only record of what the two paths actually asked for.\n softapTrace(\"acs_join_options\", {\n origin,\n transport: args.videoSource.type,\n width: video?.width ?? 0,\n height: video?.height ?? 0,\n fps: video?.fps ?? 0,\n maxBitrateBps: video?.maxBitrateBps ?? 0,\n })\n try {\n const state = await native.join({\n meetingUrl: args.meetingUrl,\n token: args.token,\n whepUrl: this.whepUrl ?? \"\",\n videoSource: args.videoSource,\n displayName: args.displayName,\n audioSource: resolved.source,\n origin,\n ...(lc3Uplink ? {audioDelayMs: SOFTAP_LC3_AUDIO_DELAY_MS} : {}),\n ...(video ? {video} : {}),\n })\n softapTrace(\"acs_native_join_returned\", {\n packageName,\n generation,\n state: state.state,\n hasIngestUrl: typeof state.ingestUrl === \"string\" && state.ingestUrl.length > 0,\n durationMs: Date.now() - joinStartedAt,\n })\n if (generation !== this.callGeneration) {\n // The wearer left while ACS was still joining. Nothing above knows about this call, so\n // hanging it up here is the only thing that takes the device out of the Teams roster.\n console.warn(\"[AcsMeeting] phase=join-cancelled\", {packageName, generation})\n softapTraceFailure(\"acs_native_join_cancelled\", {\n packageName,\n generation,\n current: this.callGeneration,\n durationMs: Date.now() - joinStartedAt,\n })\n await native.leave().catch((leaveError) => {\n console.warn(\"[AcsMeeting] native leave after a cancelled join failed\", leaveError)\n softapTraceFailure(\"acs_native_leave_after_cancelled_join_failed\", {\n packageName,\n reason: leaveError instanceof Error ? leaveError.message : String(leaveError),\n })\n })\n throw new Error(\"The meeting was cancelled before it finished joining\")\n }\n this.ingestUrl = typeof state.ingestUrl === \"string\" ? state.ingestUrl : null\n const {ingestUrl: _ingestUrl, ...meetingState} = state\n this.lastState = {\n ...meetingState,\n audioSource: resolved.source,\n audioSourceReason: resolved.reason,\n micTransport: this.micTransport,\n }\n console.log(\"[AcsMeeting] phase=join-native-ok\", {state: state.state, muted: state.muted})\n this.startGlassesMicUplink(generation)\n } catch (error) {\n // Native never joined (or is unwinding). Release the slot so the same or another\n // miniapp can retry, and make sure nothing half-joined lingers in Teams.\n console.warn(\"[AcsMeeting] phase=join-native-failed\", {\n packageName,\n error: error instanceof Error ? error.message : String(error),\n })\n softapTraceFailure(\"acs_native_join_failed\", {\n packageName,\n generation,\n durationMs: Date.now() - joinStartedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n await native.leave().catch((leaveError) => {\n console.warn(\"[AcsMeeting] native leave after failed join also failed\", leaveError)\n softapTraceFailure(\"acs_native_leave_after_failed_join_failed\", {\n packageName,\n reason: leaveError instanceof Error ? leaveError.message : String(leaveError),\n })\n })\n await this.releaseHostState()\n throw error\n }\n this.watchPhoneNetwork(native)\n // Return audio is additive: the wearer is already in the meeting with camera and\n // mic. A playback failure must not reject the join — that would leave the miniapp\n // believing it never joined while native keeps the wearer in Teams.\n try {\n await this.ensurePcmPlayback(packageName)\n console.log(\"[AcsMeeting] phase=pcm-playback\", {streamId: this.pcmStreamId})\n } catch (error) {\n console.warn(\"[AcsMeeting] phase=pcm-playback-failed; continuing without return audio\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n return this.lastState\n }\n\n async leave(packageName: string): Promise<void> {\n if (this.owner && this.owner !== packageName) {\n // Not the owner, so this is a no-op rather than a leave. Said out loud because a miniapp\n // that thinks it left and a host that never hung up look identical from the miniapp's side.\n softapTrace(\"acs_native_leave_ignored\", {packageName, owner: this.owner})\n return\n }\n const native = getNative()\n const startedAt = Date.now()\n softapTrace(\"acs_native_leave\", {packageName, nativeLoaded: Boolean(native)})\n try {\n await native?.leave()\n softapTrace(\"acs_native_leave_ok\", {packageName, durationMs: Date.now() - startedAt})\n } catch (error) {\n softapTraceFailure(\"acs_native_leave_failed\", {\n packageName,\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n } finally {\n await this.releaseHostState()\n }\n }\n\n /**\n * Leave, and do not resolve until native reports its cleanup is finished.\n *\n * Android native's `leave()` queues the hang-up, the\n * agent disposal, and the network releases on its session executor and returns straight away, so\n * a caller that awaits it and then starts the next call is racing the previous one's teardown.\n *\n * Falls back to [leave] on builds that predate the signal and says so, rather than pretending to\n * a guarantee it cannot give.\n *\n * @param timeoutMs how long native may take before it reports the cleanup as stuck\n */\n async leaveAndAwait(packageName: string, timeoutMs = ACS_LEAVE_WAIT_MS): Promise<{completed: boolean; reason?: string}> {\n if (this.owner && this.owner !== packageName) {\n softapTrace(\"acs_native_leave_and_await_ignored\", {packageName, owner: this.owner})\n return {completed: true}\n }\n const native = getNative()\n if (!native?.leaveAndAwait) {\n // The fallback is the case the cleanup barrier was built for: this build's leave returns\n // before its own teardown has finished, so nothing downstream can treat \"left\" as \"idle\".\n softapTraceFailure(\"acs_native_leave_and_await_unsupported\", {\n packageName,\n nativeLoaded: Boolean(native),\n })\n await this.leave(packageName)\n return {completed: false, reason: \"unsupported\"}\n }\n const startedAt = Date.now()\n softapTrace(\"acs_native_leave_and_await\", {packageName, timeoutMs})\n try {\n const outcome = await native.leaveAndAwait({timeoutMs})\n softapTrace(\"acs_native_leave_and_await_ok\", {\n packageName,\n completed: outcome?.completed !== false,\n durationMs: Date.now() - startedAt,\n })\n return {completed: outcome?.completed !== false}\n } catch (error) {\n softapTraceFailure(\"acs_native_leave_and_await_failed\", {\n packageName,\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n } finally {\n await this.releaseHostState()\n }\n }\n\n /** Admit one guest without changing call ownership or audio state. */\n async admitParticipant(packageName: string, participantId: string): Promise<void> {\n if (this.owner !== packageName) throw new Error(\"This miniapp does not own the active meeting\")\n if (!participantId.trim()) throw new Error(\"A participant ID is required\")\n const native = getNative()\n if (!native?.admitParticipant) throw new Error(\"This Mentra App build does not support admitting guests\")\n const generation = this.callGeneration\n await native.admitParticipant(participantId)\n if (generation !== this.callGeneration) throw new Error(\"The meeting changed during admission\")\n }\n\n /**\n * End the Teams group call for everyone.\n *\n * Host state is released either way: native tears this device down whatever the hang-up did, so\n * holding the meeting slot open after a rejection would leave the miniapp unable to start another\n * call. The rejection still propagates — the caller has to be able to say \"you left, but the\n * meeting may still be active\" instead of claiming a clean end.\n */\n async endForEveryone(packageName: string): Promise<MeetingState> {\n if (this.owner && this.owner !== packageName) {\n throw new Error(\"This miniapp does not own the active meeting\")\n }\n const native = getNative()\n if (!native?.endForEveryone) {\n softapTraceFailure(\"acs_native_end_unsupported\", {packageName, nativeLoaded: Boolean(native)})\n throw new Error(\"Update the Mentra App to end a meeting for everyone\")\n }\n const startedAt = Date.now()\n softapTrace(\"acs_native_end\", {packageName})\n try {\n const state = await native.endForEveryone()\n console.log(\"[AcsMeeting] phase=end-for-everyone-ok\", {state: state.state})\n softapTrace(\"acs_native_end_ok\", {packageName, state: state.state, durationMs: Date.now() - startedAt})\n return state\n } catch (error) {\n // The meeting may still be live for the others; this device is out regardless. Logged as a\n // failure of the claim, not of the teardown.\n softapTraceFailure(\"acs_native_end_failed\", {\n packageName,\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n } finally {\n await this.releaseHostState()\n }\n }\n\n /** Whether the wearer may end this meeting for everyone, as ACS last reported it. */\n hangUpForEveryoneCapability(): MeetingCapability {\n return this.lastState.capabilities?.hangUpForEveryone ?? {allowed: null, reason: null}\n }\n\n /**\n * Drop everything the host set up around a session: the microphone uplink, the network watcher,\n * return audio, native listeners, ownership.\n *\n * Idempotent, because there are now several terminal paths into it and they overlap. A remote\n * hang-up arrives as a native `disconnected`, and the miniapp usually calls `leave` right after\n * seeing it; releasing the microphone pin twice would clear a pin the *next* call had already\n * taken. Every release also bumps the call generation, which is what stops a `mic_pcm` event\n * already queued on the JS thread from reaching a native session that is gone.\n */\n private async releaseHostState(): Promise<void> {\n if (this.hostStateReleased) return\n this.hostStateReleased = true\n this.callGeneration++\n // Before anything else: a caller parked on a frame that will now never arrive has to be\n // rejected, or a leave mid-join leaves the orchestrator waiting out its whole timeout.\n for (const settle of [...this.firstFrameWaiters]) settle(new Error(\"The meeting ended\"))\n this.firstFrameWaiters.clear()\n this.settleMediaLiveWaiters(false)\n this.mediaLiveWaiters.clear()\n this.stopGlassesMicUplink()\n this.unwatchPhoneNetwork()\n await this.stopPcm()\n this.unbindNative()\n this.scopedLostSub?.remove()\n this.scopedLostSub = null\n this.owner = null\n this.whepUrl = null\n this.videoSource = null\n this.ingestUrl = null\n this.lastMediaRestartAt = 0\n this.lastState = {state: \"idle\", muted: false}\n }\n\n /**\n * Start forwarding the glasses microphone into ACS for this call.\n *\n * This class is a sink: it never names a gain, a pin or a setting. It does take a semantic\n * voice_call lease first, because reading the glasses mic without one is what put this call on\n * the OS default of VAD-on — a speech gate that drops the wearer's uplink whenever the GX8002\n * disagrees, which during a call is most of the time the far end is talking. The lease is a\n * backstop: when the miniapp already holds one this simply merges with it, and micPolicy still\n * decides what voice_call means for the hardware.\n *\n * `generation` is captured by the listener so a frame that lands after this call ended is\n * dropped rather than pushed at a native session that has left the meeting.\n */\n private startGlassesMicUplink(generation: number): void {\n if (this.micTransport !== \"ble-lc3\") return\n const native = getNative()\n const push = native?.pushOutgoingPcm\n if (!native || !push) return\n this.micFramesForwarded = 0\n this.micFramesWindow = 0\n this.micDropsStale = 0\n this.micDropsNonGlasses = 0\n this.micGaps = 0\n this.micGapMsMax = 0\n this.lastGlassesFrameAt = Date.now()\n this.lastMicDropLogAt = 0\n this.lastMicUplinkLogAt = Date.now()\n this.micLevel.take()\n this.lastMicLevel = null\n try {\n this.acquireMicSession()\n this.startMicGateTelemetry()\n this.micUplinkActive = true\n this.micSub = BluetoothSdk.addListener(\"mic_pcm\", (event: {pcm?: ArrayBuffer; sampleRate?: number; source?: string}) => {\n if (generation !== this.callGeneration) {\n this.micDropsStale += 1\n this.logMicDrop(\"stale\", {generation, active: this.callGeneration})\n return\n }\n // The pin makes this unreachable in normal operation, which is exactly why it is checked:\n // a mic the SDK moved under us would otherwise put the phone's room into a Teams call\n // that reports the glasses.\n if (event.source !== GLASSES_MIC_SOURCE) {\n this.micDropsNonGlasses += 1\n this.logMicDrop(\"non-glasses\", {source: event.source})\n this.reportGlassesMicUnavailable(event.source)\n return\n }\n const pcm = event.pcm\n if (!pcm) return\n const now = Date.now()\n if (this.micFramesForwarded > 0) {\n const gapMs = now - this.lastGlassesFrameAt\n if (gapMs > MIC_GAP_WARN_MS) {\n this.micGaps += 1\n this.micGapMsMax = Math.max(this.micGapMsMax, gapMs)\n this.logMicDrop(\"gap\", {gapMs})\n }\n }\n this.lastGlassesFrameAt = now\n this.micFramesForwarded += 1\n this.micFramesWindow += 1\n this.micLevel.add(pcm)\n try {\n push.call(native, pcmToBase64(pcm), event.sampleRate ?? 16000, 1)\n } catch (error) {\n console.warn(\"[AcsMeeting] pushing glasses PCM to ACS failed\", error)\n }\n this.logMicUplink()\n })\n console.log(\"[AcsMeeting] phase=glasses-mic-uplink-start\", {generation, micTransport: this.micTransport})\n } catch (error) {\n // A host that cannot subscribe has no wearer audio at all, and that is worth saying loudly,\n // but it is not worth failing a call the wearer can still see and hear.\n console.error(\"[AcsMeeting] phase=glasses-mic-uplink-unavailable\", error)\n this.stopGlassesMicUplink()\n this.markMicTransportNone()\n }\n }\n\n /**\n * Stop reading the glasses microphone. Safe to call when this call never started.\n *\n * Only this call's own backstop lease is dropped. A lease the miniapp took is its to release,\n * and letting go of ours before that owner releases is what keeps a normal hang-up from looking\n * like the wearer's microphone disappearing.\n */\n private stopGlassesMicUplink(): void {\n this.micSub?.remove()\n this.micSub = null\n this.releaseMicSession()\n if (this.micUplinkActive) {\n this.micUplinkActive = false\n console.log(\"[AcsMeeting] phase=glasses-mic-uplink-stop\", {\n frames: this.micFramesForwarded,\n dropsStale: this.micDropsStale,\n dropsNonGlasses: this.micDropsNonGlasses,\n gaps: this.micGaps,\n gapMsMax: this.micGapMsMax,\n ...this.gateSummary(),\n })\n }\n this.stopMicGateTelemetry()\n this.micTransport = \"whip\"\n }\n\n /**\n * Watch what the glasses are actually running for the length of the call.\n *\n * Two different questions, both unanswerable from this side otherwise. `mic_tuning_state` is\n * the post-clamp reply, so it catches a profile the firmware rewrote rather than accepted.\n * `mic_rms` carries the Barrier's own verdict per frame, which is the only way to tell a gate\n * that is suppressing speaker leak from one that is suppressing the wearer.\n */\n private startMicGateTelemetry(): void {\n this.gateSamples = 0\n this.gateClosed = 0\n this.gateElevated = 0\n this.gateClosedElevated = 0\n this.gateRmsMax = 0\n\n try {\n this.micTuningSub = BluetoothSdk.addListener(\"mic_tuning_state\", (event: Record<string, unknown>) => {\n console.log(\"[AcsMeeting] phase=glasses-mic-tuning-applied\", event)\n })\n this.micRmsSub = BluetoothSdk.addListener(\n \"mic_rms\",\n (event: {rms?: number; gateOpen?: boolean; speakerElevated?: boolean}) => {\n this.gateSamples += 1\n if (event.gateOpen === false) this.gateClosed += 1\n if (event.speakerElevated) {\n this.gateElevated += 1\n if (event.gateOpen === false) this.gateClosedElevated += 1\n }\n if (typeof event.rms === \"number\" && event.rms > this.gateRmsMax) this.gateRmsMax = event.rms\n },\n )\n void Promise.resolve(BluetoothSdk.setMicRmsTelemetry?.(true))\n .then(() => {\n this.micRmsEnabled = true\n })\n .catch((error) => console.warn(\"[AcsMeeting] mic RMS telemetry unavailable\", error))\n void Promise.resolve(BluetoothSdk.requestMicTuningState?.()).catch(() => {})\n } catch (error) {\n console.warn(\"[AcsMeeting] mic gate telemetry unavailable\", error)\n }\n }\n\n private stopMicGateTelemetry(): void {\n this.micTuningSub?.remove()\n this.micTuningSub = null\n this.micRmsSub?.remove()\n this.micRmsSub = null\n if (!this.micRmsEnabled) return\n this.micRmsEnabled = false\n // Super Mode may have the readout open behind this call; it re-requests on focus.\n void Promise.resolve(BluetoothSdk.setMicRmsTelemetry?.(false)).catch(() => {})\n }\n\n /** Barrier's behaviour over the window, as percentages a listening test can be checked against. */\n private gateSummary(): Record<string, number> {\n if (this.gateSamples === 0) return {}\n const pct = (n: number, of: number) => (of === 0 ? 0 : Math.round((n / of) * 1000) / 10)\n return {\n gateSamples: this.gateSamples,\n gateClosedPct: pct(this.gateClosed, this.gateSamples),\n speakerElevatedPct: pct(this.gateElevated, this.gateSamples),\n // The number that matters: closed while the far end was quiet means the wearer was cut.\n gateClosedQuietPct: pct(this.gateClosed - this.gateClosedElevated, this.gateSamples - this.gateElevated),\n gateRmsMax: this.gateRmsMax,\n }\n }\n\n /**\n * Guarantee a voice_call session for as long as this call reads the glasses mic.\n *\n * The miniapp asking for one is the intended path; this covers the builds where it cannot,\n * because a bundled Call that predates MIC_ACQUIRE joins anyway rather than failing. Without\n * this the uplink runs under whatever the OS settings say, and the shipped default is VAD-on.\n */\n private acquireMicSession(): void {\n if (this.micSession) return\n try {\n this.micSession = micSessionManager.acquire({\n owner: `${ENGINE_OWNER_PREFIX}acs-uplink`,\n source: \"glasses\",\n useCase: \"voice_call\",\n })\n } catch (error) {\n // A source conflict means something else already owns the microphone. Forwarding whatever\n // it captures is still better than dropping the wearer from the call.\n console.warn(\"[AcsMeeting] glasses mic session unavailable\", error)\n }\n }\n\n private releaseMicSession(): void {\n const session = this.micSession\n if (!session) return\n this.micSession = null\n try {\n session.release()\n } catch (error) {\n console.warn(\"[AcsMeeting] releasing the glasses mic session failed\", error)\n }\n }\n\n /**\n * Report a call whose pinned microphone stopped delivering. There is deliberately no fallback:\n * the wearer agreed to be heard from the glasses, and quietly switching to the phone in the\n * middle of a meeting puts the room they are standing in on the call.\n */\n private reportGlassesMicUnavailable(source: string | undefined): void {\n if (Date.now() - this.lastGlassesFrameAt < GLASSES_MIC_GRACE_MS) return\n if (this.micTransport === \"none\") return\n console.error(\"[AcsMeeting] phase=glasses-mic-unavailable\", {source, dropsNonGlasses: this.micDropsNonGlasses})\n this.markMicTransportNone()\n }\n\n /**\n * Record that this call has no wearer audio path.\n *\n * The state has to carry it, not just the field: a call that reported `ble-lc3` and then failed\n * to start the uplink looks identical from the miniapp's side to one that is working, and the\n * wearer finds out by being asked to repeat themselves.\n */\n private markMicTransportNone(): void {\n this.micTransport = \"none\"\n this.lastState = {...this.lastState, micTransport: \"none\", error: GLASSES_MIC_UNAVAILABLE}\n if (this.owner) this.onState?.(this.owner, this.lastState)\n }\n\n private logMicUplink(): void {\n const now = Date.now()\n const elapsed = now - this.lastMicUplinkLogAt\n const sweep = getCallGainSweep()\n const interval = sweep.isActive() ? MIC_UPLINK_SWEEP_LOG_INTERVAL_MS : MIC_UPLINK_LOG_INTERVAL_MS\n if (elapsed < interval) return\n this.lastMicUplinkLogAt = now\n // Level, not just cadence: a 20 Hz stream of the noise floor and a 20 Hz stream of speech\n // have the same framesPerSecond. Quiet room on Mentra Live LC3 is meanAbs ≈30–60.\n const level = this.micLevel.take()\n const stats = pcm16WindowStats(level)\n this.lastMicLevel = {meanAbs: level.meanAbs, peak: level.peak}\n const gain = sweep.currentGain() ?? micStateCoordinator.getSessionMicTuning()?.gain ?? null\n if (sweep.isActive()) sweep.ingest(level)\n console.log(\"[AcsMeeting] phase=glasses-mic-uplink\", {\n framesPerSecond: Math.round((this.micFramesWindow * 1000) / elapsed),\n frames: this.micFramesForwarded,\n meanAbs: stats.meanAbs,\n peak: stats.peak,\n peakPct: stats.peakPct,\n clipped: stats.clipped,\n clipPct: stats.clipPct,\n nearClip: stats.nearClip,\n nearClipPct: stats.nearClipPct,\n gain,\n barrier: micStateCoordinator.getSessionLoudnessGate(),\n sweep: sweep.currentLabel(),\n dropsStale: this.micDropsStale,\n dropsNonGlasses: this.micDropsNonGlasses,\n gaps: this.micGaps,\n gapMsMax: this.micGapMsMax,\n ...this.gateSummary(),\n })\n this.micFramesWindow = 0\n }\n\n /** Level of the last uplink window, for tests and dev screens. `null` until a window closed. */\n lastGlassesMicLevel(): {meanAbs: number; peak: number} | null {\n return this.lastMicLevel\n }\n\n private logMicDrop(reason: string, extra: Record<string, unknown>): void {\n const now = Date.now()\n if (now - this.lastMicDropLogAt < 1000) return\n this.lastMicDropLogAt = now\n console.warn(\"[AcsMeeting] phase=glasses-mic-drop\", {\n reason,\n dropsStale: this.micDropsStale,\n dropsNonGlasses: this.micDropsNonGlasses,\n gaps: this.micGaps,\n ...extra,\n })\n }\n\n async setMuted(packageName: string, muted: boolean): Promise<MeetingState> {\n this.assertOwner(packageName)\n const native = getNative()\n if (!native) throw new Error(\"ACS meeting module is not available on this host\")\n const state = await native.setMuted(muted)\n this.lastState = {\n ...this.lastState,\n ...state,\n audioSourceReason: this.lastState.audioSourceReason,\n // Mute is an ACS-side gate. It does not change which microphone the call is using, and it\n // deliberately does not turn the glasses microphone off — see the mute chain in native.\n micTransport: this.micTransport,\n }\n return this.lastState\n }\n\n async updateVideoSource(packageName: string, whepUrl: string): Promise<void> {\n this.assertOwner(packageName)\n const native = getNative()\n if (!native) throw new Error(\"ACS meeting module is not available on this host\")\n if (this.videoSource?.type === \"softap\") {\n // The host owns the softap endpoint, so there is no URL for a caller to change. Failing is\n // better than accepting it and doing nothing.\n throw new Error(\"updateVideoSource is not applicable to a SoftAP call\")\n }\n this.whepUrl = whepUrl\n await native.updateVideoSource(whepUrl)\n }\n\n async readState(packageName: string): Promise<MeetingState> {\n if (this.owner && this.owner !== packageName) {\n return {state: \"idle\", muted: false}\n }\n const native = getNative()\n if (!native) return {state: \"idle\", muted: false}\n const state = await native.getState()\n this.lastState = {...state, micTransport: this.micTransport}\n return this.lastState\n }\n\n async leaveIfOwner(packageName: string): Promise<void> {\n if (this.owner === packageName) await this.leave(packageName)\n }\n\n private assertOwner(packageName: string): void {\n if (this.owner !== packageName) {\n throw new Error(\n this.owner ? \"This miniapp does not own the active meeting\" : \"No active meeting; call meeting.join first\",\n )\n }\n }\n\n private unbindNative(): void {\n this.subscriptions.forEach((sub) => sub.remove())\n this.subscriptions = []\n }\n\n private bindNative(native: NativeModule, packageName: string): void {\n this.unbindNative()\n // Captured at bind, checked on every event. `unbindNative` removes the listener, but an event\n // already dispatched onto the JS queue still runs — and this is the one path where that lands\n // as the *previous* call's `disconnected` ending the call the wearer just started. Every other\n // callback that can outlive a session (mic PCM, the in-flight join) is fenced the same way.\n const generation = this.callGeneration\n this.subscriptions = [\n native.addListener(\"onState\", (event) => {\n if (generation !== this.callGeneration) {\n softapTraceFailure(\"softap_stale_callback\", {\n source: \"acs_state\",\n generation,\n current: this.callGeneration,\n state: String(event.state ?? \"unknown\"),\n })\n return\n }\n const audioSafety = parseAudioSafety(event.audioSafety)\n if (audioSafety === \"unsafe\") {\n console.error(\"[AcsMeeting] phase=audio-unsafe\", {\n activeStream: event.activeStream,\n audioSource: event.audioSource,\n })\n }\n const participants = parseMeetingParticipants(event.participants)\n const mediaSource = parseMediaSource(event.mediaSource)\n const mediaSourceReason = typeof event.mediaSourceReason === \"string\" ? event.mediaSourceReason : undefined\n const callEndReason =\n Number.isInteger(event.endReason_code) && Number.isInteger(event.endReason_subcode)\n ? {code: event.endReason_code as number, subcode: event.endReason_subcode as number}\n : undefined\n const capabilities = parseMeetingCapabilities(event.capabilities)\n const endReason = parseMeetingEndReason(event as Record<string, unknown>)\n const state: MeetingState = {\n state: (event.state as MeetingPhase) ?? \"idle\",\n muted: Boolean(event.muted),\n error: event.error as string | undefined,\n meetingUrl: event.meetingUrl as string | undefined,\n provider: \"acs-teams\",\n audioSource: event.audioSource === \"phone\" ? \"phone\" : \"glasses\",\n audioSourceReason: this.lastState.audioSourceReason,\n activeStream: parseActiveStream(event.activeStream),\n audioSafety,\n micTransport: this.micTransport,\n ...(mediaSource ? {mediaSource} : {}),\n ...(mediaSourceReason ? {mediaSourceReason} : {}),\n ...(callEndReason ? {callEndReason} : {}),\n ...(participants ? {participants} : {}),\n ...(endReason ? {endReason} : {}),\n // Absent means unknown, so keep the last known verdict rather than clearing it.\n ...((capabilities ?? this.lastState.capabilities) ? {capabilities: capabilities ?? this.lastState.capabilities} : {}),\n }\n const previous = this.lastState.state\n this.lastState = state\n if (state.state !== previous) {\n // The host's own copy of the transition. Native already traces `acs_call_state` with\n // timings; this one survives a capture where the native trace is absent, and is the\n // line the miniapp's timeline is reconciled against.\n softapTrace(\"acs_state\", {\n state: state.state,\n previous,\n origin: this.callOrigin,\n mediaSource: state.mediaSource ?? \"unknown\",\n micTransport: state.micTransport ?? \"unknown\",\n })\n }\n console.log(\"[AcsMeeting] phase=native-state\", {\n state: state.state,\n muted: state.muted,\n error: state.error,\n audioSource: state.audioSource,\n activeStream: state.activeStream,\n audioSafety: state.audioSafety,\n mediaSource: state.mediaSource,\n mediaSourceReason: state.mediaSourceReason,\n callEndReason: state.callEndReason,\n micTransport: state.micTransport,\n participants: participants?.length,\n endReason: endReason ? `${endReason.code ?? \"?\"}/${endReason.subcode ?? \"?\"}` : undefined,\n })\n if (mediaSource === \"live\") this.liveEpoch = this.decodedMediaEpoch\n this.settleFirstFrameWaiters(mediaSource)\n this.onState?.(packageName, state)\n // A remote hang-up, an ACS error or a dropped call never goes through `leave`, so without\n // this the microphone pin, the PCM requirement and the `mic_pcm` listener would outlive the\n // meeting — and the next miniapp to start a call would inherit them.\n if (state.state === \"disconnected\" || state.state === \"error\") {\n void this.releaseHostState().catch((error) => {\n console.warn(\"[AcsMeeting] releasing host state after a terminal native state failed\", error)\n })\n }\n }),\n native.addListener(\"onIncomingPcm\", (event) => {\n const base64 = event.base64 as string | undefined\n if (!base64 || !this.owner) return\n // Serialize: native async calls may complete out of order, and PCM\n // chunks written out of order are audible as garbling.\n this.pcmWriteChain = this.pcmWriteChain\n .then(() => this.writeIncomingPcm(packageName, base64, event.sampleRate, event.channels))\n .catch(() => undefined)\n }),\n ]\n }\n\n /**\n * The WHEP PeerConnection does not survive the phone changing networks\n * (Wi-Fi↔cellular, or a different Wi-Fi): ICE fails and native parks the source\n * as `failed` while the ACS call itself reconnects on its own. Nudge native to\n * rebuild the subscription whenever the phone's network identity changes during\n * a live meeting. Native ignores the request when the source is healthy on the\n * same URL, so a spurious event costs nothing.\n */\n private watchPhoneNetwork(native: NativeModule): void {\n this.unwatchPhoneNetwork()\n const source = getPhoneNetwork()\n if (!source) return\n this.lastPhoneNetworkKey = null\n try {\n this.phoneNetworkUnsub = source.addEventListener((info) => {\n const key = `${info.type}:${info.isConnected === false ? \"offline\" : \"online\"}`\n const previous = this.lastPhoneNetworkKey\n this.lastPhoneNetworkKey = key\n // First callback is NetInfo replaying the current state, not a change.\n if (previous === null || previous === key) return\n if (info.isConnected === false) return\n void this.restartMediaSource(native, `phone network ${previous} → ${key}`)\n })\n } catch (error) {\n console.warn(\"[AcsMeeting] phone network watch unavailable\", error)\n this.phoneNetworkUnsub = null\n }\n }\n\n private unwatchPhoneNetwork(): void {\n this.phoneNetworkUnsub?.()\n this.phoneNetworkUnsub = null\n this.lastPhoneNetworkKey = null\n }\n\n private async restartMediaSource(native: NativeModule, reason: string): Promise<void> {\n const whepUrl = this.whepUrl\n const softap = this.videoSource?.type === \"softap\"\n // SoftAP media is bound to the scoped hotspot, not the phone's default route. Joining that\n // hotspot is what *causes* NetInfo to flap `none:offline → cellular:online` — the default\n // route looks gone for a beat, then cellular comes back. Rebuilding the WHIP listener on\n // that flap changes the ingest port after the glasses already have the old URL, and their\n // POST hits a tombstone (HTTP 410). A real hotspot loss is `onScopedNetworkLost`, not this\n // default-network watch. WHEP still needs the rebuild: that path rides the default route.\n if (softap) return\n if (!this.owner || !MEDIA_ACTIVE_PHASES.has(this.lastState.state)) return\n if (!whepUrl) return\n const now = Date.now()\n if (now - this.lastMediaRestartAt < MEDIA_RESTART_MIN_INTERVAL_MS) return\n this.lastMediaRestartAt = now\n console.log(\"[AcsMeeting] phase=media-restart\", {reason, mediaSource: this.lastState.mediaSource})\n try {\n // A same-URL updateVideoSource is a no-op while native still believes the\n // peer is healthy; after a network switch that belief is exactly what is wrong.\n if (native.restartVideoSource) await native.restartVideoSource()\n else if (whepUrl) await native.updateVideoSource(whepUrl)\n else console.warn(\"[AcsMeeting] softap restart needs a native restartVideoSource\", {reason})\n } catch (error) {\n console.warn(\"[AcsMeeting] media restart failed\", {reason, error})\n }\n }\n\n /**\n * Native normalizes to 16 kHz mono, so this is normally a straight write.\n * If the format ever differs, reopen the player to match rather than play\n * the bytes at the wrong rate (that is what slows and deepens the audio).\n */\n private async writeIncomingPcm(\n packageName: string,\n base64: string,\n rawRate: unknown,\n rawChannels: unknown,\n ): Promise<void> {\n const sampleRate = Number(rawRate) || 16000\n const channels = Number(rawChannels) || 1\n if (!PCM_SAMPLE_RATES.has(sampleRate) || channels !== 1) {\n console.warn(\"[AcsMeeting] incoming PCM format unsupported; dropping chunk\", {sampleRate, channels})\n return\n }\n if (this.pcmFormat && (this.pcmFormat.sampleRate !== sampleRate || this.pcmFormat.channels !== channels)) {\n if (!this.pcmReopen) {\n console.warn(\"[AcsMeeting] incoming PCM format changed; reopening player\", {\n from: this.pcmFormat,\n to: {sampleRate, channels},\n })\n this.pcmReopen = this.stopPcm()\n .then(() => this.ensurePcmPlayback(packageName, sampleRate, channels))\n .finally(() => {\n this.pcmReopen = null\n })\n }\n await this.pcmReopen\n } else if (!this.pcmStreamId) {\n await this.ensurePcmPlayback(packageName, sampleRate, channels)\n }\n const streamId = this.pcmStreamId\n if (!streamId) return\n try {\n const result = await audioPlaybackService.writeStreamChunk(streamId, base64)\n const bufferedMs = result?.bufferedMs\n if (typeof bufferedMs === \"number\" && bufferedMs > PCM_BACKLOG_WARN_MS) {\n const now = Date.now()\n if (now - this.lastBacklogWarnAt > 5000) {\n this.lastBacklogWarnAt = now\n console.warn(\"[AcsMeeting] incoming PCM backlog high (downlink playback, not glasses mic)\", {bufferedMs})\n }\n }\n } catch (error) {\n console.warn(\"[AcsMeeting] incoming PCM write failed\", error)\n }\n }\n\n private async ensurePcmPlayback(packageName: string, sampleRate = 16000, channels = 1): Promise<void> {\n if (this.pcmStreamId) return\n const streamId = `acs-in-${packageName}-${Date.now()}`\n await audioPlaybackService.openStream({\n streamId,\n appId: packageName,\n sampleRate,\n channels,\n stopOtherAudio: true,\n jitterMs: PCM_JITTER_MS,\n onEnded: () => {\n if (this.pcmStreamId === streamId) {\n this.pcmStreamId = null\n this.pcmFormat = null\n }\n },\n })\n this.pcmStreamId = streamId\n this.pcmFormat = {sampleRate, channels}\n }\n\n private async stopPcm(): Promise<void> {\n const streamId = this.pcmStreamId\n this.pcmStreamId = null\n this.pcmFormat = null\n if (!streamId) return\n await audioPlaybackService.abortStream(streamId).catch(() => undefined)\n }\n}\n\nconst acsMeetingService = new AcsMeetingService()\nexport default acsMeetingService\n"]}
|
|
1
|
+
{"version":3,"file":"AcsMeetingService.js","sourceRoot":"","sources":["../../src/services/AcsMeetingService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-side ACS meeting controller. One active meeting. Native module owns\n * WHEP + ACS; this service maps that into miniapp envelopes and pipes\n * incoming PCM into AudioPlaybackService (A2DP / PcmStreamPlayer).\n */\n\nimport {Platform} from \"react-native\"\n\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\n\nimport audioPlaybackService from \"./AudioPlaybackService\"\nimport {getCallGainSweep} from \"./CallGainSweep\"\nimport micStateCoordinator from \"./MicStateCoordinator\"\nimport micSessionManager, {type MicSession} from \"./MicSessionManager\"\nimport {ENGINE_OWNER_PREFIX} from \"./micPolicy\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\nimport {Pcm16LevelMeter, pcm16WindowStats} from \"../utils/pcm16\"\nimport {pcmToBase64} from \"../utils/pcmToBase64\"\nimport {softapTrace, softapTraceFailure, softapTraceId} from \"../utils/softapTrace\"\nimport {ACS_CALL_MIC, type AcsAudioSource, type ResolvedAudioSource, type SourceReason} from \"./acsAudioSource\"\nimport type {SoftapProgress} from \"./SoftapCallTransport\"\n\nexport {ACS_CALL_MIC}\nexport {pcmToBase64}\nexport type {ResolvedAudioSource, SourceReason}\n\ntype MeetingPhase = \"idle\" | \"connecting\" | \"lobby\" | \"connected\" | \"disconnected\" | \"error\"\n\nexport type AudioSafety = \"safe\" | \"degraded\" | \"unsafe\"\nexport type ActiveStream = \"none\" | \"virtual\" | \"local\"\n/**\n * Health of the glasses WHEP subscription that feeds the call. `failed` means ICE\n * dropped or the WHEP endpoint went away (glasses stopped publishing, phone changed\n * networks); the ACS call itself may still be `connected` with a frozen last frame.\n */\nexport type MediaSourceState = \"idle\" | \"connecting\" | \"live\" | \"failed\"\n\n/**\n * How the wearer's voice is reaching ACS.\n *\n * `ble-lc3` is the glasses microphone over Bluetooth, decoded on the phone and pushed into the ACS\n * raw outgoing stream. `whip` is the glasses microphone on the WebRTC track they publish (SoftAP or\n * Cloudflare). `phone` is the phone's own microphone. `none` means the source we committed to went\n * away mid-call, which is a reportable failure rather than a reason to open a different microphone.\n */\nexport type MicTransport = \"ble-lc3\" | \"whip\" | \"phone\" | \"none\"\n\n/** Error surfaced when the pinned glasses microphone stops producing audio during a call. */\nexport const GLASSES_MIC_UNAVAILABLE = \"GLASSES_MIC_UNAVAILABLE\"\n\nexport type MeetingParticipantState = \"idle\" | \"connecting\" | \"connected\" | \"lobby\" | \"hold\" | \"disconnected\"\n\nexport interface MeetingParticipant {\n id: string\n displayName: string | null\n state: MeetingParticipantState\n isMuted: boolean\n isSpeaking: boolean\n}\n\n/**\n * One runtime participant capability.\n *\n * `allowed` is nullable because \"denied\" and \"not known yet\" are different facts. ACS delivers\n * capabilities asynchronously, so every call is briefly unknown, and collapsing that into `false`\n * would hide controls on calls that do in fact permit them.\n */\nexport interface MeetingCapability {\n allowed: boolean | null\n reason: string | null\n}\n\nexport interface MeetingCapabilities {\n /** Whether this participant may end the Teams group call for everyone. Presenters only. */\n hangUpForEveryone: MeetingCapability\n manageLobby?: MeetingCapability\n}\n\nexport function parseMeetingCapabilities(raw: unknown): MeetingCapabilities | undefined {\n if (!raw || typeof raw !== \"object\") return undefined\n const value = (raw as Record<string, unknown>).hangUpForEveryone\n if (!value || typeof value !== \"object\") return undefined\n const capability = value as Record<string, unknown>\n const rawLobby = (raw as Record<string, unknown>).manageLobby\n const lobby = rawLobby && typeof rawLobby === \"object\" ? rawLobby as Record<string, unknown> : undefined\n return {\n ...(lobby ? {manageLobby: {\n allowed: typeof lobby.allowed === \"boolean\" ? lobby.allowed : null,\n reason: typeof lobby.reason === \"string\" && lobby.reason ? lobby.reason : null,\n }} : {}),\n hangUpForEveryone: {\n allowed: typeof capability.allowed === \"boolean\" ? capability.allowed : null,\n reason: typeof capability.reason === \"string\" && capability.reason ? capability.reason : null,\n },\n }\n}\n\n/**\n * Read the ACS `CallEndReason` off a native state event.\n *\n * Native flattens it into `endReason_code` / `endReason_subcode` / `endReason_message` rather than\n * a nested object, because the Expo bridge drops nested nulls. Anything non-numeric is discarded:\n * a code that arrived as a string would compare unequal to every entry in the lookup tables and\n * classify a known failure as unknown, which is worse than having no code at all.\n */\nexport function parseMeetingEndReason(event: Record<string, unknown>): MeetingEndReason | undefined {\n const num = (value: unknown): number | undefined => (typeof value === \"number\" && Number.isFinite(value) ? value : undefined)\n const code = num(event.endReason_code)\n const subcode = num(event.endReason_subcode)\n const message = typeof event.endReason_message === \"string\" ? event.endReason_message : undefined\n if (code === undefined && subcode === undefined && !message) return undefined\n return {...(code !== undefined ? {code} : {}), ...(subcode !== undefined ? {subcode} : {}), ...(message ? {message} : {})}\n}\n\nexport interface MeetingState {\n state: MeetingPhase\n muted: boolean\n error?: string\n meetingUrl?: string\n provider?: \"acs-teams\"\n audioSource?: \"glasses\" | \"phone\"\n audioSourceReason?: SourceReason\n activeStream?: ActiveStream\n audioSafety?: AudioSafety\n mediaSource?: MediaSourceState\n mediaSourceReason?: string\n callEndReason?: {code: number; subcode: number}\n participants?: MeetingParticipant[]\n /** Runtime capabilities. Omitted by natives that predate them; read that as unknown. */\n capabilities?: MeetingCapabilities\n /** Which microphone path is carrying the wearer's voice, decided at join time. */\n micTransport?: MicTransport\n /**\n * SoftAP join checklist, attached only to the state events the SoftAP orchestrator emits while\n * it walks hotspot → scoped join → ACS join → publish → live. Native ACS events never carry it,\n * so a consumer keeps the last one it saw rather than treating its absence as a reset.\n */\n softap?: SoftapProgress\n /**\n * ACS `CallEndReason`, forwarded numerically.\n *\n * It is the only machine-readable statement of *why* a join failed, and a miniapp cannot tell a\n * dead meeting link from a dropped network any other way — the human message is localised and\n * reworded between SDK releases, so matching on it would turn an outage into \"your link is\n * broken\" the first time Microsoft rephrases a sentence.\n */\n endReason?: MeetingEndReason\n}\n\n/** Numeric ACS `CallEndReason`. `message` is for logs and bug reports only, never for branching. */\nexport interface MeetingEndReason {\n code?: number\n subcode?: number\n message?: string\n}\n\n/**\n * The call microphone is [ACS_CALL_MIC], and `preferred_mic` governs MentraOS STT capture rather\n * than this call.\n *\n * `\"glasses\"` selects the wearer's own microphone. Which *transport* carries it is a separate\n * decision made per call by [glassesLc3UplinkSupported]: BLE LC3 into the ACS raw outgoing stream\n * where the host and native both support it, otherwise the glasses' published WebRTC audio track.\n * `\"phone\"` selects the phone's microphone via `PhoneMicCapturer`; do not route it through ACS\n * `LocalOutgoingAudioStream`, because that hands ACS the audio route\n * (MODE_IN_COMMUNICATION + forced speaker) and opens an echo loop.\n */\nexport function resolveAcsAudioSource(): ResolvedAudioSource {\n return {source: ACS_CALL_MIC, reason: \"explicit\"}\n}\n\n/**\n * Whether this call can take the wearer's voice off the glasses over BLE LC3.\n *\n * Every term is a hard requirement, and the answer has to be known *before* the glasses are told\n * what to publish — deciding afterwards is how a call ends up with either two copies of the wearer\n * or none. A host whose native module has no `pushOutgoingPcm` keeps the WHIP audio track it has\n * always used rather than silently joining a meeting nobody can be heard in.\n *\n * SoftAP takes BLE LC3 and publishes WHIP video only (`captureAudio=false`), so the glasses SoC\n * microphone is never opened for a call.\n *\n * This was switched off once on a misread: a soak logged `P4 pcm meanAbs` 8–39 and called it\n * digital silence. It was the room. The same LC3 path measured on the bench sits at `meanAbs`\n * ≈30–60 / `peak` ≈80–100 in a quiet room with nobody talking, and that soak had already\n * published with `captureAudio=false`, so the SoC mic was not the thief either. The uplink now\n * logs its own `meanAbs`/`peak` every window ([logMicUplink]) so the next soak reads the level,\n * not the frame rate. Disable only with a level log showing the floor *while the wearer talks*.\n */\nconst SOFTAP_BLE_LC3_UPLINK = true\n/**\n * How long native may take to finish a leave before it reports the cleanup as stuck.\n *\n * Generous on purpose: this is a diagnostic ceiling on a hang-up plus an agent disposal, not a\n * readiness deadline. The caller treats a timeout as \"cleanup failed\", never as \"safe to restart\".\n */\nconst ACS_LEAVE_WAIT_MS = 20_000\n/**\n * SoftAP video (camera → H.264 → WHIP → WHEP → ACS) is slower than BLE LC3.\n * Hold glasses PCM this long so the talk track does not lead the picture.\n * Set from SoftAP+LC3 clap correlator (2026-09-10): leads 70/201/173/300/142 ms,\n * median 173, rounded to 170. `AVSYNC clap audioLeadMs` is still the re-cal.\n */\nexport const SOFTAP_LC3_AUDIO_DELAY_MS = 170\nlet softapBleLc3UplinkForTests: boolean | null = null\n\nexport function glassesLc3UplinkSupported(args: {\n videoSource: AcsVideoSource\n audioSource: AcsAudioSource\n hasPushOutgoingPcm: boolean\n platform: string\n /** Somebody holds a glasses microphone session through MicSessionManager. */\n glassesSession: boolean\n}): boolean {\n if (!(softapBleLc3UplinkForTests ?? SOFTAP_BLE_LC3_UPLINK)) return false\n // The microphone belongs to whoever leased it. Without a lease nothing has pinned the glasses\n // or claimed raw PCM, so this call has no wearer audio to read off them.\n if (!args.glassesSession) return false\n // iOS has no `setMicSourcePin` yet, so it cannot promise the phone microphone stays shut.\n if (args.platform !== \"android\") return false\n // WHEP audio comes back from Cloudflare already mixed into the subscribed track; there is no\n // captureAudio flag on that path to turn off.\n if (args.videoSource.type !== \"softap\") return false\n if (args.audioSource !== \"glasses\") return false\n return args.hasPushOutgoingPcm\n}\n\nconst PARTICIPANT_STATES = new Set<MeetingParticipantState>([\n \"idle\",\n \"connecting\",\n \"connected\",\n \"lobby\",\n \"hold\",\n \"disconnected\",\n])\n\nexport function parseMeetingParticipants(raw: unknown): MeetingParticipant[] | undefined {\n if (!Array.isArray(raw)) return undefined\n const result: MeetingParticipant[] = []\n for (const entry of raw) {\n if (!entry || typeof entry !== \"object\") continue\n const value = entry as Record<string, unknown>\n if (typeof value.id !== \"string\" || !value.id) continue\n const state = PARTICIPANT_STATES.has(value.state as MeetingParticipantState)\n ? (value.state as MeetingParticipantState)\n : \"idle\"\n result.push({\n id: value.id,\n displayName: typeof value.displayName === \"string\" && value.displayName ? value.displayName : null,\n state,\n isMuted: Boolean(value.isMuted),\n isSpeaking: Boolean(value.isSpeaking),\n })\n }\n return result\n}\n\nexport type AcsOutgoingVideo = {\n width: number\n height: number\n fps: number\n maxBitrateBps: number\n}\n\n/** ACS VirtualOutgoingVideoStream documented 16:9 sizes. P540 is 960×540, not 540×960. */\nconst ACS_VIRTUAL_CAMERA_SIZES = new Set([\"1280x720\", \"960x540\", \"858x480\"])\n\nexport function parseAcsOutgoingVideo(raw: unknown): AcsOutgoingVideo | undefined {\n if (raw == null) return undefined\n if (typeof raw !== \"object\") throw new Error(\"video must be an object\")\n const value = raw as Record<string, unknown>\n const width = Number(value.width)\n const height = Number(value.height)\n const fps = Number(value.fps)\n const maxBitrateBps = Number(value.maxBitrateBps)\n if (![width, height, fps, maxBitrateBps].every(Number.isFinite)) {\n throw new Error(\"video requires width, height, fps, and maxBitrateBps\")\n }\n if (!ACS_VIRTUAL_CAMERA_SIZES.has(`${width}x${height}`) || fps < 1 || fps > 30 || maxBitrateBps <= 0) {\n throw new Error(`unsupported ACS video ${width}x${height}@${fps}`)\n }\n return {width, height, fps, maxBitrateBps}\n}\n\n/**\n * Where the glasses video comes from.\n *\n * A union rather than a nullable URL because the two transports need different inputs: WHEP is\n * given a URL, while SoftAP produces one only after the host binds a local listener. Collapsing\n * them into `whepUrl?: string` is what lets an empty string reach the subscriber and fail seconds\n * later as an opaque HTTP error.\n */\nexport type AcsVideoSource =\n | {type: \"whep\"; url: string}\n | {type: \"softap\"; ssid?: string; passphrase?: string; bindAddress?: string}\n\n/**\n * Validates a `videoSource` from a miniapp.\n *\n * Throws rather than defaulting to WHEP. A miniapp that asks for SoftAP and silently gets a\n * Cloudflare call — or vice versa — is a bug that shows up as unexplained latency or a black tile,\n * not as an error anyone can act on.\n */\nexport function parseAcsVideoSource(raw: unknown): AcsVideoSource {\n if (raw == null || typeof raw !== \"object\") {\n throw new Error(`videoSource must be {type: \"whep\", url} or {type: \"softap\"}`)\n }\n const value = raw as Record<string, unknown>\n\n if (value.type === \"whep\") {\n const url = typeof value.url === \"string\" ? value.url.trim() : \"\"\n if (!url) throw new Error(\"videoSource.url is required for a WHEP source\")\n return {type: \"whep\", url}\n }\n\n if (value.type === \"softap\") {\n const ssid = typeof value.ssid === \"string\" ? value.ssid.trim() : \"\"\n const passphrase = typeof value.passphrase === \"string\" ? value.passphrase : \"\"\n // Half a credential pair would otherwise present as a failed hotspot join much later.\n if (Boolean(ssid) !== Boolean(passphrase)) {\n throw new Error(\"videoSource.ssid and videoSource.passphrase must be provided together\")\n }\n return ssid ? {type: \"softap\", ssid, passphrase} : {type: \"softap\"}\n }\n\n throw new Error(`unsupported videoSource.type: ${String(value.type)}`)\n}\n\n/**\n * The app's default network after a hotspot join.\n *\n * `usable` is the only field to branch on; the rest is for the note the wearer sees and the trace.\n * A held cellular request brings the radio up but does not promise the default route has switched\n * or validated, so this is asked separately rather than inferred from the hold.\n */\nexport interface DefaultNetworkStatus {\n transport: string\n validated: boolean\n present: boolean\n usable: boolean\n detail: string\n}\n\n/**\n * Which path the wearer took into the call.\n *\n * Diagnostic only — nothing behaves differently — but it is carried all the way to the native\n * traces because the open question about video quality is exactly \"do these two differ\", and a\n * log that cannot separate them cannot answer it.\n */\nexport type AcsCallOrigin = \"created\" | \"joined\" | \"unknown\"\n\nexport function parseAcsCallOrigin(value: unknown): AcsCallOrigin {\n return value === \"created\" || value === \"joined\" ? value : \"unknown\"\n}\n\ntype NativeModule = {\n prepareAgent?(options: {token: string; displayName?: string}): Promise<MeetingState>\n join(options: {\n meetingUrl: string\n token: string\n /** Legacy field, still sent for whep so an older native keeps working. */\n whepUrl: string\n videoSource: AcsVideoSource\n displayName?: string\n dumpPcmWav?: boolean\n audioSource?: \"glasses\" | \"phone\"\n audioDelayMs?: number\n video?: AcsOutgoingVideo\n origin?: AcsCallOrigin\n }): Promise<MeetingState & {ingestUrl?: string}>\n leave(): Promise<void>\n /**\n * Leave, and resolve only once the hang-up, the agent disposal, and the network releases have\n * actually finished.\n *\n * [leave] queues its work on the session executor and returns immediately, so awaiting it proves\n * nothing about cleanup — which is what let a fast Stop/Start start a second call on top of the\n * first one's teardown. Absent on natives that predate the signal.\n */\n leaveAndAwait?(options: {timeoutMs: number}): Promise<{completed: boolean}>\n /**\n * Wait for the SoftAP WHIP listener's port. `closed: false` means it is still held.\n *\n * Separate from [leaveAndAwait] because the listener outlives the ACS teardown on purpose: it\n * answers `410` for a few seconds so an in-flight request from the glasses gets a status rather\n * than a reset. Absent on natives that predate the barrier.\n */\n awaitIngestClosed?(options: {timeoutMs: number}): Promise<{closed: boolean}>\n /** Drop the retiring WHIP listener now, skipping its grace period. */\n forceCloseIngest?(): Promise<void>\n /**\n * End the group call for everyone, then tear this device down. Rejects when the capability is\n * denied or ACS refuses — and has still left the call. Absent on natives that predate End.\n */\n endForEveryone?(): Promise<MeetingState>\n admitParticipant?(participantId: string): Promise<void>\n setMuted(muted: boolean): Promise<MeetingState>\n setAudioSource(source: \"glasses\" | \"phone\"): Promise<MeetingState>\n updateVideoSource(whepUrl: string): Promise<void>\n /** Force a WHEP rebuild on the current URL. Absent on natives that predate it. */\n restartVideoSource?(): Promise<void>\n /**\n * SoftAP: destroy the current ingest listener and bind a new one. Resolves with\n * the new URL. Absent on natives that predate rebind; disabled natives reject.\n */\n rebindSoftApIngest?(): Promise<string>\n /**\n * Join the glasses hotspot as a scoped, internet-less network; resolves with this phone's\n * address on it. Absent on natives that predate SoftAP.\n */\n joinScopedNetwork?(ssid: string, passphrase: string): Promise<string>\n joinScopedNetworkWithGateway?(ssid: string, passphrase: string, gateway: string): Promise<string>\n /** Is this phone's Wi-Fi radio on? Absent on natives that predate the preflight. */\n isWifiEnabled?(): Promise<boolean>\n beginTrace?(traceId: string): Promise<void>\n leaveScopedNetwork?(): Promise<void>\n cancelScopedNetworkJoin?(): Promise<void>\n awaitDefaultNetworkAfterHotspot?(): Promise<DefaultNetworkStatus>\n /**\n * TCP-probe the hotspot gateway over the scoped network. Absent on natives that predate it.\n * `detail` is a one-line human summary (address, port, latency or the failure).\n */\n probeScopedGateway?(): Promise<{reachable: boolean; detail: string}>\n /** The joined hotspot: `prefix` is what the media path must stay inside. */\n scopedNetworkInfo?(): Promise<{available: boolean; localIpv4: string | null; prefix: string | null}>\n /**\n * Wait for the app's default network to be validated, after the hotspot join changed it.\n * Absent on natives that predate the cellular transition handling.\n */\n awaitValidatedDefaultNetwork?(): Promise<DefaultNetworkStatus>\n getState(): Promise<MeetingState>\n /**\n * Hand one chunk of already-decoded microphone PCM to the ACS uplink. Synchronous on purpose:\n * this runs ~100×/s and a promise per chunk would cost more than the copy does.\n *\n * Absent on natives that predate the BLE LC3 uplink, which is exactly what\n * [glassesLc3UplinkSupported] tests for.\n */\n pushOutgoingPcm?(base64: string, sampleRate: number, channels: number): void\n addListener(event: string, listener: (event: Record<string, unknown>) => void): {remove: () => void}\n}\n\nlet nativeModule: NativeModule | null | undefined\n\nfunction getNative(): NativeModule | null {\n if (nativeModule !== undefined) return nativeModule\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n nativeModule = require(\"@mentra/acs-meeting\").default as NativeModule\n } catch {\n nativeModule = null\n }\n return nativeModule\n}\n\n/** Test seam: skip the native require and inject a fake ACS module. */\nexport function setAcsMeetingNativeForTests(mod: NativeModule | null | undefined): void {\n nativeModule = mod\n}\n\n/** Test seam: exercise the BLE LC3 path without flipping the production kill switch. */\nexport function setSoftapBleLc3UplinkForTests(enabled: boolean | null): void {\n softapBleLc3UplinkForTests = enabled\n}\n\n/**\n * Phone connectivity feed. Only the subset of `@react-native-community/netinfo`\n * this service needs, so tests can inject a fake and hosts without the package\n * (or a bare test runtime) degrade to \"no phone-network awareness\" instead of\n * failing to load the meeting service.\n */\nexport type PhoneNetworkInfo = {type: string; isConnected: boolean | null}\ntype PhoneNetworkSource = {\n addEventListener(listener: (state: PhoneNetworkInfo) => void): () => void\n}\n\nlet phoneNetwork: PhoneNetworkSource | null | undefined\n\nfunction getPhoneNetwork(): PhoneNetworkSource | null {\n if (phoneNetwork !== undefined) return phoneNetwork\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const netInfo = require(\"@react-native-community/netinfo\") as {default?: PhoneNetworkSource} & PhoneNetworkSource\n phoneNetwork = netInfo.default ?? netInfo\n } catch {\n phoneNetwork = null\n }\n return phoneNetwork\n}\n\n/** Test seam: inject a fake phone-network feed (or `null` to disable it). */\nexport function setAcsMeetingPhoneNetworkForTests(source: PhoneNetworkSource | null | undefined): void {\n phoneNetwork = source\n}\n\nfunction parseActiveStream(value: unknown): ActiveStream | undefined {\n if (value === \"none\" || value === \"virtual\" || value === \"local\") return value\n return undefined\n}\n\nfunction parseAudioSafety(value: unknown): AudioSafety | undefined {\n if (value === \"safe\" || value === \"degraded\" || value === \"unsafe\") return value\n return undefined\n}\n\nfunction parseMediaSource(value: unknown): MediaSourceState | undefined {\n if (value === \"idle\" || value === \"connecting\" || value === \"live\" || value === \"failed\") return value\n return undefined\n}\n\n/** Meeting phases during which the WHEP feed should be alive and is worth restarting. */\nconst MEDIA_ACTIVE_PHASES = new Set<MeetingPhase>([\"connecting\", \"lobby\", \"connected\"])\n/** Floor between WHEP restarts we trigger from the host, so a flapping network cannot thrash native. */\nconst MEDIA_RESTART_MIN_INTERVAL_MS = 3000\n\n/** Formats the native PcmStreamPlayer accepts (mono only). */\nconst PCM_SAMPLE_RATES = new Set([16000, 24000, 48000])\n\n/**\n * Playout headroom for the far end's voice.\n *\n * The native player defaults to half a second, which is right for a miniapp clip and wrong here:\n * a streaming track sits at its buffer size, so that default is 500ms of delay before the wearer\n * hears anyone, enough that both sides talk over each other. This trades cushion for immediacy —\n * still several BLE playout beats, but a conversation instead of a broadcast.\n */\nconst PCM_JITTER_MS = 120\n/**\n * Above this the backlog is real congestion rather than the configured cushion.\n *\n * Has to stay clear of [PCM_JITTER_MS], because the reported backlog *includes* the track's own\n * buffer and so never falls below it. A threshold at or under the cushion logs once per interval\n * for the whole call and says nothing.\n */\nconst PCM_BACKLOG_WARN_MS = PCM_JITTER_MS + 400\n\n/** The Bluetooth SDK mic identifier the call pins itself to. */\nconst GLASSES_MIC_SOURCE = \"glasses\"\n/**\n * How long the glasses may produce no PCM before the call reports its microphone gone.\n *\n * The pin makes a phone-mic fallback impossible, so the only honest response to a source that\n * stopped is to say so. One second is several BLE mic-beats: long enough that a reconnect blip\n * does not raise an error, short enough that the wearer is not talking into nothing for long.\n */\nconst GLASSES_MIC_GRACE_MS = 1000\n/** Cadence of the uplink health line, matching the native P8 ladder. */\nconst MIC_UPLINK_LOG_INTERVAL_MS = 5000\n/** During a gain sweep, one-second windows so each 25 s phase has enough speech samples. */\nconst MIC_UPLINK_SWEEP_LOG_INTERVAL_MS = 1000\n/** A 50 ms LC3 frame arriving more than this late is a missed beat, not jitter. */\nconst MIC_GAP_WARN_MS = 90\n\nclass AcsMeetingService {\n private owner: string | null = null\n private pcmStreamId: string | null = null\n private pcmFormat: {sampleRate: number; channels: number} | null = null\n private pcmReopen: Promise<void> | null = null\n private pcmWriteChain: Promise<void> = Promise.resolve()\n private lastBacklogWarnAt = 0\n private subscriptions: Array<{remove: () => void}> = []\n private lastState: MeetingState = {state: \"idle\", muted: false}\n private onState: ((packageName: string, state: MeetingState) => void) | null = null\n /** WHEP URL native is (or should be) subscribed to; what a host-triggered restart re-feeds. */\n private whepUrl: string | null = null\n /** Transport for the active call, so recovery picks the right repair. */\n private videoSource: AcsVideoSource | null = null\n /**\n * SoftAP only: the URL the glasses must publish to. An output of the join rather than an input,\n * because it is not known until native has bound a listener and been given a port.\n */\n private ingestUrl: string | null = null\n private phoneNetworkUnsub: (() => void) | null = null\n private lastPhoneNetworkKey: string | null = null\n private lastMediaRestartAt = 0\n /** Callers parked in [waitForFirstFrame], woken by the next `mediaSource` verdict. */\n private readonly firstFrameWaiters = new Set<(error?: Error) => void>()\n /**\n * Bumped by [invalidateDecodedMedia]. A `live` verdict only counts for the wait that\n * started after that bump if [liveEpoch] matches.\n */\n private decodedMediaEpoch = 0\n /** [decodedMediaEpoch] at the moment the phone last reported `mediaSource: live`. */\n private liveEpoch = -1\n /** Mid-call republish waiters: live resolves true, leave/timeout resolves false. Failed is ignored. */\n private readonly mediaLiveWaiters = new Set<(live: boolean) => void>()\n private scopedLostSub: {remove: () => void} | null = null\n private readonly scopedLostListeners = new Set<(error: {code: string; message: string}) => void>()\n /**\n * Set before the scoped network is released, so the loss we are about to cause is not reported as\n * one that happened to us. Android emits `onLost` for a deliberate release, and a naive wiring\n * turns every successful Leave and End into a mid-call network error.\n */\n private scopedTerminating = false\n /**\n * Bumped by every join and every release, and captured by everything that can outlive a call:\n * the `mic_pcm` listener and the in-flight `native.join`.\n *\n * A leave during a slow join is the case this exists for. Without it the join resolves into a\n * torn-down host, subscribes a microphone listener nobody will ever unsubscribe, and pushes the\n * wearer's voice at a native session that has already left the meeting.\n */\n private callGeneration = 0\n /** Stamped on the host-side state traces so they can be grouped the same way the native ones are. */\n private callOrigin: AcsCallOrigin = \"unknown\"\n private micTransport: MicTransport = \"whip\"\n private micSub: {remove: () => void} | null = null\n /** Backstop lease, held only while this call is actually reading the glasses mic. */\n private micSession: MicSession | null = null\n private micTuningSub: {remove: () => void} | null = null\n private micRmsSub: {remove: () => void} | null = null\n /** Only turn telemetry off again if this call is what turned it on. */\n private micRmsEnabled = false\n private gateSamples = 0\n private gateClosed = 0\n private gateElevated = 0\n private gateClosedElevated = 0\n private gateRmsMax = 0\n /** True between the pin/requirement being taken and released, so release is exactly once. */\n private micUplinkActive = false\n private micFramesForwarded = 0\n /** Frames since the last health line, so the rate and the call total stay separate facts. */\n private micFramesWindow = 0\n private micDropsStale = 0\n private micDropsNonGlasses = 0\n private micGaps = 0\n private micGapMsMax = 0\n private lastGlassesFrameAt = 0\n private lastMicUplinkLogAt = 0\n private lastMicDropLogAt = 0\n /** PCM level over the current health window; read and reset by [logMicUplink]. */\n private micLevel = new Pcm16LevelMeter()\n private lastMicLevel: {meanAbs: number; peak: number} | null = null\n /** Guards [releaseHostState] so a remote hang-up followed by an explicit leave releases once. */\n private hostStateReleased = true\n\n setStateHandler(handler: (packageName: string, state: MeetingState) => void): void {\n this.onState = handler\n }\n\n getState(): MeetingState {\n return {...this.lastState}\n }\n\n ownerPackage(): string | null {\n return this.owner\n }\n\n /**\n * The WHIP URL the glasses must POST their offer to, for a SoftAP call. Null for every other\n * transport and until the join has bound a listener; the orchestrator reads it between the ACS\n * join and telling the glasses to publish.\n */\n softApIngestUrl(): string | null {\n return this.ingestUrl\n }\n\n /**\n * Whether this call is taking the wearer's voice over BLE LC3, which means the glasses must\n * publish video only. Read by the SoftAP orchestrator between the meeting join and the publish.\n */\n glassesLc3UplinkActive(): boolean {\n return this.micTransport === \"ble-lc3\"\n }\n\n /**\n * Has the SoftAP video receiver released its port?\n *\n * A native that cannot answer reports `true`: it also predates the tombstone this waits out, so\n * there is nothing for the barrier to be waiting on.\n */\n async awaitIngestClosed(timeoutMs: number): Promise<boolean> {\n const native = getNative()\n if (!native?.awaitIngestClosed) return true\n const outcome = await native.awaitIngestClosed({timeoutMs})\n return outcome.closed\n }\n\n /** Close the retiring WHIP listener now. No-op on natives without it. */\n async forceCloseIngest(): Promise<void> {\n await getNative()?.forceCloseIngest?.()\n }\n\n /**\n * Destroy the current SoftAP ingest listener and bind a new one. The caller\n * rejoins the hotspot first; native reads the current scoped address.\n */\n async rebindSoftApIngest(): Promise<string> {\n const native = getNative()\n if (!native?.rebindSoftApIngest) {\n throw new Error(\"SoftAP ingest rebind is not available on this native\")\n }\n this.invalidateDecodedMedia()\n const url = await native.rebindSoftApIngest()\n this.ingestUrl = url\n return url\n }\n\n /**\n * Forget a previously decoded first frame. Recovery must wait for a frame\n * from the new ingest generation, not short-circuit on the last live verdict.\n */\n invalidateDecodedMedia(): void {\n this.decodedMediaEpoch++\n if (this.lastState.mediaSource === \"live\") {\n this.lastState = {...this.lastState, mediaSource: \"connecting\", mediaSourceReason: \"ingest_rebind\"}\n }\n }\n\n /**\n * Is this phone's Wi-Fi radio on?\n *\n * `null` means the question cannot be answered on this host — iOS, or a native that predates the\n * preflight — and callers must treat that as \"carry on\", not as \"off\". Refusing a call because\n * we could not ask would break every platform that never had the problem.\n */\n async isWifiEnabled(): Promise<boolean | null> {\n const native = getNative()\n if (!native?.isWifiEnabled) return null\n return await native.isWifiEnabled()\n }\n\n /**\n * Join the glasses hotspot as a scoped, internet-less network, returning this phone's address on\n * it. Called before the ACS join, because the local WHIP listener has to bind to that address.\n *\n * A host without the native function is not a host that silently skips the join — the SoftAP call\n * has no network to run on, so this reports the reason instead.\n */\n async joinScopedNetwork(\n ssid: string,\n passphrase: string,\n gateway?: string,\n report?: (detail: string) => void,\n ): Promise<string | undefined> {\n const native = getNative()\n if (!native?.joinScopedNetwork) {\n throw new Error(\"This host cannot join the glasses hotspot; SoftAP calling is unavailable\")\n }\n this.scopedTerminating = false\n this.bindScopedNetworkLost(native)\n await native.beginTrace?.(softapTraceId())\n if (this.scopedTerminating) throw new Error(\"Hotspot join cancelled\")\n const progress =\n Platform.OS === \"ios\" && report\n ? native.addListener(\"onScopedNetworkProgress\", (event) => {\n if (!this.scopedTerminating && event.permissionRequired === true) {\n report(\n \"Allow Local Network access to connect to your glasses. If you previously denied access, enable it in Settings, or cancel to return home.\",\n )\n }\n })\n : undefined\n try {\n if (native.joinScopedNetworkWithGateway) {\n if (!gateway) throw new Error(\"The glasses did not report a hotspot gateway\")\n return await native.joinScopedNetworkWithGateway(ssid, passphrase, gateway)\n }\n return await native.joinScopedNetwork(ssid, passphrase)\n } finally {\n progress?.remove()\n }\n }\n\n /**\n * Subscribe to \"the glasses hotspot went away while we still wanted it\".\n *\n * Only unexpected losses arrive here. Native drops the framework callback for a network it\n * released itself, and [leaveScopedNetwork] raises the terminal intent before releasing, so a\n * normal Leave or End cannot manufacture a mid-call failure.\n */\n onScopedNetworkLost(listener: (error: {code: string; message: string}) => void): () => void {\n this.scopedLostListeners.add(listener)\n return () => this.scopedLostListeners.delete(listener)\n }\n\n private bindScopedNetworkLost(native: NativeModule): void {\n if (this.scopedLostSub) return\n try {\n this.scopedLostSub = native.addListener(\"onScopedNetworkLost\", (event) => {\n if (this.scopedTerminating) {\n console.log(\"[AcsMeeting] phase=scoped-lost-expected\", {code: event.code})\n return\n }\n const error = {\n code: typeof event.code === \"string\" ? event.code : \"SOFTAP_NETWORK_LOST\",\n message: typeof event.message === \"string\" ? event.message : \"The glasses hotspot went away\",\n }\n console.warn(\"[AcsMeeting] phase=scoped-lost\", error)\n for (const listener of [...this.scopedLostListeners]) {\n try {\n listener(error)\n } catch (listenerError) {\n console.warn(\"[AcsMeeting] scoped-lost listener threw\", listenerError)\n }\n }\n })\n } catch (error) {\n // A native that predates the event simply never reports mid-call loss; that is a smaller\n // problem than failing the join over a missing listener.\n console.warn(\"[AcsMeeting] scoped network loss events unavailable\", error)\n this.scopedLostSub = null\n }\n }\n\n /** Raise the terminal intent so the release we are about to do is not read as a failure. */\n beginScopedTeardown(): void {\n this.scopedTerminating = true\n }\n\n /**\n * Wait until the phone's default network is validated again after the hotspot join.\n *\n * Joining the glasses hotspot takes the phone off Wi-Fi, and ACS needs the internet for the very\n * next step. Waiting is what turns a 40-second join timeout with device-wide DNS failures into a\n * short, named wait — or an honest failure. Null when the host cannot tell.\n */\n async awaitValidatedDefaultNetwork(): Promise<DefaultNetworkStatus | null> {\n const native = getNative()\n if (!native?.awaitValidatedDefaultNetwork) return null\n return await native.awaitValidatedDefaultNetwork()\n }\n\n /** Cleanup may restore home Wi-Fi; only the live SoftAP leg requires cellular on iOS. */\n async awaitDefaultNetworkAfterHotspot(): Promise<DefaultNetworkStatus | null> {\n const native = getNative()\n return native?.awaitDefaultNetworkAfterHotspot\n ? await native.awaitDefaultNetworkAfterHotspot()\n : await this.awaitValidatedDefaultNetwork()\n }\n\n async cancelScopedNetworkJoin(): Promise<void> {\n this.scopedTerminating = true\n await getNative()?.cancelScopedNetworkJoin?.()\n }\n\n /**\n * Can this phone reach the glasses over the hotspot it just joined? Null when the host cannot\n * tell (no native support), so the orchestrator narrates nothing rather than a guess.\n */\n async probeScopedGateway(): Promise<{reachable: boolean; detail: string} | null> {\n const native = getNative()\n if (!native?.probeScopedGateway) return null\n return await native.probeScopedGateway()\n }\n\n /** Safe to call when nothing was joined: teardown runs after failed starts too. */\n async leaveScopedNetwork(): Promise<void> {\n // Intent first, release second. The other order is the false-positive bug: Android reports the\n // loss we asked for, and the call reports a network failure as it is successfully ending.\n this.scopedTerminating = true\n try {\n await getNative()?.leaveScopedNetwork?.()\n } finally {\n this.scopedLostSub?.remove()\n this.scopedLostSub = null\n }\n }\n\n /**\n * Resolves when the phone decodes its first glasses frame. This confirms the local media leg;\n * Teams admission is a separate call state and may still be connecting or in the lobby.\n * Rejects if the feed fails first, and on timeout.\n *\n * @param timeoutMs how long to wait before treating the silence as a failure\n */\n waitForFirstFrame(timeoutMs: number, options: {fresh?: boolean} = {}): Promise<void> {\n const liveThisGeneration =\n this.lastState.mediaSource === \"live\" && this.liveEpoch === this.decodedMediaEpoch\n // Join short-circuits on any live. Recovery (`fresh`) short-circuits only on a live\n // from this ingest generation: the new WHIP first frame often lands during publish,\n // before this wait starts. Waiting for a later `onState` then times out while video\n // is already flowing, and the miniapp hangs up the ACS meeting.\n if (liveThisGeneration) {\n softapTrace(\n options.fresh ? \"glasses_first_frame_this_generation\" : \"glasses_first_frame_already_received\",\n {mediaSource: this.lastState.mediaSource, epoch: this.decodedMediaEpoch},\n )\n return Promise.resolve()\n }\n const startedAt = Date.now()\n softapTrace(\"acs_first_frame_wait\", {\n timeoutMs,\n mediaSource: this.lastState.mediaSource ?? \"unknown\",\n state: this.lastState.state,\n })\n return new Promise<void>((resolve, reject) => {\n const settle = (error?: Error) => {\n if (done) return\n done = true\n clearTimeout(timer)\n this.firstFrameWaiters.delete(settle)\n // The step this closes is the one that decides whether the call is usable, so its outcome\n // is named rather than inferred from whichever line happens to follow.\n if (error) {\n softapTraceFailure(\"acs_first_frame_wait_done\", {\n waitedMs: Date.now() - startedAt,\n reason: error.message,\n })\n reject(error)\n } else {\n softapTrace(\"acs_first_frame_wait_done\", {waitedMs: Date.now() - startedAt})\n resolve()\n }\n }\n let done = false\n const timer = setTimeout(\n () => settle(new Error(`No glasses video reached the phone within ${Math.round(timeoutMs / 1000)}s`)),\n timeoutMs,\n )\n this.firstFrameWaiters.add(settle)\n })\n }\n\n /** Wake every `waitForFirstFrame` caller with the outcome the host just reported. */\n private settleFirstFrameWaiters(mediaSource: MediaSourceState | undefined): void {\n if (mediaSource !== \"live\" && mediaSource !== \"failed\") return\n const error = mediaSource === \"failed\" ? new Error(\"The glasses video feed failed\") : undefined\n for (const settle of [...this.firstFrameWaiters]) settle(error)\n if (mediaSource === \"live\") this.settleMediaLiveWaiters(true)\n }\n\n private settleMediaLiveWaiters(live: boolean): void {\n for (const settle of [...this.mediaLiveWaiters]) settle(live)\n }\n\n /**\n * Mid-call SoftAP camera recovery. Resolves `true` only when ingest is live again.\n * A standing `failed` is why we republished, so it must not abort the wait the way\n * [waitForFirstFrame] does on join.\n */\n waitUntilMediaLive(timeoutMs: number): Promise<boolean> {\n if (this.lastState.mediaSource === \"live\") return Promise.resolve(true)\n const startedAt = Date.now()\n softapTrace(\"acs_media_live_wait\", {\n timeoutMs,\n mediaSource: this.lastState.mediaSource ?? \"unknown\",\n state: this.lastState.state,\n })\n return new Promise<boolean>((resolve) => {\n const settle = (live: boolean) => {\n if (done) return\n done = true\n clearTimeout(timer)\n this.mediaLiveWaiters.delete(settle)\n softapTrace(\"acs_media_live_wait_done\", {\n waitedMs: Date.now() - startedAt,\n live,\n })\n resolve(live)\n }\n let done = false\n const timer = setTimeout(() => settle(false), timeoutMs)\n this.mediaLiveWaiters.add(settle)\n })\n }\n\n /**\n * On Android, pin cellular and sign in before the glasses hotspot exists.\n *\n * SoftAP DNS cannot resolve Teams hosts. Doing this on the phone's existing internet is what\n * stops `createCallAgent` from hanging until the hotspot is torn down.\n */\n async prepareAgent(args: {token: string; displayName?: string}): Promise<void> {\n // iOS creates its agent after the host's hotspot/default-route wait so signaling starts\n // on the post-handoff route instead of reusing an agent signed in over the previous Wi-Fi.\n if (Platform.OS === \"ios\") {\n softapTrace(\"acs_prepare_agent_deferred\", {reason: \"ios_hotspot_handoff\"})\n return\n }\n const native = getNative()\n if (!native?.prepareAgent) {\n // A host that cannot pre-sign-in still joins; it just does the sign-in inside the SoftAP\n // join, which is the 20-second ACS_AGENT_TIMEOUT this step exists to avoid. Worth a line,\n // because from the trace alone that build looks like one whose sign-in was instant.\n softapTrace(\"acs_prepare_agent_skipped\", {reason: native ? \"unsupported build\" : \"no native module\"})\n return\n }\n console.log(\"[AcsMeeting] phase=prepare-agent\")\n const startedAt = Date.now()\n softapTrace(\"acs_native_prepare_agent\", {hasDisplayName: Boolean(args.displayName)})\n try {\n await native.prepareAgent({token: args.token, displayName: args.displayName})\n } catch (error) {\n softapTraceFailure(\"acs_native_prepare_agent_failed\", {\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n }\n console.log(\"[AcsMeeting] phase=prepare-agent-ok\")\n softapTrace(\"acs_native_prepare_agent_ok\", {durationMs: Date.now() - startedAt})\n }\n\n async join(\n packageName: string,\n args: {\n meetingUrl: string\n token: string\n videoSource: AcsVideoSource\n displayName?: string\n video?: AcsOutgoingVideo\n origin?: AcsCallOrigin\n /**\n * Whether the caller holds a glasses microphone session. The uplink is the wearer's voice,\n * so it is only taken off the glasses when somebody has actually claimed that microphone\n * through MicSessionManager; this class never claims it itself.\n */\n glassesSession?: boolean\n },\n ): Promise<MeetingState> {\n const native = getNative()\n if (!native) {\n console.warn(\"[AcsMeeting] phase=join-native nativeLoaded=false\")\n throw new Error(\"ACS meeting module is not available on this host\")\n }\n if (this.owner && this.owner !== packageName) {\n throw new Error(\"Another miniapp already has an active meeting\")\n }\n // Validate before claiming ownership so a bad request cannot leave the slot taken.\n const video = args.video ? parseAcsOutgoingVideo(args.video) : undefined\n const resolved = resolveAcsAudioSource()\n const generation = ++this.callGeneration\n this.hostStateReleased = false\n this.owner = packageName\n // Only a whep source has a URL to re-feed on recovery; softap rebuilds instead.\n this.whepUrl = args.videoSource.type === \"whep\" ? args.videoSource.url : null\n this.videoSource = args.videoSource\n // Decided here, before the join, so the SoftAP orchestrator can read it between the join and\n // telling the glasses what to capture.\n const lc3Uplink = glassesLc3UplinkSupported({\n videoSource: args.videoSource,\n audioSource: resolved.source,\n hasPushOutgoingPcm: typeof native.pushOutgoingPcm === \"function\",\n platform: Platform.OS,\n glassesSession: args.glassesSession ?? false,\n })\n this.micTransport = lc3Uplink ? \"ble-lc3\" : resolved.source === \"phone\" ? \"phone\" : \"whip\"\n this.bindNative(native, packageName)\n console.log(\"[AcsMeeting] phase=join-native\", {\n packageName,\n nativeLoaded: true,\n hasToken: Boolean(args.token),\n transport: args.videoSource.type,\n audioSource: resolved.source,\n audioSourceReason: resolved.reason,\n micTransport: this.micTransport,\n preferredMic: useSettingsStore.getState().getSetting(SETTINGS.preferred_mic.key),\n })\n const joinStartedAt = Date.now()\n const origin = parseAcsCallOrigin(args.origin)\n this.callOrigin = origin\n softapTrace(\"acs_native_join\", {\n packageName,\n generation,\n transport: args.videoSource.type,\n audioSource: resolved.source,\n micTransport: this.micTransport,\n audioDelayMs: lc3Uplink ? SOFTAP_LC3_AUDIO_DELAY_MS : 0,\n video: video ? `${video.width}x${video.height}@${video.fps}` : \"default\",\n origin,\n })\n // Duplicated from the native `native_join_options` line on purpose: if the native trace is\n // missing from a capture — a bug report with only the JS log, a crash before export — this is\n // the only record of what the two paths actually asked for.\n softapTrace(\"acs_join_options\", {\n origin,\n transport: args.videoSource.type,\n width: video?.width ?? 0,\n height: video?.height ?? 0,\n fps: video?.fps ?? 0,\n maxBitrateBps: video?.maxBitrateBps ?? 0,\n })\n try {\n const state = await native.join({\n meetingUrl: args.meetingUrl,\n token: args.token,\n whepUrl: this.whepUrl ?? \"\",\n videoSource: args.videoSource,\n displayName: args.displayName,\n audioSource: resolved.source,\n origin,\n ...(lc3Uplink ? {audioDelayMs: SOFTAP_LC3_AUDIO_DELAY_MS} : {}),\n ...(video ? {video} : {}),\n })\n softapTrace(\"acs_native_join_returned\", {\n packageName,\n generation,\n state: state.state,\n hasIngestUrl: typeof state.ingestUrl === \"string\" && state.ingestUrl.length > 0,\n durationMs: Date.now() - joinStartedAt,\n })\n if (generation !== this.callGeneration) {\n // The wearer left while ACS was still joining. Nothing above knows about this call, so\n // hanging it up here is the only thing that takes the device out of the Teams roster.\n console.warn(\"[AcsMeeting] phase=join-cancelled\", {packageName, generation})\n softapTraceFailure(\"acs_native_join_cancelled\", {\n packageName,\n generation,\n current: this.callGeneration,\n durationMs: Date.now() - joinStartedAt,\n })\n await native.leave().catch((leaveError) => {\n console.warn(\"[AcsMeeting] native leave after a cancelled join failed\", leaveError)\n softapTraceFailure(\"acs_native_leave_after_cancelled_join_failed\", {\n packageName,\n reason: leaveError instanceof Error ? leaveError.message : String(leaveError),\n })\n })\n throw new Error(\"The meeting was cancelled before it finished joining\")\n }\n this.ingestUrl = typeof state.ingestUrl === \"string\" ? state.ingestUrl : null\n const {ingestUrl: _ingestUrl, ...meetingState} = state\n this.lastState = {\n ...meetingState,\n audioSource: resolved.source,\n audioSourceReason: resolved.reason,\n micTransport: this.micTransport,\n }\n console.log(\"[AcsMeeting] phase=join-native-ok\", {state: state.state, muted: state.muted})\n this.startGlassesMicUplink(generation)\n } catch (error) {\n // Native never joined (or is unwinding). Release the slot so the same or another\n // miniapp can retry, and make sure nothing half-joined lingers in Teams.\n console.warn(\"[AcsMeeting] phase=join-native-failed\", {\n packageName,\n error: error instanceof Error ? error.message : String(error),\n })\n softapTraceFailure(\"acs_native_join_failed\", {\n packageName,\n generation,\n durationMs: Date.now() - joinStartedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n await native.leave().catch((leaveError) => {\n console.warn(\"[AcsMeeting] native leave after failed join also failed\", leaveError)\n softapTraceFailure(\"acs_native_leave_after_failed_join_failed\", {\n packageName,\n reason: leaveError instanceof Error ? leaveError.message : String(leaveError),\n })\n })\n await this.releaseHostState()\n throw error\n }\n this.watchPhoneNetwork(native)\n // Return audio is additive: the wearer is already in the meeting with camera and\n // mic. A playback failure must not reject the join — that would leave the miniapp\n // believing it never joined while native keeps the wearer in Teams.\n try {\n await this.ensurePcmPlayback(packageName)\n console.log(\"[AcsMeeting] phase=pcm-playback\", {streamId: this.pcmStreamId})\n } catch (error) {\n console.warn(\"[AcsMeeting] phase=pcm-playback-failed; continuing without return audio\", {\n error: error instanceof Error ? error.message : String(error),\n })\n }\n return this.lastState\n }\n\n async leave(packageName: string): Promise<void> {\n if (this.owner && this.owner !== packageName) {\n // Not the owner, so this is a no-op rather than a leave. Said out loud because a miniapp\n // that thinks it left and a host that never hung up look identical from the miniapp's side.\n softapTrace(\"acs_native_leave_ignored\", {packageName, owner: this.owner})\n return\n }\n const native = getNative()\n const startedAt = Date.now()\n softapTrace(\"acs_native_leave\", {packageName, nativeLoaded: Boolean(native)})\n try {\n await native?.leave()\n softapTrace(\"acs_native_leave_ok\", {packageName, durationMs: Date.now() - startedAt})\n } catch (error) {\n softapTraceFailure(\"acs_native_leave_failed\", {\n packageName,\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n } finally {\n await this.releaseHostState()\n }\n }\n\n /**\n * Leave, and do not resolve until native reports its cleanup is finished.\n *\n * Android native's `leave()` queues the hang-up, the\n * agent disposal, and the network releases on its session executor and returns straight away, so\n * a caller that awaits it and then starts the next call is racing the previous one's teardown.\n *\n * Falls back to [leave] on builds that predate the signal and says so, rather than pretending to\n * a guarantee it cannot give.\n *\n * @param timeoutMs how long native may take before it reports the cleanup as stuck\n */\n async leaveAndAwait(packageName: string, timeoutMs = ACS_LEAVE_WAIT_MS): Promise<{completed: boolean; reason?: string}> {\n if (this.owner && this.owner !== packageName) {\n softapTrace(\"acs_native_leave_and_await_ignored\", {packageName, owner: this.owner})\n return {completed: true}\n }\n const native = getNative()\n if (!native?.leaveAndAwait) {\n // The fallback is the case the cleanup barrier was built for: this build's leave returns\n // before its own teardown has finished, so nothing downstream can treat \"left\" as \"idle\".\n softapTraceFailure(\"acs_native_leave_and_await_unsupported\", {\n packageName,\n nativeLoaded: Boolean(native),\n })\n await this.leave(packageName)\n return {completed: false, reason: \"unsupported\"}\n }\n const startedAt = Date.now()\n softapTrace(\"acs_native_leave_and_await\", {packageName, timeoutMs})\n try {\n const outcome = await native.leaveAndAwait({timeoutMs})\n softapTrace(\"acs_native_leave_and_await_ok\", {\n packageName,\n completed: outcome?.completed !== false,\n durationMs: Date.now() - startedAt,\n })\n return {completed: outcome?.completed !== false}\n } catch (error) {\n softapTraceFailure(\"acs_native_leave_and_await_failed\", {\n packageName,\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n } finally {\n await this.releaseHostState()\n }\n }\n\n /** Admit one guest without changing call ownership or audio state. */\n async admitParticipant(packageName: string, participantId: string): Promise<void> {\n if (this.owner !== packageName) throw new Error(\"This miniapp does not own the active meeting\")\n if (!participantId.trim()) throw new Error(\"A participant ID is required\")\n const native = getNative()\n if (!native?.admitParticipant) throw new Error(\"This Mentra App build does not support admitting guests\")\n const generation = this.callGeneration\n await native.admitParticipant(participantId)\n if (generation !== this.callGeneration) throw new Error(\"The meeting changed during admission\")\n }\n\n /**\n * End the Teams group call for everyone.\n *\n * Host state is released either way: native tears this device down whatever the hang-up did, so\n * holding the meeting slot open after a rejection would leave the miniapp unable to start another\n * call. The rejection still propagates — the caller has to be able to say \"you left, but the\n * meeting may still be active\" instead of claiming a clean end.\n */\n async endForEveryone(packageName: string): Promise<MeetingState> {\n if (this.owner && this.owner !== packageName) {\n throw new Error(\"This miniapp does not own the active meeting\")\n }\n const native = getNative()\n if (!native?.endForEveryone) {\n softapTraceFailure(\"acs_native_end_unsupported\", {packageName, nativeLoaded: Boolean(native)})\n throw new Error(\"Update the Mentra App to end a meeting for everyone\")\n }\n const startedAt = Date.now()\n softapTrace(\"acs_native_end\", {packageName})\n try {\n const state = await native.endForEveryone()\n console.log(\"[AcsMeeting] phase=end-for-everyone-ok\", {state: state.state})\n softapTrace(\"acs_native_end_ok\", {packageName, state: state.state, durationMs: Date.now() - startedAt})\n return state\n } catch (error) {\n // The meeting may still be live for the others; this device is out regardless. Logged as a\n // failure of the claim, not of the teardown.\n softapTraceFailure(\"acs_native_end_failed\", {\n packageName,\n durationMs: Date.now() - startedAt,\n reason: error instanceof Error ? error.message : String(error),\n })\n throw error\n } finally {\n await this.releaseHostState()\n }\n }\n\n /** Whether the wearer may end this meeting for everyone, as ACS last reported it. */\n hangUpForEveryoneCapability(): MeetingCapability {\n return this.lastState.capabilities?.hangUpForEveryone ?? {allowed: null, reason: null}\n }\n\n /**\n * Drop everything the host set up around a session: the microphone uplink, the network watcher,\n * return audio, native listeners, ownership.\n *\n * Idempotent, because there are now several terminal paths into it and they overlap. A remote\n * hang-up arrives as a native `disconnected`, and the miniapp usually calls `leave` right after\n * seeing it; releasing the microphone pin twice would clear a pin the *next* call had already\n * taken. Every release also bumps the call generation, which is what stops a `mic_pcm` event\n * already queued on the JS thread from reaching a native session that is gone.\n */\n private async releaseHostState(): Promise<void> {\n if (this.hostStateReleased) return\n this.hostStateReleased = true\n this.callGeneration++\n // Before anything else: a caller parked on a frame that will now never arrive has to be\n // rejected, or a leave mid-join leaves the orchestrator waiting out its whole timeout.\n for (const settle of [...this.firstFrameWaiters]) settle(new Error(\"The meeting ended\"))\n this.firstFrameWaiters.clear()\n this.settleMediaLiveWaiters(false)\n this.mediaLiveWaiters.clear()\n this.stopGlassesMicUplink()\n this.unwatchPhoneNetwork()\n await this.stopPcm()\n this.unbindNative()\n this.scopedLostSub?.remove()\n this.scopedLostSub = null\n this.owner = null\n this.whepUrl = null\n this.videoSource = null\n this.ingestUrl = null\n this.lastMediaRestartAt = 0\n this.lastState = {state: \"idle\", muted: false}\n }\n\n /**\n * Start forwarding the glasses microphone into ACS for this call.\n *\n * This class is a sink: it never names a gain, a pin or a setting. It does take a semantic\n * voice_call lease first, because reading the glasses mic without one is what put this call on\n * the OS default of VAD-on — a speech gate that drops the wearer's uplink whenever the GX8002\n * disagrees, which during a call is most of the time the far end is talking. The lease is a\n * backstop: when the miniapp already holds one this simply merges with it, and micPolicy still\n * decides what voice_call means for the hardware.\n *\n * `generation` is captured by the listener so a frame that lands after this call ended is\n * dropped rather than pushed at a native session that has left the meeting.\n */\n private startGlassesMicUplink(generation: number): void {\n if (this.micTransport !== \"ble-lc3\") return\n const native = getNative()\n const push = native?.pushOutgoingPcm\n if (!native || !push) return\n this.micFramesForwarded = 0\n this.micFramesWindow = 0\n this.micDropsStale = 0\n this.micDropsNonGlasses = 0\n this.micGaps = 0\n this.micGapMsMax = 0\n this.lastGlassesFrameAt = Date.now()\n this.lastMicDropLogAt = 0\n this.lastMicUplinkLogAt = Date.now()\n this.micLevel.take()\n this.lastMicLevel = null\n try {\n this.acquireMicSession()\n this.startMicGateTelemetry()\n this.micUplinkActive = true\n this.micSub = BluetoothSdk.addListener(\"mic_pcm\", (event: {pcm?: ArrayBuffer; sampleRate?: number; source?: string}) => {\n if (generation !== this.callGeneration) {\n this.micDropsStale += 1\n this.logMicDrop(\"stale\", {generation, active: this.callGeneration})\n return\n }\n // The pin makes this unreachable in normal operation, which is exactly why it is checked:\n // a mic the SDK moved under us would otherwise put the phone's room into a Teams call\n // that reports the glasses.\n if (event.source !== GLASSES_MIC_SOURCE) {\n this.micDropsNonGlasses += 1\n this.logMicDrop(\"non-glasses\", {source: event.source})\n this.reportGlassesMicUnavailable(event.source)\n return\n }\n const pcm = event.pcm\n if (!pcm) return\n const now = Date.now()\n if (this.micFramesForwarded > 0) {\n const gapMs = now - this.lastGlassesFrameAt\n if (gapMs > MIC_GAP_WARN_MS) {\n this.micGaps += 1\n this.micGapMsMax = Math.max(this.micGapMsMax, gapMs)\n this.logMicDrop(\"gap\", {gapMs})\n }\n }\n this.lastGlassesFrameAt = now\n this.micFramesForwarded += 1\n this.micFramesWindow += 1\n this.micLevel.add(pcm)\n try {\n push.call(native, pcmToBase64(pcm), event.sampleRate ?? 16000, 1)\n } catch (error) {\n console.warn(\"[AcsMeeting] pushing glasses PCM to ACS failed\", error)\n }\n this.logMicUplink()\n })\n console.log(\"[AcsMeeting] phase=glasses-mic-uplink-start\", {generation, micTransport: this.micTransport})\n } catch (error) {\n // A host that cannot subscribe has no wearer audio at all, and that is worth saying loudly,\n // but it is not worth failing a call the wearer can still see and hear.\n console.error(\"[AcsMeeting] phase=glasses-mic-uplink-unavailable\", error)\n this.stopGlassesMicUplink()\n this.markMicTransportNone()\n }\n }\n\n /**\n * Stop reading the glasses microphone. Safe to call when this call never started.\n *\n * Only this call's own backstop lease is dropped. A lease the miniapp took is its to release,\n * and letting go of ours before that owner releases is what keeps a normal hang-up from looking\n * like the wearer's microphone disappearing.\n */\n private stopGlassesMicUplink(): void {\n this.micSub?.remove()\n this.micSub = null\n this.releaseMicSession()\n if (this.micUplinkActive) {\n this.micUplinkActive = false\n console.log(\"[AcsMeeting] phase=glasses-mic-uplink-stop\", {\n frames: this.micFramesForwarded,\n dropsStale: this.micDropsStale,\n dropsNonGlasses: this.micDropsNonGlasses,\n gaps: this.micGaps,\n gapMsMax: this.micGapMsMax,\n ...this.gateSummary(),\n })\n }\n this.stopMicGateTelemetry()\n this.micTransport = \"whip\"\n }\n\n /**\n * Watch what the glasses are actually running for the length of the call.\n *\n * Two different questions, both unanswerable from this side otherwise. `mic_tuning_state` is\n * the post-clamp reply, so it catches a profile the firmware rewrote rather than accepted.\n * `mic_rms` carries the Barrier's own verdict per frame, which is the only way to tell a gate\n * that is suppressing speaker leak from one that is suppressing the wearer.\n */\n private startMicGateTelemetry(): void {\n this.gateSamples = 0\n this.gateClosed = 0\n this.gateElevated = 0\n this.gateClosedElevated = 0\n this.gateRmsMax = 0\n\n try {\n this.micTuningSub = BluetoothSdk.addListener(\"mic_tuning_state\", (event: Record<string, unknown>) => {\n console.log(\"[AcsMeeting] phase=glasses-mic-tuning-applied\", event)\n })\n this.micRmsSub = BluetoothSdk.addListener(\n \"mic_rms\",\n (event: {rms?: number; gateOpen?: boolean; speakerElevated?: boolean}) => {\n this.gateSamples += 1\n if (event.gateOpen === false) this.gateClosed += 1\n if (event.speakerElevated) {\n this.gateElevated += 1\n if (event.gateOpen === false) this.gateClosedElevated += 1\n }\n if (typeof event.rms === \"number\" && event.rms > this.gateRmsMax) this.gateRmsMax = event.rms\n },\n )\n void Promise.resolve(BluetoothSdk.setMicRmsTelemetry?.(true))\n .then(() => {\n this.micRmsEnabled = true\n })\n .catch((error) => console.warn(\"[AcsMeeting] mic RMS telemetry unavailable\", error))\n void Promise.resolve(BluetoothSdk.requestMicTuningState?.()).catch(() => {})\n } catch (error) {\n console.warn(\"[AcsMeeting] mic gate telemetry unavailable\", error)\n }\n }\n\n private stopMicGateTelemetry(): void {\n this.micTuningSub?.remove()\n this.micTuningSub = null\n this.micRmsSub?.remove()\n this.micRmsSub = null\n if (!this.micRmsEnabled) return\n this.micRmsEnabled = false\n // Super Mode may have the readout open behind this call; it re-requests on focus.\n void Promise.resolve(BluetoothSdk.setMicRmsTelemetry?.(false)).catch(() => {})\n }\n\n /** Barrier's behaviour over the window, as percentages a listening test can be checked against. */\n private gateSummary(): Record<string, number> {\n if (this.gateSamples === 0) return {}\n const pct = (n: number, of: number) => (of === 0 ? 0 : Math.round((n / of) * 1000) / 10)\n return {\n gateSamples: this.gateSamples,\n gateClosedPct: pct(this.gateClosed, this.gateSamples),\n speakerElevatedPct: pct(this.gateElevated, this.gateSamples),\n // The number that matters: closed while the far end was quiet means the wearer was cut.\n gateClosedQuietPct: pct(this.gateClosed - this.gateClosedElevated, this.gateSamples - this.gateElevated),\n gateRmsMax: this.gateRmsMax,\n }\n }\n\n /**\n * Guarantee a voice_call session for as long as this call reads the glasses mic.\n *\n * The miniapp asking for one is the intended path; this covers the builds where it cannot,\n * because a bundled Call that predates MIC_ACQUIRE joins anyway rather than failing. Without\n * this the uplink runs under whatever the OS settings say, and the shipped default is VAD-on.\n */\n private acquireMicSession(): void {\n if (this.micSession) return\n try {\n this.micSession = micSessionManager.acquire({\n owner: `${ENGINE_OWNER_PREFIX}acs-uplink`,\n source: \"glasses\",\n useCase: \"voice_call\",\n })\n } catch (error) {\n // A source conflict means something else already owns the microphone. Forwarding whatever\n // it captures is still better than dropping the wearer from the call.\n console.warn(\"[AcsMeeting] glasses mic session unavailable\", error)\n }\n }\n\n private releaseMicSession(): void {\n const session = this.micSession\n if (!session) return\n this.micSession = null\n try {\n session.release()\n } catch (error) {\n console.warn(\"[AcsMeeting] releasing the glasses mic session failed\", error)\n }\n }\n\n /**\n * Report a call whose pinned microphone stopped delivering. There is deliberately no fallback:\n * the wearer agreed to be heard from the glasses, and quietly switching to the phone in the\n * middle of a meeting puts the room they are standing in on the call.\n */\n private reportGlassesMicUnavailable(source: string | undefined): void {\n if (Date.now() - this.lastGlassesFrameAt < GLASSES_MIC_GRACE_MS) return\n if (this.micTransport === \"none\") return\n console.error(\"[AcsMeeting] phase=glasses-mic-unavailable\", {source, dropsNonGlasses: this.micDropsNonGlasses})\n this.markMicTransportNone()\n }\n\n /**\n * Record that this call has no wearer audio path.\n *\n * The state has to carry it, not just the field: a call that reported `ble-lc3` and then failed\n * to start the uplink looks identical from the miniapp's side to one that is working, and the\n * wearer finds out by being asked to repeat themselves.\n */\n private markMicTransportNone(): void {\n this.micTransport = \"none\"\n this.lastState = {...this.lastState, micTransport: \"none\", error: GLASSES_MIC_UNAVAILABLE}\n if (this.owner) this.onState?.(this.owner, this.lastState)\n }\n\n private logMicUplink(): void {\n const now = Date.now()\n const elapsed = now - this.lastMicUplinkLogAt\n const sweep = getCallGainSweep()\n const interval = sweep.isActive() ? MIC_UPLINK_SWEEP_LOG_INTERVAL_MS : MIC_UPLINK_LOG_INTERVAL_MS\n if (elapsed < interval) return\n this.lastMicUplinkLogAt = now\n // Level, not just cadence: a 20 Hz stream of the noise floor and a 20 Hz stream of speech\n // have the same framesPerSecond. Quiet room on Mentra Live LC3 is meanAbs ≈30–60.\n const level = this.micLevel.take()\n const stats = pcm16WindowStats(level)\n this.lastMicLevel = {meanAbs: level.meanAbs, peak: level.peak}\n const gain = sweep.currentGain() ?? micStateCoordinator.getSessionMicTuning()?.gain ?? null\n if (sweep.isActive()) sweep.ingest(level)\n console.log(\"[AcsMeeting] phase=glasses-mic-uplink\", {\n framesPerSecond: Math.round((this.micFramesWindow * 1000) / elapsed),\n frames: this.micFramesForwarded,\n meanAbs: stats.meanAbs,\n peak: stats.peak,\n peakPct: stats.peakPct,\n clipped: stats.clipped,\n clipPct: stats.clipPct,\n nearClip: stats.nearClip,\n nearClipPct: stats.nearClipPct,\n gain,\n barrier: micStateCoordinator.getSessionLoudnessGate(),\n sweep: sweep.currentLabel(),\n dropsStale: this.micDropsStale,\n dropsNonGlasses: this.micDropsNonGlasses,\n gaps: this.micGaps,\n gapMsMax: this.micGapMsMax,\n ...this.gateSummary(),\n })\n this.micFramesWindow = 0\n }\n\n /** Level of the last uplink window, for tests and dev screens. `null` until a window closed. */\n lastGlassesMicLevel(): {meanAbs: number; peak: number} | null {\n return this.lastMicLevel\n }\n\n private logMicDrop(reason: string, extra: Record<string, unknown>): void {\n const now = Date.now()\n if (now - this.lastMicDropLogAt < 1000) return\n this.lastMicDropLogAt = now\n console.warn(\"[AcsMeeting] phase=glasses-mic-drop\", {\n reason,\n dropsStale: this.micDropsStale,\n dropsNonGlasses: this.micDropsNonGlasses,\n gaps: this.micGaps,\n ...extra,\n })\n }\n\n async setMuted(packageName: string, muted: boolean): Promise<MeetingState> {\n this.assertOwner(packageName)\n const native = getNative()\n if (!native) throw new Error(\"ACS meeting module is not available on this host\")\n const state = await native.setMuted(muted)\n this.lastState = {\n ...this.lastState,\n ...state,\n audioSourceReason: this.lastState.audioSourceReason,\n // Mute is an ACS-side gate. It does not change which microphone the call is using, and it\n // deliberately does not turn the glasses microphone off — see the mute chain in native.\n micTransport: this.micTransport,\n }\n return this.lastState\n }\n\n async updateVideoSource(packageName: string, whepUrl: string): Promise<void> {\n this.assertOwner(packageName)\n const native = getNative()\n if (!native) throw new Error(\"ACS meeting module is not available on this host\")\n if (this.videoSource?.type === \"softap\") {\n // The host owns the softap endpoint, so there is no URL for a caller to change. Failing is\n // better than accepting it and doing nothing.\n throw new Error(\"updateVideoSource is not applicable to a SoftAP call\")\n }\n this.whepUrl = whepUrl\n await native.updateVideoSource(whepUrl)\n }\n\n async readState(packageName: string): Promise<MeetingState> {\n if (this.owner && this.owner !== packageName) {\n return {state: \"idle\", muted: false}\n }\n const native = getNative()\n if (!native) return {state: \"idle\", muted: false}\n const state = await native.getState()\n this.lastState = {...state, micTransport: this.micTransport}\n return this.lastState\n }\n\n async leaveIfOwner(packageName: string): Promise<void> {\n if (this.owner === packageName) await this.leave(packageName)\n }\n\n private assertOwner(packageName: string): void {\n if (this.owner !== packageName) {\n throw new Error(\n this.owner ? \"This miniapp does not own the active meeting\" : \"No active meeting; call meeting.join first\",\n )\n }\n }\n\n private unbindNative(): void {\n this.subscriptions.forEach((sub) => sub.remove())\n this.subscriptions = []\n }\n\n private bindNative(native: NativeModule, packageName: string): void {\n this.unbindNative()\n // Captured at bind, checked on every event. `unbindNative` removes the listener, but an event\n // already dispatched onto the JS queue still runs — and this is the one path where that lands\n // as the *previous* call's `disconnected` ending the call the wearer just started. Every other\n // callback that can outlive a session (mic PCM, the in-flight join) is fenced the same way.\n const generation = this.callGeneration\n this.subscriptions = [\n native.addListener(\"onState\", (event) => {\n if (generation !== this.callGeneration) {\n softapTraceFailure(\"softap_stale_callback\", {\n source: \"acs_state\",\n generation,\n current: this.callGeneration,\n state: String(event.state ?? \"unknown\"),\n })\n return\n }\n const audioSafety = parseAudioSafety(event.audioSafety)\n if (audioSafety === \"unsafe\") {\n console.error(\"[AcsMeeting] phase=audio-unsafe\", {\n activeStream: event.activeStream,\n audioSource: event.audioSource,\n })\n }\n const participants = parseMeetingParticipants(event.participants)\n const mediaSource = parseMediaSource(event.mediaSource)\n const mediaSourceReason = typeof event.mediaSourceReason === \"string\" ? event.mediaSourceReason : undefined\n const callEndReason =\n Number.isInteger(event.endReason_code) && Number.isInteger(event.endReason_subcode)\n ? {code: event.endReason_code as number, subcode: event.endReason_subcode as number}\n : undefined\n const capabilities = parseMeetingCapabilities(event.capabilities)\n const endReason = parseMeetingEndReason(event as Record<string, unknown>)\n const state: MeetingState = {\n state: (event.state as MeetingPhase) ?? \"idle\",\n muted: Boolean(event.muted),\n error: event.error as string | undefined,\n meetingUrl: event.meetingUrl as string | undefined,\n provider: \"acs-teams\",\n audioSource: event.audioSource === \"phone\" ? \"phone\" : \"glasses\",\n audioSourceReason: this.lastState.audioSourceReason,\n activeStream: parseActiveStream(event.activeStream),\n audioSafety,\n micTransport: this.micTransport,\n ...(mediaSource ? {mediaSource} : {}),\n ...(mediaSourceReason ? {mediaSourceReason} : {}),\n ...(callEndReason ? {callEndReason} : {}),\n ...(participants ? {participants} : {}),\n ...(endReason ? {endReason} : {}),\n // Absent means unknown, so keep the last known verdict rather than clearing it.\n ...((capabilities ?? this.lastState.capabilities) ? {capabilities: capabilities ?? this.lastState.capabilities} : {}),\n }\n const previous = this.lastState.state\n this.lastState = state\n if (state.state !== previous) {\n // The host's own copy of the transition. Native already traces `acs_call_state` with\n // timings; this one survives a capture where the native trace is absent, and is the\n // line the miniapp's timeline is reconciled against.\n softapTrace(\"acs_state\", {\n state: state.state,\n previous,\n origin: this.callOrigin,\n mediaSource: state.mediaSource ?? \"unknown\",\n micTransport: state.micTransport ?? \"unknown\",\n })\n }\n console.log(\"[AcsMeeting] phase=native-state\", {\n state: state.state,\n muted: state.muted,\n error: state.error,\n audioSource: state.audioSource,\n activeStream: state.activeStream,\n audioSafety: state.audioSafety,\n mediaSource: state.mediaSource,\n mediaSourceReason: state.mediaSourceReason,\n callEndReason: state.callEndReason,\n micTransport: state.micTransport,\n participants: participants?.length,\n endReason: endReason ? `${endReason.code ?? \"?\"}/${endReason.subcode ?? \"?\"}` : undefined,\n })\n if (mediaSource === \"live\") this.liveEpoch = this.decodedMediaEpoch\n this.settleFirstFrameWaiters(mediaSource)\n this.onState?.(packageName, state)\n // A remote hang-up, an ACS error or a dropped call never goes through `leave`, so without\n // this the microphone pin, the PCM requirement and the `mic_pcm` listener would outlive the\n // meeting — and the next miniapp to start a call would inherit them.\n if (state.state === \"disconnected\" || state.state === \"error\") {\n void this.releaseHostState().catch((error) => {\n console.warn(\"[AcsMeeting] releasing host state after a terminal native state failed\", error)\n })\n }\n }),\n native.addListener(\"onIncomingPcm\", (event) => {\n const base64 = event.base64 as string | undefined\n if (!base64 || !this.owner) return\n // Serialize: native async calls may complete out of order, and PCM\n // chunks written out of order are audible as garbling.\n this.pcmWriteChain = this.pcmWriteChain\n .then(() => this.writeIncomingPcm(packageName, base64, event.sampleRate, event.channels))\n .catch(() => undefined)\n }),\n ]\n }\n\n /**\n * The WHEP PeerConnection does not survive the phone changing networks\n * (Wi-Fi↔cellular, or a different Wi-Fi): ICE fails and native parks the source\n * as `failed` while the ACS call itself reconnects on its own. Nudge native to\n * rebuild the subscription whenever the phone's network identity changes during\n * a live meeting. Native ignores the request when the source is healthy on the\n * same URL, so a spurious event costs nothing.\n */\n private watchPhoneNetwork(native: NativeModule): void {\n this.unwatchPhoneNetwork()\n const source = getPhoneNetwork()\n if (!source) return\n this.lastPhoneNetworkKey = null\n try {\n this.phoneNetworkUnsub = source.addEventListener((info) => {\n const key = `${info.type}:${info.isConnected === false ? \"offline\" : \"online\"}`\n const previous = this.lastPhoneNetworkKey\n this.lastPhoneNetworkKey = key\n // First callback is NetInfo replaying the current state, not a change.\n if (previous === null || previous === key) return\n if (info.isConnected === false) return\n void this.restartMediaSource(native, `phone network ${previous} → ${key}`)\n })\n } catch (error) {\n console.warn(\"[AcsMeeting] phone network watch unavailable\", error)\n this.phoneNetworkUnsub = null\n }\n }\n\n private unwatchPhoneNetwork(): void {\n this.phoneNetworkUnsub?.()\n this.phoneNetworkUnsub = null\n this.lastPhoneNetworkKey = null\n }\n\n private async restartMediaSource(native: NativeModule, reason: string): Promise<void> {\n const whepUrl = this.whepUrl\n const softap = this.videoSource?.type === \"softap\"\n // SoftAP media is bound to the scoped hotspot, not the phone's default route. Joining that\n // hotspot is what *causes* NetInfo to flap `none:offline → cellular:online` — the default\n // route looks gone for a beat, then cellular comes back. Rebuilding the WHIP listener on\n // that flap changes the ingest port after the glasses already have the old URL, and their\n // POST hits a tombstone (HTTP 410). A real hotspot loss is `onScopedNetworkLost`, not this\n // default-network watch. WHEP still needs the rebuild: that path rides the default route.\n if (softap) return\n if (!this.owner || !MEDIA_ACTIVE_PHASES.has(this.lastState.state)) return\n if (!whepUrl) return\n const now = Date.now()\n if (now - this.lastMediaRestartAt < MEDIA_RESTART_MIN_INTERVAL_MS) return\n this.lastMediaRestartAt = now\n console.log(\"[AcsMeeting] phase=media-restart\", {reason, mediaSource: this.lastState.mediaSource})\n try {\n // A same-URL updateVideoSource is a no-op while native still believes the\n // peer is healthy; after a network switch that belief is exactly what is wrong.\n if (native.restartVideoSource) await native.restartVideoSource()\n else if (whepUrl) await native.updateVideoSource(whepUrl)\n else console.warn(\"[AcsMeeting] softap restart needs a native restartVideoSource\", {reason})\n } catch (error) {\n console.warn(\"[AcsMeeting] media restart failed\", {reason, error})\n }\n }\n\n /**\n * Native normalizes to 16 kHz mono, so this is normally a straight write.\n * If the format ever differs, reopen the player to match rather than play\n * the bytes at the wrong rate (that is what slows and deepens the audio).\n */\n private async writeIncomingPcm(\n packageName: string,\n base64: string,\n rawRate: unknown,\n rawChannels: unknown,\n ): Promise<void> {\n const sampleRate = Number(rawRate) || 16000\n const channels = Number(rawChannels) || 1\n if (!PCM_SAMPLE_RATES.has(sampleRate) || channels !== 1) {\n console.warn(\"[AcsMeeting] incoming PCM format unsupported; dropping chunk\", {sampleRate, channels})\n return\n }\n if (this.pcmFormat && (this.pcmFormat.sampleRate !== sampleRate || this.pcmFormat.channels !== channels)) {\n if (!this.pcmReopen) {\n console.warn(\"[AcsMeeting] incoming PCM format changed; reopening player\", {\n from: this.pcmFormat,\n to: {sampleRate, channels},\n })\n this.pcmReopen = this.stopPcm()\n .then(() => this.ensurePcmPlayback(packageName, sampleRate, channels))\n .finally(() => {\n this.pcmReopen = null\n })\n }\n await this.pcmReopen\n } else if (!this.pcmStreamId) {\n await this.ensurePcmPlayback(packageName, sampleRate, channels)\n }\n const streamId = this.pcmStreamId\n if (!streamId) return\n try {\n const result = await audioPlaybackService.writeStreamChunk(streamId, base64)\n const bufferedMs = result?.bufferedMs\n if (typeof bufferedMs === \"number\" && bufferedMs > PCM_BACKLOG_WARN_MS) {\n const now = Date.now()\n if (now - this.lastBacklogWarnAt > 5000) {\n this.lastBacklogWarnAt = now\n console.warn(\"[AcsMeeting] incoming PCM backlog high (downlink playback, not glasses mic)\", {bufferedMs})\n }\n }\n } catch (error) {\n console.warn(\"[AcsMeeting] incoming PCM write failed\", error)\n }\n }\n\n private async ensurePcmPlayback(packageName: string, sampleRate = 16000, channels = 1): Promise<void> {\n if (this.pcmStreamId) return\n const streamId = `acs-in-${packageName}-${Date.now()}`\n await audioPlaybackService.openStream({\n streamId,\n appId: packageName,\n sampleRate,\n channels,\n stopOtherAudio: true,\n jitterMs: PCM_JITTER_MS,\n onEnded: () => {\n if (this.pcmStreamId === streamId) {\n this.pcmStreamId = null\n this.pcmFormat = null\n }\n },\n })\n this.pcmStreamId = streamId\n this.pcmFormat = {sampleRate, channels}\n }\n\n private async stopPcm(): Promise<void> {\n const streamId = this.pcmStreamId\n this.pcmStreamId = null\n this.pcmFormat = null\n if (!streamId) return\n await audioPlaybackService.abortStream(streamId).catch(() => undefined)\n }\n}\n\nconst acsMeetingService = new AcsMeetingService()\nexport default acsMeetingService\n"]}
|