refactor: more bluetooth improvements

This commit is contained in:
jubb
2021-11-26 17:12:30 +11:00
parent 787fefc237
commit 644213ea32
8 changed files with 69 additions and 72 deletions

View File

@@ -155,8 +155,8 @@ dependencies {
testImplementation 'org.robolectric:shadows-multidex:4.4' testImplementation 'org.robolectric:shadows-multidex:4.4'
} }
def canonicalVersionCode = 236 def canonicalVersionCode = 237
def canonicalVersionName = "1.12.0-ALPHA3" def canonicalVersionName = "1.12.0-ALPHA4"
def postFixSize = 10 def postFixSize = 10
def abiPostFix = ['armeabi-v7a' : 1, def abiPostFix = ['armeabi-v7a' : 1,
@@ -246,6 +246,7 @@ android {
buildTypes { buildTypes {
release { release {
signingConfig signingConfigs.release signingConfig signingConfigs.release
debuggable true
minifyEnabled false minifyEnabled false
} }
debug { debug {

View File

@@ -176,6 +176,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
@Synchronized @Synchronized
private fun terminate() { private fun terminate() {
sendBroadcast(Intent(WebRtcCallActivity.ACTION_END)) sendBroadcast(Intent(WebRtcCallActivity.ACTION_END))
lockManager.updatePhoneState(LockManager.PhoneState.IDLE)
callManager.stop() callManager.stop()
stopForeground(true) stopForeground(true)
} }
@@ -377,7 +378,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
callManager.startOutgoingRinger(OutgoingRinger.Type.RINGING) callManager.startOutgoingRinger(OutgoingRinger.Type.RINGING)
setCallInProgressNotification(TYPE_OUTGOING_RINGING, callManager.recipient) setCallInProgressNotification(TYPE_OUTGOING_RINGING, callManager.recipient)
callManager.insertCallMessage(recipient.address.serialize(), CallMessageType.CALL_OUTGOING) callManager.insertCallMessage(recipient.address.serialize(), CallMessageType.CALL_OUTGOING)
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 2, TimeUnit.MINUTES) timeoutExecutor.schedule(TimeoutRunnable(callId, this), 1, TimeUnit.MINUTES)
val expectedState = callManager.currentConnectionState val expectedState = callManager.currentConnectionState
val expectedCallId = callManager.callId val expectedCallId = callManager.callId
@@ -425,7 +426,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
return return
} }
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 2, TimeUnit.MINUTES) timeoutExecutor.schedule(TimeoutRunnable(callId, this), 1, TimeUnit.MINUTES)
callManager.initializeAudioForCall() callManager.initializeAudioForCall()
callManager.initializeVideo(this) callManager.initializeVideo(this)
@@ -490,11 +491,6 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
callManager.handleSetCameraFlip() callManager.handleSetCameraFlip()
} }
private fun handleBluetoothChange(intent: Intent) {
val bluetoothAvailable = intent.getBooleanExtra(EXTRA_AVAILABLE, false)
callManager.postBluetoothAvailable(bluetoothAvailable)
}
private fun handleWiredHeadsetChanged(intent: Intent) { private fun handleWiredHeadsetChanged(intent: Intent) {
callManager.handleWiredHeadsetChanged(intent.getBooleanExtra(EXTRA_AVAILABLE, false)) callManager.handleWiredHeadsetChanged(intent.getBooleanExtra(EXTRA_AVAILABLE, false))
} }
@@ -611,6 +607,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
System.currentTimeMillis() - intent.getLongExtra(EXTRA_TIMESTAMP, -1) > TimeUnit.MINUTES.toMillis(2) System.currentTimeMillis() - intent.getLongExtra(EXTRA_TIMESTAMP, -1) > TimeUnit.MINUTES.toMillis(2)
override fun onDestroy() { override fun onDestroy() {
Log.d(TAG,"onDestroy()")
callManager.unregisterListener(this) callManager.unregisterListener(this)
callReceiver?.let { receiver -> callReceiver?.let { receiver ->
unregisterReceiver(receiver) unregisterReceiver(receiver)
@@ -621,7 +618,6 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
networkChangedReceiver = null networkChangedReceiver = null
callReceiver = null callReceiver = null
uncaughtExceptionHandlerManager?.unregister() uncaughtExceptionHandlerManager?.unregister()
callManager.onDestroy()
super.onDestroy() super.onDestroy()
// shutdown audiomanager // shutdown audiomanager
// unregister network receiver // unregister network receiver

View File

@@ -10,9 +10,6 @@ open class AudioManagerCommand: Parcelable {
@Parcelize @Parcelize
object Initialize: AudioManagerCommand() object Initialize: AudioManagerCommand()
@Parcelize
object Shutdown: AudioManagerCommand()
@Parcelize @Parcelize
object UpdateAudioDeviceState: AudioManagerCommand() object UpdateAudioDeviceState: AudioManagerCommand()

View File

@@ -309,8 +309,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
} else if (json.containsKey("hangup")) { } else if (json.containsKey("hangup")) {
peerConnectionObservers.forEach(WebRtcListener::onHangup) peerConnectionObservers.forEach(WebRtcListener::onHangup)
} }
val videoEnabled = Json.decodeFromString(VideoEnabledMessage.serializer(), byteArray.decodeToString())
_remoteVideoEvents.value = VideoEnabled(videoEnabled.video)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Failed to deserialize data channel message", e) Log.e(TAG, "Failed to deserialize data channel message", e)
} }
@@ -519,7 +517,8 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
fun handleSetMuteVideo(muted: Boolean, lockManager: LockManager) { fun handleSetMuteVideo(muted: Boolean, lockManager: LockManager) {
_videoEvents.value = VideoEnabled(!muted) _videoEvents.value = VideoEnabled(!muted)
peerConnection?.setVideoEnabled(!muted) val connection = peerConnection ?: return
connection.setVideoEnabled(!muted)
dataChannel?.let { channel -> dataChannel?.let { channel ->
val toSend = if (muted) VIDEO_DISABLED_JSON else VIDEO_ENABLED_JSON val toSend = if (muted) VIDEO_DISABLED_JSON else VIDEO_ENABLED_JSON
val buffer = DataChannel.Buffer(ByteBuffer.wrap(toSend.toString().encodeToByteArray()), false) val buffer = DataChannel.Buffer(ByteBuffer.wrap(toSend.toString().encodeToByteArray()), false)
@@ -527,7 +526,7 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
} }
if (currentConnectionState == CallState.STATE_CONNECTED) { if (currentConnectionState == CallState.STATE_CONNECTED) {
if (localCameraState.enabled) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO) if (connection.isVideoEnabled()) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO)
else lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL) else lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL)
} }
@@ -548,10 +547,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
} }
} }
fun postBluetoothAvailable(available: Boolean) {
// TODO: _bluetoothEnabled.value = available
}
fun handleWiredHeadsetChanged(present: Boolean) { fun handleWiredHeadsetChanged(present: Boolean) {
if (currentConnectionState in arrayOf(CallState.STATE_CONNECTED, if (currentConnectionState in arrayOf(CallState.STATE_CONNECTED,
CallState.STATE_DIALING, CallState.STATE_DIALING,
@@ -601,10 +596,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
} }
} }
fun onDestroy() {
signalAudioManager.handleCommand(AudioManagerCommand.Shutdown)
}
fun startIncomingRinger() { fun startIncomingRinger() {
signalAudioManager.handleCommand(AudioManagerCommand.StartIncomingRinger(true)) signalAudioManager.handleCommand(AudioManagerCommand.StartIncomingRinger(true))
} }
@@ -612,7 +603,7 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
fun startCommunication(lockManager: LockManager) { fun startCommunication(lockManager: LockManager) {
signalAudioManager.handleCommand(AudioManagerCommand.Start) signalAudioManager.handleCommand(AudioManagerCommand.Start)
val connection = peerConnection ?: return val connection = peerConnection ?: return
if (localCameraState.enabled) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO) if (connection.isVideoEnabled()) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO)
else lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL) else lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL)
connection.setCommunicationMode() connection.setCommunicationMode()
setAudioEnabled(true) setAudioEnabled(true)
@@ -649,9 +640,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
} }
} }
@Serializable
data class VideoEnabledMessage(val video: Boolean)
interface WebRtcListener: PeerConnection.Observer { interface WebRtcListener: PeerConnection.Observer {
fun onHangup() fun onHangup()
} }

View File

@@ -24,7 +24,7 @@ class PeerConnectionWrapper(context: Context,
private val videoTrack: VideoTrack? private val videoTrack: VideoTrack?
val readyForIce val readyForIce
get() = peerConnection.localDescription != null && peerConnection.remoteDescription != null get() = peerConnection.localDescription != null && peerConnection.remoteDescription != null
init { init {
val turn = PeerConnection.IceServer.builder("turn:freyr.getsession.org").setUsername("session").setPassword("session").createIceServer() val turn = PeerConnection.IceServer.builder("turn:freyr.getsession.org").setUsername("session").setPassword("session").createIceServer()
@@ -269,6 +269,8 @@ class PeerConnectionWrapper(context: Context,
} }
} }
fun isVideoEnabled() = camera.enabled
fun flipCamera() { fun flipCamera() {
camera.flip() camera.flip()
} }

View File

@@ -17,6 +17,9 @@ class IncomingRinger(private val context: Context) {
private val vibrator: Vibrator? = ServiceUtil.getVibrator(context) private val vibrator: Vibrator? = ServiceUtil.getVibrator(context)
var mediaPlayer: MediaPlayer? = null var mediaPlayer: MediaPlayer? = null
val isRinging: Boolean
get() = mediaPlayer?.isPlaying ?: false
fun start(vibrate: Boolean) { fun start(vibrate: Boolean) {
val audioManager = ServiceUtil.getAudioManager(context) val audioManager = ServiceUtil.getAudioManager(context)
mediaPlayer?.release() mediaPlayer?.release()
@@ -31,16 +34,14 @@ class IncomingRinger(private val context: Context) {
} }
mediaPlayer?.let { player -> mediaPlayer?.let { player ->
if (ringerMode == AudioManager.RINGER_MODE_NORMAL) { try {
try { if (!player.isPlaying) {
if (!player.isPlaying) { player.prepare()
player.prepare() player.start()
player.start() Log.i(TAG,"Playing ringtone")
Log.i(TAG,"Playing ringtone")
}
} catch (e: Exception) {
Log.e(TAG,"Failed to start mediaPlayer", e)
} }
} catch (e: Exception) {
Log.e(TAG,"Failed to start mediaPlayer", e)
} }
} ?: run { } ?: run {
Log.w(TAG,"Not ringing, mediaPlayer: ${mediaPlayer?.let{"available"}}, mode: $ringerMode") Log.w(TAG,"Not ringing, mediaPlayer: ${mediaPlayer?.let{"available"}}, mode: $ringerMode")

View File

@@ -11,6 +11,7 @@ import android.os.HandlerThread
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.webrtc.AudioManagerCommand import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
import org.thoughtcrime.securesms.webrtc.audio.SignalBluetoothManager.State as BState
private val TAG = Log.tag(SignalAudioManager::class.java) private val TAG = Log.tag(SignalAudioManager::class.java)
@@ -68,7 +69,6 @@ class SignalAudioManager(private val context: Context,
} }
handler?.post { handler?.post {
when (command) { when (command) {
is AudioManagerCommand.Shutdown -> shutdown()
is AudioManagerCommand.UpdateAudioDeviceState -> updateAudioDeviceState() is AudioManagerCommand.UpdateAudioDeviceState -> updateAudioDeviceState()
is AudioManagerCommand.Start -> start() is AudioManagerCommand.Start -> start()
is AudioManagerCommand.Stop -> stop(command.playDisconnect) is AudioManagerCommand.Stop -> stop(command.playDisconnect)
@@ -144,15 +144,23 @@ class SignalAudioManager(private val context: Context,
return return
} }
incomingRinger.stop() handler?.post {
outgoingRinger.stop() incomingRinger.stop()
outgoingRinger.stop()
stop(false)
if (commandAndControlThread != null) {
Log.i(TAG, "Shutting down command and control")
commandAndControlThread?.quitSafely()
commandAndControlThread = null
}
}
if (playDisconnect) { if (playDisconnect) {
val volume: Float = androidAudioManager.ringVolumeWithMinimum() val volume: Float = androidAudioManager.ringVolumeWithMinimum()
soundPool.play(disconnectedSoundId, volume, volume, 0, 0, 1.0f) soundPool.play(disconnectedSoundId, volume, volume, 0, 0, 1.0f)
} }
state = State.PREINITIALIZED state = State.UNINITIALIZED
wiredHeadsetReceiver?.let { receiver -> wiredHeadsetReceiver?.let { receiver ->
try { try {
@@ -175,19 +183,6 @@ class SignalAudioManager(private val context: Context,
Log.d(TAG, "Stopped") Log.d(TAG, "Stopped")
} }
private fun shutdown() {
handler?.post {
incomingRinger.stop()
outgoingRinger.stop()
stop(false)
if (commandAndControlThread != null) {
Log.i(TAG, "Shutting down command and control")
commandAndControlThread?.quitSafely()
commandAndControlThread = null
}
}
}
private fun updateAudioDeviceState() { private fun updateAudioDeviceState() {
handler!!.assertHandlerThread() handler!!.assertHandlerThread()
@@ -223,7 +218,7 @@ class SignalAudioManager(private val context: Context,
var audioDeviceSetUpdated = audioDevices != newAudioDevices var audioDeviceSetUpdated = audioDevices != newAudioDevices
audioDevices = newAudioDevices audioDevices = newAudioDevices
if (signalBluetoothManager!!.state == SignalBluetoothManager.State.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) { if (signalBluetoothManager!!.state == BState.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) {
userSelectedAudioDevice = AudioDevice.NONE userSelectedAudioDevice = AudioDevice.NONE
} }
@@ -236,13 +231,14 @@ class SignalAudioManager(private val context: Context,
userSelectedAudioDevice = AudioDevice.NONE userSelectedAudioDevice = AudioDevice.NONE
} }
val needBluetoothAudioStart = signalBluetoothManager!!.state == SignalBluetoothManager.State.AVAILABLE && signalBluetoothManager!!.state != SignalBluetoothManager.State.CONNECTING val btState = signalBluetoothManager!!.state
val needBluetoothAudioStart = btState == BState.AVAILABLE &&
(userSelectedAudioDevice == AudioDevice.NONE || userSelectedAudioDevice == AudioDevice.BLUETOOTH || autoSwitchToBluetooth) (userSelectedAudioDevice == AudioDevice.NONE || userSelectedAudioDevice == AudioDevice.BLUETOOTH || autoSwitchToBluetooth)
val needBluetoothAudioStop = (signalBluetoothManager!!.state == SignalBluetoothManager.State.CONNECTED || signalBluetoothManager!!.state != SignalBluetoothManager.State.CONNECTING) && val needBluetoothAudioStop = (btState == BState.CONNECTED || btState == BState.CONNECTING) &&
(userSelectedAudioDevice != AudioDevice.NONE && userSelectedAudioDevice != AudioDevice.BLUETOOTH) (userSelectedAudioDevice != AudioDevice.NONE && userSelectedAudioDevice != AudioDevice.BLUETOOTH)
if (signalBluetoothManager!!.state.hasDevice()) { 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")
} }
@@ -251,18 +247,19 @@ class SignalAudioManager(private val context: Context,
signalBluetoothManager!!.updateDevice() signalBluetoothManager!!.updateDevice()
} }
if (!autoSwitchToBluetooth && signalBluetoothManager!!.state == SignalBluetoothManager.State.UNAVAILABLE) { if (!autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.UNAVAILABLE) {
autoSwitchToBluetooth = true autoSwitchToBluetooth = true
} }
if (needBluetoothAudioStart && !needBluetoothAudioStop) { if (needBluetoothAudioStart && !needBluetoothAudioStop) {
if (!signalBluetoothManager!!.startScoAudio()) { if (!signalBluetoothManager!!.startScoAudio()) {
Log.e(TAG,"Failed to start sco audio")
audioDevices.remove(AudioDevice.BLUETOOTH) audioDevices.remove(AudioDevice.BLUETOOTH)
audioDeviceSetUpdated = true audioDeviceSetUpdated = true
} }
} }
if (autoSwitchToBluetooth && signalBluetoothManager!!.state == SignalBluetoothManager.State.CONNECTED) { if (autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.CONNECTED) {
userSelectedAudioDevice = AudioDevice.BLUETOOTH userSelectedAudioDevice = AudioDevice.BLUETOOTH
autoSwitchToBluetooth = false autoSwitchToBluetooth = false
} }
@@ -342,7 +339,6 @@ class SignalAudioManager(private val context: Context,
private fun startIncomingRinger(vibrate: Boolean) { private fun startIncomingRinger(vibrate: Boolean) {
Log.i(TAG, "startIncomingRinger(): vibrate: $vibrate") Log.i(TAG, "startIncomingRinger(): vibrate: $vibrate")
androidAudioManager.mode = AudioManager.MODE_RINGTONE androidAudioManager.mode = AudioManager.MODE_RINGTONE
setDefaultAudioDevice(AudioDevice.SPEAKER_PHONE, false)
incomingRinger.start(vibrate) incomingRinger.start(vibrate)
} }

View File

@@ -9,6 +9,7 @@ import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.media.AudioManager
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.webrtc.AudioManagerCommand import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@@ -73,7 +74,7 @@ class SignalBluetoothManager(
val bluetoothHeadsetFilter = IntentFilter().apply { val bluetoothHeadsetFilter = IntentFilter().apply {
addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED) addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED) addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)
} }
bluetoothReceiver = BluetoothHeadsetBroadcastReceiver() bluetoothReceiver = BluetoothHeadsetBroadcastReceiver()
@@ -134,7 +135,6 @@ class SignalBluetoothManager(
state = State.CONNECTING state = State.CONNECTING
androidAudioManager.startBluetoothSco() androidAudioManager.startBluetoothSco()
androidAudioManager.isBluetoothScoOn = true
scoConnectionAttempts++ scoConnectionAttempts++
startTimer() startTimer()
@@ -165,7 +165,7 @@ class SignalBluetoothManager(
return return
} }
if (bluetoothAdapter!!.getProfileConnectionState(BluetoothProfile.HEADSET) !in arrayOf(BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED)) { if (bluetoothAdapter!!.getProfileConnectionState(BluetoothProfile.HEADSET) !in arrayOf(BluetoothProfile.STATE_CONNECTED)) {
state = State.UNAVAILABLE state = State.UNAVAILABLE
Log.i(TAG, "No connected bluetooth headset") Log.i(TAG, "No connected bluetooth headset")
} else { } else {
@@ -216,6 +216,7 @@ class SignalBluetoothManager(
private fun onServiceConnected(proxy: BluetoothHeadset?) { private fun onServiceConnected(proxy: BluetoothHeadset?) {
bluetoothHeadset = proxy bluetoothHeadset = proxy
androidAudioManager.isBluetoothScoOn = true
updateAudioDeviceState() updateAudioDeviceState()
} }
@@ -244,9 +245,9 @@ class SignalBluetoothManager(
private fun onAudioStateChanged(audioState: Int, isInitialStateChange: Boolean) { private fun onAudioStateChanged(audioState: Int, isInitialStateChange: Boolean) {
Log.i(TAG, "onAudioStateChanged: state: $state audioState: ${audioState.toStateString()} initialSticky: $isInitialStateChange") Log.i(TAG, "onAudioStateChanged: state: $state audioState: ${audioState.toStateString()} initialSticky: $isInitialStateChange")
if (audioState == BluetoothHeadset.STATE_AUDIO_CONNECTED) { if (audioState == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
cancelTimer() cancelTimer()
if (state === State.CONNECTING) { if (state == State.CONNECTING) {
Log.d(TAG, "Bluetooth audio SCO is now connected") Log.d(TAG, "Bluetooth audio SCO is now connected")
state = State.CONNECTED state = State.CONNECTED
scoConnectionAttempts = 0 scoConnectionAttempts = 0
@@ -254,9 +255,9 @@ class SignalBluetoothManager(
} else { } else {
Log.w(TAG, "Unexpected state ${audioState.toStateString()}") Log.w(TAG, "Unexpected state ${audioState.toStateString()}")
} }
} else if (audioState == BluetoothHeadset.STATE_AUDIO_CONNECTING) { } else if (audioState == AudioManager.SCO_AUDIO_STATE_CONNECTING) {
Log.d(TAG, "Bluetooth audio SCO is now connecting...") Log.d(TAG, "Bluetooth audio SCO is now connecting...")
} else if (audioState == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { } else if (audioState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
Log.d(TAG, "Bluetooth audio SCO is now disconnected") Log.d(TAG, "Bluetooth audio SCO is now disconnected")
if (isInitialStateChange) { if (isInitialStateChange) {
Log.d(TAG, "Ignore ${audioState.toStateString()} initial sticky broadcast.") Log.d(TAG, "Ignore ${audioState.toStateString()} initial sticky broadcast.")
@@ -298,10 +299,17 @@ class SignalBluetoothManager(
} }
} }
} else if (intent.action == BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED) { } else if (intent.action == BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED) {
val connectionState: Int = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED) // val connectionState: Int = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED)
// handler.post {
// if (state != State.UNINITIALIZED) {
// onAudioStateChanged(connectionState, isInitialStickyBroadcast)
// }
// }
} else if (intent.action == AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED) {
val scoState: Int = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, AudioManager.ERROR)
handler.post { handler.post {
if (state != State.UNINITIALIZED) { if (state != State.UNINITIALIZED) {
onAudioStateChanged(connectionState, isInitialStickyBroadcast) onAudioStateChanged(scoState, isInitialStickyBroadcast)
} }
} }
} }
@@ -346,3 +354,11 @@ private fun Int.toStateString(): String {
else -> "UNKNOWN" else -> "UNKNOWN"
} }
} }
private fun Int.toScoString(): String = when (this) {
AudioManager.SCO_AUDIO_STATE_DISCONNECTED -> "DISCONNECTED"
AudioManager.SCO_AUDIO_STATE_CONNECTED -> "CONNECTED"
AudioManager.SCO_AUDIO_STATE_CONNECTING -> "CONNECTING"
AudioManager.SCO_AUDIO_STATE_ERROR -> "ERROR"
else -> "UNKNOWN"
}