davidliu
Committed by GitHub

Fix bluetooth mic not being used when no other audio is playing (#244)

1 package io.livekit.android.audio 1 package io.livekit.android.audio
2 2
3 import android.content.Context 3 import android.content.Context
  4 +import android.media.AudioDeviceInfo
4 import android.media.AudioManager 5 import android.media.AudioManager
5 import android.os.Build 6 import android.os.Build
6 import android.os.Handler 7 import android.os.Handler
@@ -74,7 +75,54 @@ constructor(private val context: Context) : AudioHandler { @@ -74,7 +75,54 @@ constructor(private val context: Context) : AudioHandler {
74 ) 75 )
75 } 76 }
76 audioSwitch = switch 77 audioSwitch = switch
77 - switch.start(audioDeviceChangeListener ?: defaultAudioDeviceChangeListener) 78 + switch.start { audioDevices: List<AudioDevice>, selectedAudioDevice: AudioDevice? ->
  79 +
  80 + // On >S, some devices don't properly use bluetooth mic if no audio tracks.
  81 + // Using the new communication devices api fixes this.
  82 + // TODO: Move into AudioSwitch itself
  83 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
  84 + val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
  85 + val commDevices = audioManager.availableCommunicationDevices
  86 +
  87 + val audioDeviceInfo = when (selectedAudioDevice) {
  88 + is AudioDevice.BluetoothHeadset -> {
  89 + commDevices.firstOrNull { info ->
  90 + info.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO || info.type == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
  91 + }
  92 + }
  93 +
  94 + is AudioDevice.Earpiece -> {
  95 + commDevices.firstOrNull { info ->
  96 + info.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
  97 + }
  98 + }
  99 +
  100 + is AudioDevice.Speakerphone -> {
  101 + commDevices.firstOrNull { info ->
  102 + info.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
  103 + }
  104 + }
  105 +
  106 + is AudioDevice.WiredHeadset -> {
  107 + commDevices.firstOrNull { info ->
  108 + info.type == AudioDeviceInfo.TYPE_WIRED_HEADSET || info.type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES
  109 + }
  110 + }
  111 +
  112 + else -> {
  113 + null
  114 + }
  115 + }
  116 +
  117 + if (audioDeviceInfo != null) {
  118 + audioManager.setCommunicationDevice(audioDeviceInfo)
  119 + } else {
  120 + audioManager.clearCommunicationDevice()
  121 + }
  122 + }
  123 +
  124 + audioDeviceChangeListener?.invoke(audioDevices, selectedAudioDevice)
  125 + }
78 switch.activate() 126 switch.activate()
79 } 127 }
80 } 128 }