mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-03-30 16:25:57 +00:00
android: sound from speaker fix (#4067)
This commit is contained in:
committed by
GitHub
parent
bea19f76e9
commit
4c1dfc76d4
@@ -18,7 +18,7 @@ interface CallAudioDeviceManagerInterface {
|
||||
fun start()
|
||||
fun stop()
|
||||
// AudioDeviceInfo.AudioDeviceType
|
||||
fun selectLastExternalDeviceOrDefault(speaker: Boolean, keepAnyNonEarpiece: Boolean)
|
||||
fun selectLastExternalDeviceOrDefault(speaker: Boolean, keepAnyExternal: Boolean)
|
||||
// AudioDeviceInfo.AudioDeviceType
|
||||
fun selectDevice(id: Int)
|
||||
|
||||
@@ -74,24 +74,24 @@ class PostSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
|
||||
am.removeOnCommunicationDeviceChangedListener(listener)
|
||||
}
|
||||
|
||||
override fun selectLastExternalDeviceOrDefault(speaker: Boolean, keepAnyNonEarpiece: Boolean) {
|
||||
override fun selectLastExternalDeviceOrDefault(speaker: Boolean, keepAnyExternal: Boolean) {
|
||||
Log.d(TAG, "selectLastExternalDeviceOrDefault: set audio mode, speaker enabled: $speaker")
|
||||
val commDevice = am.communicationDevice
|
||||
if (keepAnyNonEarpiece && commDevice != null && commDevice.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) {
|
||||
// some external device or speaker selected already, no need to change it
|
||||
if (keepAnyExternal && commDevice != null && commDevice.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE && commDevice.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
|
||||
// some external device selected already, no need to change it
|
||||
return
|
||||
}
|
||||
|
||||
val preferredSecondaryDevice = if (speaker) AudioDeviceInfo.TYPE_BUILTIN_SPEAKER else AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
|
||||
val externalDevice = devices.value.lastOrNull { it.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER && it.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE }
|
||||
val preferredInternalDevice = if (speaker) AudioDeviceInfo.TYPE_BUILTIN_SPEAKER else AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
|
||||
val externalDevice = devices.value.lastOrNull { it.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE && it.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER }
|
||||
// External device already selected
|
||||
if (externalDevice != null && externalDevice.type == am.communicationDevice?.type) {
|
||||
return
|
||||
}
|
||||
if (externalDevice != null) {
|
||||
am.setCommunicationDevice(externalDevice)
|
||||
} else if (am.communicationDevice?.type != preferredSecondaryDevice) {
|
||||
am.availableCommunicationDevices.firstOrNull { it.type == preferredSecondaryDevice }?.let {
|
||||
} else if (am.communicationDevice?.type != preferredInternalDevice) {
|
||||
am.availableCommunicationDevices.firstOrNull { it.type == preferredInternalDevice }?.let {
|
||||
am.setCommunicationDevice(it)
|
||||
}
|
||||
}
|
||||
@@ -136,25 +136,25 @@ class PreSCallAudioDeviceManager: CallAudioDeviceManagerInterface {
|
||||
am.stopBluetoothSco()
|
||||
}
|
||||
|
||||
override fun selectLastExternalDeviceOrDefault(speaker: Boolean, keepAnyNonEarpiece: Boolean) {
|
||||
override fun selectLastExternalDeviceOrDefault(speaker: Boolean, keepAnyExternal: Boolean) {
|
||||
Log.d(TAG, "selectLastExternalDeviceOrDefault: set audio mode, speaker enabled: $speaker")
|
||||
val preferredSecondaryDevice = if (speaker) AudioDeviceInfo.TYPE_BUILTIN_SPEAKER else AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
|
||||
val externalDevice = devices.value.lastOrNull { it.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER && it.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE }
|
||||
val preferredInternalDevice = if (speaker) AudioDeviceInfo.TYPE_BUILTIN_SPEAKER else AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
|
||||
val externalDevice = devices.value.lastOrNull { it.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE && it.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER }
|
||||
if (externalDevice != null) {
|
||||
selectDevice(externalDevice.id)
|
||||
} else {
|
||||
am.stopBluetoothSco()
|
||||
am.isWiredHeadsetOn = false
|
||||
am.isSpeakerphoneOn = preferredSecondaryDevice == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
|
||||
am.isSpeakerphoneOn = preferredInternalDevice == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
|
||||
am.isBluetoothScoOn = false
|
||||
val newCurrentDevice = devices.value.firstOrNull { it.type == preferredSecondaryDevice }
|
||||
val newCurrentDevice = devices.value.firstOrNull { it.type == preferredInternalDevice }
|
||||
adaptToCurrentlyActiveDevice(newCurrentDevice)
|
||||
}
|
||||
}
|
||||
|
||||
override fun selectDevice(id: Int) {
|
||||
val device = devices.value.lastOrNull { it.id == id }
|
||||
val isExternalDevice = device != null && device.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER && device.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
|
||||
val isExternalDevice = device != null && device.type != AudioDeviceInfo.TYPE_BUILTIN_EARPIECE && device.type != AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
|
||||
if (isExternalDevice) {
|
||||
am.isSpeakerphoneOn = false
|
||||
if (device?.type == AudioDeviceInfo.TYPE_WIRED_HEADSET || device?.type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@@ -126,7 +125,7 @@ actual fun ActiveCallView() {
|
||||
// Starting is delayed to make Android <= 11 working good with Bluetooth
|
||||
callAudioDeviceManager.start()
|
||||
} else {
|
||||
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.soundSpeaker, true)
|
||||
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.supportsVideo(), true)
|
||||
}
|
||||
CallSoundsPlayer.startConnectingCallSound(scope)
|
||||
activeCallWaitDeliveryReceipt(scope)
|
||||
@@ -138,7 +137,7 @@ actual fun ActiveCallView() {
|
||||
// Starting is delayed to make Android <= 11 working good with Bluetooth
|
||||
callAudioDeviceManager.start()
|
||||
} else {
|
||||
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.soundSpeaker, true)
|
||||
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.supportsVideo(), true)
|
||||
}
|
||||
}
|
||||
is WCallResponse.Answer -> withBGApi {
|
||||
@@ -241,11 +240,10 @@ private fun ActiveCallOverlay(call: Call, chatModel: ChatModel, callAudioDeviceM
|
||||
selectDevice = { callAudioDeviceManager.selectDevice(it.id) },
|
||||
toggleVideo = { chatModel.callCommand.add(WCallCommand.Media(CallMediaType.Video, enable = !call.videoEnabled)) },
|
||||
toggleSound = {
|
||||
var call = chatModel.activeCall.value
|
||||
if (call != null) {
|
||||
call = call.copy(soundSpeaker = !call.soundSpeaker)
|
||||
chatModel.activeCall.value = call
|
||||
callAudioDeviceManager.selectLastExternalDeviceOrDefault(call.soundSpeaker, true)
|
||||
val enableSpeaker = callAudioDeviceManager.currentDevice.value?.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
|
||||
val preferredInternalDevice = callAudioDeviceManager.devices.value.firstOrNull { it.type == if (enableSpeaker) AudioDeviceInfo.TYPE_BUILTIN_SPEAKER else AudioDeviceInfo.TYPE_BUILTIN_EARPIECE }
|
||||
if (preferredInternalDevice != null) {
|
||||
callAudioDeviceManager.selectDevice(preferredInternalDevice.id)
|
||||
}
|
||||
},
|
||||
flipCamera = { chatModel.callCommand.add(WCallCommand.Camera(call.localCamera.flipped)) }
|
||||
@@ -308,7 +306,8 @@ private fun ActiveCallOverlayLayout(
|
||||
currentDevice.value == null ||
|
||||
devices.none { it.id == currentDevice.value?.id }
|
||||
) {
|
||||
ToggleSoundButton(call, enabled, toggleSound)
|
||||
val isSpeaker = currentDevice.value?.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
|
||||
ToggleSoundButton(call, enabled, isSpeaker, toggleSound)
|
||||
} else {
|
||||
ExposedDropDownSettingWithIcon(
|
||||
devices.map { Triple(it, it.icon, if (it.name != null) generalGetString(it.name!!) else it.productName.toString()) },
|
||||
@@ -404,8 +403,8 @@ private fun ToggleAudioButton(call: Call, enabled: Boolean = true, toggleAudio:
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ToggleSoundButton(call: Call, enabled: Boolean, toggleSound: () -> Unit) {
|
||||
if (call.soundSpeaker) {
|
||||
private fun ToggleSoundButton(call: Call, enabled: Boolean, speaker: Boolean, toggleSound: () -> Unit) {
|
||||
if (speaker) {
|
||||
ControlButton(call, painterResource(MR.images.ic_volume_up), MR.strings.icon_descr_speaker_off, enabled, toggleSound)
|
||||
} else {
|
||||
ControlButton(call, painterResource(MR.images.ic_volume_down), MR.strings.icon_descr_speaker_on, enabled, toggleSound)
|
||||
|
||||
@@ -20,7 +20,6 @@ data class Call(
|
||||
val sharedKey: String? = null,
|
||||
val audioEnabled: Boolean = true,
|
||||
val videoEnabled: Boolean = localMedia == CallMediaType.Video,
|
||||
val soundSpeaker: Boolean = localMedia == CallMediaType.Video,
|
||||
var localCamera: VideoCamera = VideoCamera.User,
|
||||
val connectionInfo: ConnectionInfo? = null,
|
||||
var connectedAt: Instant? = null,
|
||||
|
||||
Reference in New Issue
Block a user