refactor on SignalAudioManager

This commit is contained in:
Ryan Zhao 2023-04-24 15:38:06 +10:00
parent 63d442584c
commit 51856138e3
4 changed files with 53 additions and 60 deletions

View File

@ -799,6 +799,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
wantsToAnswerReceiver?.let { receiver ->
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
}
callManager.shutDownAudioManager()
powerButtonReceiver = null
wiredHeadsetStateReceiver = null
networkChangedReceiver = null

View File

@ -93,6 +93,10 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
peerConnectionObservers.remove(listener)
}
fun shutDownAudioManager() {
signalAudioManager.shutdown()
}
private val _audioEvents = MutableStateFlow(AudioEnabled(false))
val audioEvents = _audioEvents.asSharedFlow()
private val _videoEvents = MutableStateFlow(VideoEnabled(false))

View File

@ -9,6 +9,7 @@ import android.media.SoundPool
import android.os.HandlerThread
import network.loki.messenger.R
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.ThreadUtils
import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
import org.thoughtcrime.securesms.webrtc.audio.SignalBluetoothManager.State as BState
@ -32,10 +33,10 @@ class SignalAudioManager(private val context: Context,
private val eventListener: EventListener?,
private val androidAudioManager: AudioManagerCompat) {
private var commandAndControlThread: HandlerThread? = HandlerThread("call-audio").apply { start() }
private var handler: SignalAudioHandler? = null
private var commandAndControlThread: HandlerThread? = HandlerThread("call-audio", ThreadUtils.PRIORITY_IMPORTANT_BACKGROUND_THREAD).apply { start() }
private var handler: SignalAudioHandler? = SignalAudioHandler(commandAndControlThread!!.looper)
private var signalBluetoothManager: SignalBluetoothManager? = null
private var signalBluetoothManager: SignalBluetoothManager = SignalBluetoothManager(context, this, androidAudioManager, handler!!)
private var state: State = State.UNINITIALIZED
@ -62,12 +63,9 @@ class SignalAudioManager(private val context: Context,
private var wiredHeadsetReceiver: WiredHeadsetReceiver? = null
fun handleCommand(command: AudioManagerCommand) {
if (command == AudioManagerCommand.Initialize) {
initialize()
return
}
handler?.post {
when (command) {
is AudioManagerCommand.Initialize -> initialize()
is AudioManagerCommand.UpdateAudioDeviceState -> updateAudioDeviceState()
is AudioManagerCommand.Start -> start()
is AudioManagerCommand.Stop -> stop(command.playDisconnect)
@ -84,34 +82,37 @@ class SignalAudioManager(private val context: Context,
Log.i(TAG, "Initializing audio manager state: $state")
if (state == State.UNINITIALIZED) {
commandAndControlThread = HandlerThread("call-audio").apply { start() }
handler = SignalAudioHandler(commandAndControlThread!!.looper)
savedAudioMode = androidAudioManager.mode
savedIsSpeakerPhoneOn = androidAudioManager.isSpeakerphoneOn
savedIsMicrophoneMute = androidAudioManager.isMicrophoneMute
hasWiredHeadset = androidAudioManager.isWiredHeadsetOn
signalBluetoothManager = SignalBluetoothManager(context, this, androidAudioManager, handler!!)
androidAudioManager.requestCallAudioFocus()
handler!!.post {
setMicrophoneMute(false)
savedAudioMode = androidAudioManager.mode
savedIsSpeakerPhoneOn = androidAudioManager.isSpeakerphoneOn
savedIsMicrophoneMute = androidAudioManager.isMicrophoneMute
hasWiredHeadset = androidAudioManager.isWiredHeadsetOn
audioDevices.clear()
androidAudioManager.requestCallAudioFocus()
signalBluetoothManager.start()
setMicrophoneMute(false)
updateAudioDeviceState()
audioDevices.clear()
wiredHeadsetReceiver = WiredHeadsetReceiver()
context.registerReceiver(wiredHeadsetReceiver, IntentFilter(AudioManager.ACTION_HEADSET_PLUG))
signalBluetoothManager!!.start()
state = State.PREINITIALIZED
updateAudioDeviceState()
Log.d(TAG, "Initialized")
}
}
wiredHeadsetReceiver = WiredHeadsetReceiver()
context.registerReceiver(wiredHeadsetReceiver, IntentFilter(AudioManager.ACTION_HEADSET_PLUG))
state = State.PREINITIALIZED
Log.d(TAG, "Initialized")
fun shutdown() {
handler!!.post {
stop(false)
if (commandAndControlThread != null) {
Log.i(TAG, "Shutting down command and control")
commandAndControlThread?.quitSafely()
commandAndControlThread = null
}
}
}
@ -138,23 +139,11 @@ class SignalAudioManager(private val context: Context,
private fun stop(playDisconnect: Boolean) {
Log.d(TAG, "Stopping. state: $state")
if (state == State.UNINITIALIZED) {
Log.i(TAG, "Trying to stop AudioManager in incorrect state: $state")
return
}
handler?.post {
incomingRinger.stop()
outgoingRinger.stop()
stop(false)
if (commandAndControlThread != null) {
Log.i(TAG, "Shutting down command and control")
commandAndControlThread?.quitSafely()
commandAndControlThread = null
}
}
incomingRinger.stop()
outgoingRinger.stop()
if (playDisconnect) {
if (playDisconnect && state != State.UNINITIALIZED) {
val volume: Float = androidAudioManager.ringVolumeWithMinimum()
soundPool.play(disconnectedSoundId, volume, volume, 0, 0, 1.0f)
}
@ -170,7 +159,7 @@ class SignalAudioManager(private val context: Context,
}
wiredHeadsetReceiver = null
signalBluetoothManager?.stop()
signalBluetoothManager.stop()
setSpeakerphoneOn(savedIsSpeakerPhoneOn)
setMicrophoneMute(savedIsMicrophoneMute)
@ -189,19 +178,19 @@ class SignalAudioManager(private val context: Context,
TAG,
"updateAudioDeviceState(): " +
"wired: $hasWiredHeadset " +
"bt: ${signalBluetoothManager!!.state} " +
"bt: ${signalBluetoothManager.state} " +
"available: $audioDevices " +
"selected: $selectedAudioDevice " +
"userSelected: $userSelectedAudioDevice"
)
if (signalBluetoothManager!!.state.shouldUpdate()) {
signalBluetoothManager!!.updateDevice()
if (signalBluetoothManager.state.shouldUpdate()) {
signalBluetoothManager.updateDevice()
}
val newAudioDevices = mutableSetOf(AudioDevice.SPEAKER_PHONE)
if (signalBluetoothManager!!.state.hasDevice()) {
if (signalBluetoothManager.state.hasDevice()) {
newAudioDevices += AudioDevice.BLUETOOTH
}
@ -217,7 +206,7 @@ class SignalAudioManager(private val context: Context,
var audioDeviceSetUpdated = audioDevices != newAudioDevices
audioDevices = newAudioDevices
if (signalBluetoothManager!!.state == BState.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) {
if (signalBluetoothManager.state == BState.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) {
userSelectedAudioDevice = AudioDevice.NONE
}
@ -230,7 +219,7 @@ class SignalAudioManager(private val context: Context,
userSelectedAudioDevice = AudioDevice.NONE
}
val btState = signalBluetoothManager!!.state
val btState = signalBluetoothManager.state
val needBluetoothAudioStart = btState == BState.AVAILABLE &&
(userSelectedAudioDevice == AudioDevice.NONE || userSelectedAudioDevice == AudioDevice.BLUETOOTH || autoSwitchToBluetooth)
@ -238,27 +227,27 @@ class SignalAudioManager(private val context: Context,
(userSelectedAudioDevice != AudioDevice.NONE && userSelectedAudioDevice != AudioDevice.BLUETOOTH)
if (btState.hasDevice()) {
Log.i(TAG, "Need bluetooth audio: state: ${signalBluetoothManager!!.state} start: $needBluetoothAudioStart stop: $needBluetoothAudioStop")
Log.i(TAG, "Need bluetooth audio: state: ${signalBluetoothManager.state} start: $needBluetoothAudioStart stop: $needBluetoothAudioStop")
}
if (needBluetoothAudioStop) {
signalBluetoothManager!!.stopScoAudio()
signalBluetoothManager!!.updateDevice()
signalBluetoothManager.stopScoAudio()
signalBluetoothManager.updateDevice()
}
if (!autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.UNAVAILABLE) {
if (!autoSwitchToBluetooth && signalBluetoothManager.state == BState.UNAVAILABLE) {
autoSwitchToBluetooth = true
}
if (needBluetoothAudioStart && !needBluetoothAudioStop) {
if (!signalBluetoothManager!!.startScoAudio()) {
if (!needBluetoothAudioStop && needBluetoothAudioStart) {
if (!signalBluetoothManager.startScoAudio()) {
Log.e(TAG,"Failed to start sco audio")
audioDevices.remove(AudioDevice.BLUETOOTH)
audioDeviceSetUpdated = true
}
}
if (autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.CONNECTED) {
if (autoSwitchToBluetooth && signalBluetoothManager.state == BState.CONNECTED) {
userSelectedAudioDevice = AudioDevice.BLUETOOTH
autoSwitchToBluetooth = false
}

View File

@ -1,13 +1,12 @@
package org.session.libsignal.utilities
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
import android.os.Process
import java.util.concurrent.*
object ThreadUtils {
const val PRIORITY_IMPORTANT_BACKGROUND_THREAD = Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE
val executorPool: ExecutorService = Executors.newCachedThreadPool()
@JvmStatic