demo · v136

VoIP-style pause & resume

A live Web Audio tone wired to the new interrupted state. Simulate an inbound VoIP call — the tone pauses, shows a "paused by system" overlay, and re-enters running only after the system releases audio focus. Compare the silent failure we used to ship: suspended showing without context.

Probing…
Steady Pulse
Standard Tone Co.
state: no context
source: no oscillator silent
paused by system
Audio focus released to another app.

event log

interrupted vs suspended — same surface, different UX

statewho triggered itcan resume() now?UX hint
suspendedpage (you called .suspend()) or backgrounded tabyes — immediately"paused" — you chose this
interrupted (136+)OS / UA (call, lid close, exclusive audio)no — queued until system releases focus"paused by system — tap to resume"

what the simulator stands in for

buttonreal sourceexpected app response
Simulate VoIP callanother app requests exclusive output hardwareshow system-paused UX, keep audio silent, resume after focus returns
Simulate page-hidesame page intentionally calls suspend()show ordinary paused UX and wait for an explicit resume tap
Auto-resume offapp policy says focus return is not enoughkeep the tone silent and make the manual-resume affordance active

the code

const ac = new AudioContext();

ac.addEventListener("statechange", () => {
  if (ac.state === "interrupted") {
    showSystemPausedOverlay();
  } else if (ac.state === "running") {
    hideOverlay();
  } else if (ac.state === "suspended") {
    showUserPausedOverlay();
  }
});

why this angle

The sibling concept demonstrates the raw state machine — "here are the four states, watch them change." That's the API surface. This concept is the use case: a music-app UX that has to make a different visual choice depending on who paused it. The chromestatus motivation explicitly lists VoIP (exclusive audio access) and the "media-playback-while-not-visible" permission policy as the situations that needed an OS-driven state, separate from page-driven suspended. The comparison table is the answer to "why didn't we just reuse suspended?"

see also