I am developing a one way live stream and there is no need to ever send the audio to the Viewer's device's Earpierce, so I am using media: 'video' and also auto: true.
Initially, if the Viewer has no connected Bluetooth headsets, audio routes to the SpeakerPhone. If they have a connected Bluetooth headset when the join the stream or if they connect one midway, it will route to the device.
The issue arises when the Viewer turn off their only available Bluetooth headset. The AppRTCBluetoothManager identifies that a device was removed and that it needs to call BluetoothAudioDeviceCallback#updateDeviceList but does not perform the state updates needed to appropriately re-route to the SpeakerPhone.
Based on the native logs, bluetoothManager.getState() remains equal to AppRTCBluetoothManager.State.SCO_CONNECTED. This mean the selected audio device is still equal to AudioDevice.BLUETOOTH despite there being no Bluetooth device available. As a result, the device defaults back to the Earpiece and the audio routing remains in a denormalized/broken state until the call is restarted.
Reproduction Steps:
Using InCallManager.start({ media: 'video', auto: true });
Join call with no Bluetooth Device Connected, Audio Routes to the SpeakerPhone
Connect a Bluetooth Device, Audio routes to new device
Turn Bluetooth Device Off, Audio routes to Earpiece
Attempt to reconnect Bluetooth Device, Audio remains routed to Earpiece
To get my app working, I used patch-package to add bluetoothState = State.HEADSET_UNAVAILABLE; when newBtDevice === null. Im not sure how this would effect other use cases, but its a pretty simple change that appears to be handling my issue.
private class BluetoothAudioDeviceCallback extends AudioDeviceCallback {
...
private void updateDeviceList() {
final AudioDeviceInfo newBtDevice = getScoDevice();
boolean needChange = false;
if (bluetoothAudioDevice != null && newBtDevice == null) {
needChange = true;
// NEW LINE
bluetoothState = State.HEADSET_UNAVAILABLE;
} else if (bluetoothAudioDevice == null && newBtDevice != null) {
needChange = true;
} else if (bluetoothAudioDevice != null && bluetoothAudioDevice.getId() != newBtDevice.getId()) {
needChange = true;
}
if (needChange) {
updateAudioDeviceState();
}
}
}
Issue
I am developing a one way live stream and there is no need to ever send the audio to the
Viewer
's device'sEarpierce
, so I am usingmedia: 'video'
and alsoauto: true
.Initially, if the
Viewer
has no connectedBluetooth
headsets, audio routes to theSpeakerPhone
. If they have a connectedBluetooth
headset when the join the stream or if they connect one midway, it will route to the device.The issue arises when the
Viewer
turn off their only availableBluetooth
headset. TheAppRTCBluetoothManager
identifies that a device was removed and that it needs to callBluetoothAudioDeviceCallback#updateDeviceList
but does not perform the state updates needed to appropriately re-route to theSpeakerPhone
.Based on the native logs,
bluetoothManager.getState()
remains equal toAppRTCBluetoothManager.State.SCO_CONNECTED
. This mean theselected
audio device is still equal toAudioDevice.BLUETOOTH
despite there being noBluetooth
device available. As a result, the device defaults back to theEarpiece
and the audio routing remains in a denormalized/broken state until the call is restarted.Reproduction Steps:
Using
InCallManager.start({ media: 'video', auto: true });
To get my app working, I used patch-package to add
bluetoothState = State.HEADSET_UNAVAILABLE;
whennewBtDevice === null
. Im not sure how this would effect other use cases, but its a pretty simple change that appears to be handling my issue.