davidliu
Committed by GitHub

Route AudioSwitch calls through main thread (#120)

... ... @@ -2,6 +2,8 @@ package io.livekit.android.audio
import android.content.Context
import android.media.AudioManager
import android.os.Handler
import android.os.Looper
import com.twilio.audioswitch.AudioDevice
import com.twilio.audioswitch.AudioDeviceChangeListener
import com.twilio.audioswitch.AudioSwitch
... ... @@ -19,23 +21,32 @@ constructor(private val context: Context) : AudioHandler {
private var audioSwitch: AudioSwitch? = null
// AudioSwitch is not threadsafe, so all calls should be done on the main thread.
private val handler = Handler(Looper.getMainLooper())
override fun start() {
if (audioSwitch == null) {
val switch = AudioSwitch(
context = context,
loggingEnabled = loggingEnabled,
audioFocusChangeListener = onAudioFocusChangeListener ?: defaultOnAudioFocusChangeListener,
preferredDeviceList = preferredDeviceList ?: defaultPreferredDeviceList
)
audioSwitch = switch
switch.start(audioDeviceChangeListener ?: defaultAudioDeviceChangeListener)
switch.activate()
handler.removeCallbacksAndMessages(null)
handler.post {
val switch = AudioSwitch(
context = context,
loggingEnabled = loggingEnabled,
audioFocusChangeListener = onAudioFocusChangeListener ?: defaultOnAudioFocusChangeListener,
preferredDeviceList = preferredDeviceList ?: defaultPreferredDeviceList
)
audioSwitch = switch
switch.start(audioDeviceChangeListener ?: defaultAudioDeviceChangeListener)
switch.activate()
}
}
}
override fun stop() {
audioSwitch?.stop()
audioSwitch = null
handler.removeCallbacksAndMessages(null)
handler.post {
audioSwitch?.stop()
audioSwitch = null
}
}
val selectedAudioDevice: AudioDevice?
... ...
... ... @@ -19,21 +19,23 @@ import io.livekit.android.room.participant.Participant
import io.livekit.android.room.participant.RemoteParticipant
import io.livekit.android.room.track.*
import io.livekit.android.util.flow
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import livekit.LivekitRtc
@OptIn(ExperimentalCoroutinesApi::class)
class CallViewModel(
val url: String,
val token: String,
application: Application
) : AndroidViewModel(application) {
val audioHandler = AudioSwitchHandler(application)
val room = LiveKit.create(
appContext = application,
options = RoomOptions(adaptiveStream = true, dynacast = true),
overrides = LiveKitOverrides(
audioHandler = audioHandler
)
)
val participants = room::remoteParticipants.flow
... ... @@ -73,7 +75,6 @@ class CallViewModel(
private val mutablePermissionAllowed = MutableStateFlow(true)
val permissionAllowed = mutablePermissionAllowed.hide()
val audioHandler = AudioSwitchHandler(application)
init {
viewModelScope.launch {
launch {
... ...