Bug: Releasing a microphone stream causes Bluetooth headphones to remain in HSP/HFP (bidirectional profile) for approximately 10 seconds
Status: UNCONFIRMED
Priority: --
Created: 2025-03-05 03:40:56+00:00
Resolved: 2025-03-05 03:40:56+00:00

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:136.0) Gecko/20100101 Firefox/136.0

Steps to reproduce:

- Connect Bluetooth headphones with a mic to your mac (I'm using Bose QuietComfort, but this happens with any)
- Optional: play music on your system (just helps you hear dropouts/effects)
- Visit https://jsfiddle.net/kirbysayshi/qe39swLv/
- click either button in the fiddle, or run the following code in a console:

```
navigator.mediaDevices.getUserMedia({audio: true}).then(s => s.getTracks().forEach(t => t.stop()));
setTimeout(() => console.log("audio dropout about now"), 10000);
```

- Quickly accept microphone permissions prompt


Actual results:

If you have bluetooth headphones, you will hear:

- the bidirectional profile activate immediately as if you are entering a cell phone call (my headphones actually beep)
- if you are playing other audio, you'll hear it degrade in quality (mono) due to the profile switch (NOTE: this is expected, not the bug!)
- after 10 seconds, all audio will completely fade out (lasts ~1.5s)
- audio returns in R2DP (high quality)

If you are only using wired headphones and wired mic, you will hear:

- a "click or pop" immediately (an audio dropout?)
- any playing audio will remain in normal quality (as it should)
- after 10 seconds, you'll hear another audio dropout

Note that in both scenarios, the Microphone Activity Icon in the URL Bar / Tab will momentarily activate (turn active/red) but immediately turn off, even while the bidirectional profile is active.


Expected results:

If you have bluetooth headphones, you should hear:

- the bidirectional profile activate immediately as if you are entering a cell phone call (my headphones actually beep)
- the profile immediately switch back to A2DP (high quality)

Alternatively: hear no change since the stream is immediately closed.

If you are only using wired headphones and wired mic, you should hear:

- whatever audio is already playing normally, with no dropouts

Some additional details:

On Chrome 133 the sequence is (bluetooth):

- fade out (0.5s), followed by immediate profile switch
- the bidirectional profile stays active for about 2 seconds
- audio cuts out for ~1s as the profile returns to A2DP

On Chrome 133 the sequence is (wired):

- nothing audible, no audio dropouts, appears to be a noop

On Safari 18.3 the sequence is (bluetooth):

- immediate profile change, system audio is ducked
- the bidirectional profile stays active for about 3 seconds
- quick fade out to silence, ~1s later audio returns in A2DP

On Safari 18.3 the sequence is (wired):

- system audio is ducked
- ducking remains for about 3.5 seconds
- ducking returns to normal volume

In summary:

It seems that Firefox is not immediately releasing the input device, causing the bidirectional bluetooth profile (e.g. "it sounds like a call") to remain active for a much longer time than necessary: approximately 10 seconds.

Closing the tab has no effect on the observed behavior.

To avoid confusion, the code attached to this bug is contrived to demonstrate the simplest case. Even if the mic is left open for any length of time, it still takes ~10 seconds for Firefox to return to A2DP.

Overall, this is an issue for multimedia applications that open and close the microphone during the app and afterwards wish to relay important audio to the user. There is currently no mechanism to know when the profile will switch, so for the app I'm currently working on, we have to wait 12 seconds after closing the mic (heuristic, Firefox-only; you can see a version of this in the Fiddle as a demonstration). Otherwise, the combination of Firefox's 10s + fade out causes critical audio to be dropped at a non-deterministic time. For something continuous, such as a narration, even the 1.5s of dropout in the middle of a sentence can cut off words and obstruct the meaning.

Curiously related bugs:

- https://bugzilla.mozilla.org/show_bug.cgi?id=1867553: somehow visiting this only remains in bidirectional profile for ~3-4 seconds (fade still obstructs audio)
- https://bugzilla.mozilla.org/show_bug.cgi?id=1301737: I can not reproduce this.