diff --git a/vector/src/main/java/im/vector/app/features/call/CallSoundDeviceChooserBottomSheet.kt b/vector/src/main/java/im/vector/app/features/call/CallSoundDeviceChooserBottomSheet.kt index a011952549..1b83f58928 100644 --- a/vector/src/main/java/im/vector/app/features/call/CallSoundDeviceChooserBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/call/CallSoundDeviceChooserBottomSheet.kt @@ -21,7 +21,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel -import im.vector.app.R import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.databinding.BottomSheetGenericListBinding @@ -52,23 +51,28 @@ class CallSoundDeviceChooserBottomSheet : VectorBaseBottomSheetDialogFragment, current: CallAudioManager.Device) { views.bottomSheetRecyclerView.withModels { available.forEach { device -> - bottomSheetActionItem { - id(device.ordinal) - textRes(device.titleRes) - iconRes(device.drawableRes) - selected(current == device) - listener { - callViewModel.handle(VectorCallViewActions.ChangeAudioDevice(device)) - dismiss() - } + val title = when (device) { + is CallAudioManager.Device.WirelessHeadset -> device.name ?: getString(device.titleRes) + else -> getString(device.titleRes) + } + + bottomSheetActionItem { + id(device.titleRes) + text(title) + iconRes(device.drawableRes) + selected(current == device) + listener { + callViewModel.handle(VectorCallViewActions.ChangeAudioDevice(device)) + dismiss() } } } } +} - companion object { - fun newInstance(): RoomListQuickActionsBottomSheet { - return RoomListQuickActionsBottomSheet() - } +companion object { + fun newInstance(): RoomListQuickActionsBottomSheet { + return RoomListQuickActionsBottomSheet() } } +} diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt index 4c268ac8fb..8b96583406 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt @@ -146,7 +146,7 @@ class VectorCallViewModel @AssistedInject constructor( override fun onAudioDevicesChange() { val currentSoundDevice = callManager.audioManager.selectedDevice ?: return - if (currentSoundDevice == CallAudioManager.Device.PHONE) { + if (currentSoundDevice == CallAudioManager.Device.Phone) { proximityManager.start() } else { proximityManager.stop() @@ -184,7 +184,7 @@ class VectorCallViewModel @AssistedInject constructor( callManager.addCurrentCallListener(currentCallListener) webRtcCall.addListener(callListener) val currentSoundDevice = callManager.audioManager.selectedDevice - if (currentSoundDevice == CallAudioManager.Device.PHONE) { + if (currentSoundDevice == CallAudioManager.Device.Phone) { proximityManager.start() } setState { @@ -194,7 +194,7 @@ class VectorCallViewModel @AssistedInject constructor( isVideoCall = webRtcCall.mxCall.isVideoCall, callState = Success(webRtcCall.mxCall.state), callInfo = webRtcCall.extractCallInfo(), - device = currentSoundDevice ?: CallAudioManager.Device.PHONE, + device = currentSoundDevice ?: CallAudioManager.Device.Phone, isLocalOnHold = webRtcCall.isLocalOnHold, isRemoteOnHold = webRtcCall.isRemoteOnHold, availableDevices = callManager.audioManager.availableDevices, diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewState.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewState.kt index 3e7791cc08..a351806e1a 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewState.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewState.kt @@ -35,7 +35,7 @@ data class VectorCallViewState( val isHD: Boolean = false, val isFrontCamera: Boolean = true, val canSwitchCamera: Boolean = true, - val device: CallAudioManager.Device = CallAudioManager.Device.PHONE, + val device: CallAudioManager.Device = CallAudioManager.Device.Phone, val availableDevices: Set = emptySet(), val callState: Async = Uninitialized, val otherKnownCallInfo: CallInfo? = null, diff --git a/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt b/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt index 4f54f703b4..eafd1eab20 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt @@ -50,13 +50,17 @@ internal class API21AudioDeviceDetector(private val context: Context, private fun getAvailableSoundDevices(): Set { return HashSet().apply { - if (isBluetoothHeadsetOn()) add(CallAudioManager.Device.WIRELESS_HEADSET) - if (isWiredHeadsetOn()) { - add(CallAudioManager.Device.HEADSET) - } else { - add(CallAudioManager.Device.PHONE) + if (isBluetoothHeadsetOn()) { + connectedBlueToothHeadset?.connectedDevices?.forEach { + add(CallAudioManager.Device.WirelessHeadset(it.name)) + } } - add(CallAudioManager.Device.SPEAKER) + if (isWiredHeadsetOn()) { + add(CallAudioManager.Device.Headset) + } else { + add(CallAudioManager.Device.Phone) + } + add(CallAudioManager.Device.Speaker) } } diff --git a/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt b/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt index 7174554d5f..fb17338fd1 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt @@ -33,10 +33,10 @@ internal class API23AudioDeviceDetector(private val audioManager: AudioManager, val deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS) for (info in deviceInfos) { when (info.type) { - AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> devices.add(CallAudioManager.Device.WIRELESS_HEADSET) - AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> devices.add(CallAudioManager.Device.PHONE) - AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> devices.add(CallAudioManager.Device.SPEAKER) - AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_WIRED_HEADSET, TYPE_USB_HEADSET -> devices.add(CallAudioManager.Device.HEADSET) + AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> devices.add(CallAudioManager.Device.WirelessHeadset(info.productName.toString())) + AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> devices.add(CallAudioManager.Device.Phone) + AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> devices.add(CallAudioManager.Device.Speaker) + AudioDeviceInfo.TYPE_WIRED_HEADPHONES, AudioDeviceInfo.TYPE_WIRED_HEADSET, TYPE_USB_HEADSET -> devices.add(CallAudioManager.Device.Headset) } } callAudioManager.replaceDevices(devices) diff --git a/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt b/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt index 7797cec929..41a31b71e9 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt @@ -23,6 +23,7 @@ import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.core.content.getSystemService import im.vector.app.R +import im.vector.app.core.resources.StringProvider import org.matrix.android.sdk.api.extensions.orFalse import timber.log.Timber import java.util.HashSet @@ -34,11 +35,11 @@ class CallAudioManager(private val context: Context, val configChange: (() -> Un private var audioDeviceDetector: AudioDeviceDetector? = null private var audioDeviceRouter: AudioDeviceRouter? = null - enum class Device(@StringRes val titleRes: Int, @DrawableRes val drawableRes: Int) { - PHONE(R.string.sound_device_phone,R.drawable.ic_sound_device_phone), - SPEAKER(R.string.sound_device_speaker,R.drawable.ic_sound_device_speaker), - HEADSET(R.string.sound_device_headset,R.drawable.ic_sound_device_headphone), - WIRELESS_HEADSET(R.string.sound_device_wireless_headset,R.drawable.ic_sound_device_headphone) + sealed class Device(@StringRes val titleRes: Int, @DrawableRes val drawableRes: Int) { + object Phone : Device(R.string.sound_device_phone, R.drawable.ic_sound_device_phone) + object Speaker : Device(R.string.sound_device_speaker, R.drawable.ic_sound_device_speaker) + object Headset : Device(R.string.sound_device_headset, R.drawable.ic_sound_device_headphone) + data class WirelessHeadset(val name: String?) : Device(R.string.sound_device_wireless_headset, R.drawable.ic_sound_device_wireless) } enum class Mode { @@ -136,19 +137,19 @@ class CallAudioManager(private val context: Context, val configChange: (() -> Un userSelectedDevice = null return true } - val bluetoothAvailable = _availableDevices.contains(Device.WIRELESS_HEADSET) - val headsetAvailable = _availableDevices.contains(Device.HEADSET) + val availableBluetoothDevice = _availableDevices.firstOrNull { it is Device.WirelessHeadset } + val headsetAvailable = _availableDevices.contains(Device.Headset) // Pick the desired device based on what's available and the mode. var audioDevice: Device - audioDevice = if (bluetoothAvailable) { - Device.WIRELESS_HEADSET + audioDevice = if (availableBluetoothDevice != null) { + availableBluetoothDevice } else if (headsetAvailable) { - Device.HEADSET + Device.Headset } else if (mode == Mode.VIDEO_CALL) { - Device.SPEAKER + Device.Speaker } else { - Device.PHONE + Device.Phone } // Consider the user's selection if (userSelectedDevice != null && _availableDevices.contains(userSelectedDevice)) { diff --git a/vector/src/main/java/im/vector/app/features/call/audio/DefaultAudioDeviceRouter.kt b/vector/src/main/java/im/vector/app/features/call/audio/DefaultAudioDeviceRouter.kt index c252cc9f89..fd85ce075f 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/DefaultAudioDeviceRouter.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/DefaultAudioDeviceRouter.kt @@ -31,8 +31,8 @@ class DefaultAudioDeviceRouter(private val audioManager: AudioManager, private var focusRequestCompat: AudioFocusRequestCompat? = null override fun setAudioRoute(device: CallAudioManager.Device) { - audioManager.isSpeakerphoneOn = device === CallAudioManager.Device.SPEAKER - setBluetoothAudioRoute(device === CallAudioManager.Device.WIRELESS_HEADSET) + audioManager.isSpeakerphoneOn = device is CallAudioManager.Device.Speaker + setBluetoothAudioRoute(device is CallAudioManager.Device.WirelessHeadset) } override fun setMode(mode: CallAudioManager.Mode): Boolean { diff --git a/vector/src/main/res/drawable/ic_sound_device_wireless.xml b/vector/src/main/res/drawable/ic_sound_device_wireless.xml new file mode 100644 index 0000000000..02287aa96c --- /dev/null +++ b/vector/src/main/res/drawable/ic_sound_device_wireless.xml @@ -0,0 +1,12 @@ + + + +