Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -921,15 +921,17 @@ class CallActivity : CallBaseActivity() {
fun setDefaultAudioOutputChannel(selectedAudioDevice: AudioDevice?) {
if (audioManager != null) {
audioManager!!.setDefaultAudioDevice(selectedAudioDevice)
updateAudioOutputButton(audioManager!!.currentAudioDevice)
updateAudioOutputButton(audioManager!!.audioDeviceForUi)
}
}

fun setAudioOutputChannel(selectedAudioDevice: AudioDevice?) {
if (audioManager != null) {
audioManager!!.selectAudioDevice(selectedAudioDevice)
updateAudioOutputButton(audioManager!!.currentAudioDevice)
fun setAudioOutputChannel(selectedAudioDevice: AudioDevice?): Boolean {
val activeAudioManager = audioManager ?: return false
val accepted = activeAudioManager.selectAudioDevice(selectedAudioDevice)
if (accepted) {
updateAudioOutputButton(activeAudioManager.audioDeviceForUi)
}
return accepted
}

private fun updateAudioOutputButton(activeAudioDevice: AudioDevice) {
Expand Down Expand Up @@ -1144,7 +1146,7 @@ class CallActivity : CallBaseActivity() {
if (audioOutputDialog != null) {
audioOutputDialog!!.updateOutputDeviceList()
}
updateAudioOutputButton(currentDevice)
updateAudioOutputButton(audioManager?.audioDeviceForUi ?: currentDevice)
}

private fun cameraInitialization() {
Expand Down
27 changes: 16 additions & 11 deletions app/src/main/java/com/nextcloud/talk/ui/dialog/AudioOutputDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,26 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call
}

fun updateOutputDeviceList() {
if (callActivity.audioManager?.audioDevices?.contains(WebRtcAudioManager.AudioDevice.BLUETOOTH) == false) {
val activeAudioManager = callActivity.audioManager
if (activeAudioManager?.audioDevices?.contains(WebRtcAudioManager.AudioDevice.BLUETOOTH) != true) {
dialogAudioOutputBinding.audioOutputBluetooth.visibility = View.GONE
} else {
dialogAudioOutputBinding.audioOutputBluetooth.visibility = View.VISIBLE
}

if (callActivity.audioManager?.audioDevices?.contains(WebRtcAudioManager.AudioDevice.EARPIECE) == false) {
if (activeAudioManager?.audioDevices?.contains(WebRtcAudioManager.AudioDevice.EARPIECE) != true) {
dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.GONE
} else {
dialogAudioOutputBinding.audioOutputEarspeaker.visibility = View.VISIBLE
}

if (callActivity.audioManager?.audioDevices?.contains(WebRtcAudioManager.AudioDevice.SPEAKER_PHONE) == false) {
if (activeAudioManager?.audioDevices?.contains(WebRtcAudioManager.AudioDevice.SPEAKER_PHONE) != true) {
dialogAudioOutputBinding.audioOutputSpeaker.visibility = View.GONE
} else {
dialogAudioOutputBinding.audioOutputSpeaker.visibility = View.VISIBLE
}

if (callActivity.audioManager?.currentAudioDevice?.equals(
if (activeAudioManager?.currentAudioDevice?.equals(
WebRtcAudioManager.AudioDevice.WIRED_HEADSET
) == true
) {
Expand All @@ -77,7 +78,8 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call
}

private fun highlightActiveOutputChannel() {
when (callActivity.audioManager?.currentAudioDevice) {
viewThemeUtils.platform.themeDialogDark(dialogAudioOutputBinding.root)
when (callActivity.audioManager?.audioDeviceForUi) {
WebRtcAudioManager.AudioDevice.BLUETOOTH -> {
viewThemeUtils.platform.colorImageView(
dialogAudioOutputBinding.audioOutputBluetoothIcon,
Expand Down Expand Up @@ -118,18 +120,21 @@ class AudioOutputDialog(val callActivity: CallActivity) : BottomSheetDialog(call

private fun initClickListeners() {
dialogAudioOutputBinding.audioOutputBluetooth.setOnClickListener {
callActivity.setAudioOutputChannel(WebRtcAudioManager.AudioDevice.BLUETOOTH)
dismiss()
if (callActivity.setAudioOutputChannel(WebRtcAudioManager.AudioDevice.BLUETOOTH)) {
dismiss()
}
}

dialogAudioOutputBinding.audioOutputSpeaker.setOnClickListener {
callActivity.setAudioOutputChannel(WebRtcAudioManager.AudioDevice.SPEAKER_PHONE)
dismiss()
if (callActivity.setAudioOutputChannel(WebRtcAudioManager.AudioDevice.SPEAKER_PHONE)) {
dismiss()
}
}

dialogAudioOutputBinding.audioOutputEarspeaker.setOnClickListener {
callActivity.setAudioOutputChannel(WebRtcAudioManager.AudioDevice.EARPIECE)
dismiss()
if (callActivity.setAudioOutputChannel(WebRtcAudioManager.AudioDevice.EARPIECE)) {
dismiss()
}
}
}

Expand Down
58 changes: 58 additions & 0 deletions app/src/main/java/com/nextcloud/talk/webrtc/AudioRoutePolicy.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Nextcloud Talk - Android Client
*
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package com.nextcloud.talk.webrtc

import android.media.AudioDeviceInfo
import com.nextcloud.talk.webrtc.WebRtcAudioManager.AudioDevice

internal object AudioRoutePolicy {
@JvmStatic
fun selectAudioDevice(
availableDevices: Set<AudioDevice>,
userSelectedDevice: AudioDevice,
defaultDevice: AudioDevice,
hasWiredHeadset: Boolean,
bluetoothConnected: Boolean
): AudioDevice =
when {
bluetoothConnected -> AudioDevice.BLUETOOTH
hasWiredHeadset -> AudioDevice.WIRED_HEADSET
userSelectedDevice != AudioDevice.NONE &&
userSelectedDevice != AudioDevice.BLUETOOTH &&
availableDevices.contains(userSelectedDevice) -> userSelectedDevice
defaultDevice != AudioDevice.NONE && availableDevices.contains(defaultDevice) -> defaultDevice
availableDevices.contains(AudioDevice.EARPIECE) -> AudioDevice.EARPIECE
availableDevices.contains(AudioDevice.SPEAKER_PHONE) -> AudioDevice.SPEAKER_PHONE
else -> AudioDevice.NONE
}

@JvmStatic
fun shouldPreferBluetooth(
userSelectedDevice: AudioDevice,
bluetoothCurrentlyPreferred: Boolean,
bluetoothExpected: Boolean,
bluetoothUnavailable: Boolean
): Boolean =
when {
userSelectedDevice == AudioDevice.BLUETOOTH -> true
userSelectedDevice != AudioDevice.NONE -> false
bluetoothExpected -> true
else -> bluetoothCurrentlyPreferred && !bluetoothUnavailable
}

@JvmStatic
fun shouldSetCommunicationDevice(currentRouteMatches: Boolean, bluetoothSelectionActive: Boolean): Boolean =
!currentRouteMatches || bluetoothSelectionActive

@JvmStatic
fun isWiredCommunicationDeviceType(type: Int): Boolean =
type == AudioDeviceInfo.TYPE_WIRED_HEADSET ||
type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES ||
type == AudioDeviceInfo.TYPE_USB_HEADSET ||
type == AudioDeviceInfo.TYPE_USB_DEVICE ||
type == AudioDeviceInfo.TYPE_USB_ACCESSORY
}
Loading