diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index d309c164..7cc991bd 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -21,6 +21,7 @@ import android.graphics.ImageDecoder import android.media.AudioAttributes import android.media.AudioManager import android.media.AudioManager.MODE_IN_COMMUNICATION +import android.media.AudioManager.MODE_NORMAL import android.media.MediaPlayer import android.media.Ringtone import android.media.RingtoneManager @@ -1013,8 +1014,10 @@ class BaresipService: Service() { else -> DisconnectCause.REMOTE } connection.setDisconnected(DisconnectCause(cause)) - connection.destroy() - ConnectionService.connections.remove(callp) + Handler(Looper.getMainLooper()).postDelayed({ + connection.destroy() + ConnectionService.connections.remove(callp) + }, 500) } nm.cancel(CALL_NOTIFICATION_ID) if (call != null) { @@ -1046,8 +1049,8 @@ class BaresipService: Service() { val tone = ev[2] if (tone == "busy") playBusy() - else if (!Call.inCall()) { - am.mode = AudioManager.MODE_NORMAL + else { + ensureCommunicationMode() resetCallVolume() proximitySensing(false) } @@ -1060,15 +1063,15 @@ class BaresipService: Service() { val completedElsewhere = missed && ev[2].startsWith("SIP") && ev[2].contains(";cause=200") if (ua.account.callHistory) { - val history = CallHistoryNew(aor, call.peerUri, call.dir) - history.stopTime = GregorianCalendar() - history.startTime = if (completedElsewhere) history.stopTime else call.startTime - history.rejected = call.rejected - if (call.dumpfiles[0] != "") { - history.recording = call.dumpfiles - } - history.add() CoroutineScope(Dispatchers.IO).launch { + val history = CallHistoryNew(aor, call.peerUri, call.dir) + history.stopTime = GregorianCalendar() + history.startTime = if (completedElsewhere) history.stopTime else call.startTime + history.rejected = call.rejected + if (call.dumpfiles[0] != "") { + history.recording = call.dumpfiles + } + history.add() if (call.startTime != null && call.dumpfiles[0] != "") { delay(500) val rxFile = File(call.dumpfiles[0]) @@ -1871,12 +1874,17 @@ class BaresipService: Service() { } private fun ensureCommunicationMode() { - if (Call.inCall() && am.mode != MODE_IN_COMMUNICATION) { - am.mode = MODE_IN_COMMUNICATION - if (VERSION.SDK_INT < 31) - Log.d(TAG, "Manual Mode Guard (SDK < 31): Setting MODE_IN_COMMUNICATION") - else - Log.d(TAG, "Manual Mode Guard (SDK >= 31): Setting MODE_IN_COMMUNICATION") + if (Call.inCall()) { + if (am.mode != MODE_IN_COMMUNICATION) { + am.mode = MODE_IN_COMMUNICATION + Log.d(TAG, "Manual Mode Guard (SDK ${VERSION.SDK_INT}): Setting MODE_IN_COMMUNICATION") + } + } else { + if (am.mode != MODE_NORMAL) { + am.mode = MODE_NORMAL + Log.d(TAG, "Manual Mode Guard (SDK ${VERSION.SDK_INT}): Resetting to MODE_NORMAL") + } + Utils.clearCommunicationDevice(am) } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index d881642b..272b674e 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -868,60 +868,50 @@ object Utils { private fun setSpeakerPhone(executor: Executor, am: AudioManager, enable: Boolean) { if (Build.VERSION.SDK_INT >= 31) { + if (!enable) { + Log.d(TAG, "Disabling speakerphone") + clearCommunicationDevice(am) + if (inCall() && am.mode == AudioManager.MODE_NORMAL) { + Log.d(TAG, "Restoring MODE_IN_COMMUNICATION") + am.mode = AudioManager.MODE_IN_COMMUNICATION + } + return + } val current = am.communicationDevice!!.type Log.d(TAG, "Current com dev/mode is $current/${am.mode}") var speakerDevice: AudioDeviceInfo? = null - if (enable) { - for (device in am.availableCommunicationDevices) - if (device.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) { - speakerDevice = device - break - } - } else { - for (device in am.availableCommunicationDevices) - if (device.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) { - speakerDevice = device - break - } - } + for (device in am.availableCommunicationDevices) + if (device.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) { + speakerDevice = device + break + } if (speakerDevice == null) { Log.w(TAG,"Could not find requested communication device") return } if (current != speakerDevice.type) { - if (speakerDevice.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) { - clearCommunicationDevice(am) - Log.d(TAG, "Setting com device to TYPE_BUILTIN_EARPIECE") + // Currently at API levels 31+, speakerphone needs normal mode + if (am.mode == AudioManager.MODE_NORMAL) { + Log.d(TAG, "Setting com device to ${speakerDevice.type} in MODE_NORMAL") if (!am.setCommunicationDevice(speakerDevice)) Log.e(TAG, "Could not set com device") - if (inCall() && am.mode == AudioManager.MODE_NORMAL) { - Log.d(TAG, "Setting mode to communication") - am.mode = AudioManager.MODE_IN_COMMUNICATION - } } else { - // Currently at API levels 31+, speakerphone needs normal mode - if (am.mode == AudioManager.MODE_NORMAL) { - Log.d(TAG, "Setting com device to ${speakerDevice.type} in MODE_NORMAL") - if (!am.setCommunicationDevice(speakerDevice)) - Log.e(TAG, "Could not set com device") - } else { - val normalListener = object : AudioManager.OnModeChangedListener { - override fun onModeChanged(mode: Int) { - if (mode == AudioManager.MODE_NORMAL) { - am.removeOnModeChangedListener(this) - Log.d( - TAG, "Setting com device to ${speakerDevice.type}" + - " in mode ${am.mode}" - ) - if (!am.setCommunicationDevice(speakerDevice)) - Log.e(TAG, "Could not set com device") - } + val normalListener = object : AudioManager.OnModeChangedListener { + override fun onModeChanged(mode: Int) { + if (mode == AudioManager.MODE_NORMAL) { + am.removeOnModeChangedListener(this) + Log.d( + TAG, "Setting com device to ${speakerDevice.type}" + + " in mode ${am.mode}" + ) + if (!am.setCommunicationDevice(speakerDevice)) + Log.e(TAG, "Could not set com device") } } - am.addOnModeChangedListener(executor, normalListener) - Log.d(TAG, "Setting mode to NORMAL") - am.mode = AudioManager.MODE_NORMAL } + am.addOnModeChangedListener(executor, normalListener) + Log.d(TAG, "Setting mode to NORMAL") + am.mode = AudioManager.MODE_NORMAL } Log.d(TAG, "New com device/mode is ${am.communicationDevice!!.type}/${am.mode}") } @@ -934,17 +924,17 @@ object Utils { fun toggleSpeakerPhone(executor: Executor, am: AudioManager) { if (Build.VERSION.SDK_INT >= 31) { - if (am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) - setSpeakerPhone(executor, am, true) - else if (am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) + if (am.communicationDevice!!.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) setSpeakerPhone(executor, am, false) + else + setSpeakerPhone(executor, am, true) } else { @Suppress("DEPRECATION") setSpeakerPhone(executor, am, !am.isSpeakerphoneOn) } } - private fun clearCommunicationDevice(am: AudioManager) { + fun clearCommunicationDevice(am: AudioManager) { if (Build.VERSION.SDK_INT >= 31) { am.clearCommunicationDevice() } else {