From 007f8236767dd51707321e9e3f5f5ee93a562289 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 8 Nov 2022 11:00:56 +0100 Subject: [PATCH] Fixed issues with actively speaking participant device for outgoing group calls --- .../data/ConferenceParticipantDeviceData.kt | 1 + .../voip/viewmodels/ConferenceViewModel.kt | 46 ++++++++++++++----- .../voip_conference_active_speaker.xml | 1 - .../layout/voip_conference_active_speaker.xml | 1 - 4 files changed, 35 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/voip/data/ConferenceParticipantDeviceData.kt b/app/src/main/java/org/linphone/activities/voip/data/ConferenceParticipantDeviceData.kt index b15c782d9..da463586c 100644 --- a/app/src/main/java/org/linphone/activities/voip/data/ConferenceParticipantDeviceData.kt +++ b/app/src/main/java/org/linphone/activities/voip/data/ConferenceParticipantDeviceData.kt @@ -122,6 +122,7 @@ class ConferenceParticipantDeviceData( val state = participantDevice.state isJoining.value = state == ParticipantDeviceState.Joining || state == ParticipantDeviceState.Alerting + Log.i("[Conference Participant Device] State for participant [${participantDevice.address.asStringUriOnly()}] is $state") videoEnabled.value = isVideoAvailableAndSendReceive() videoEnabled.addSource(videoAvailable) { diff --git a/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt b/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt index 8fb1a843e..d8b21bc3a 100644 --- a/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt +++ b/app/src/main/java/org/linphone/activities/voip/viewmodels/ConferenceViewModel.kt @@ -87,11 +87,6 @@ class ConferenceViewModel : ViewModel() { override fun onParticipantRemoved(conference: Conference, participant: Participant) { Log.i("[Conference] Participant removed: ${participant.address.asStringUriOnly()}") updateParticipantsList(conference) - - if (conferenceParticipants.value.orEmpty().isEmpty()) { - speakingParticipant.value?.videoEnabled?.value = false - allParticipantsLeftEvent.value = Event(true) - } } override fun onParticipantDeviceAdded( @@ -115,8 +110,15 @@ class ConferenceViewModel : ViewModel() { Log.i("[Conference] Participant device removed: ${participantDevice.address.asStringUriOnly()}") removeParticipantDevice(participantDevice) - if (conferenceParticipantDevices.value.orEmpty().size == 2) { - secondParticipantJoinedEvent.value = Event(true) + when (conferenceParticipantDevices.value.orEmpty().size) { + 1 -> { + speakingParticipant.value?.videoEnabled?.value = false + allParticipantsLeftEvent.value = Event(true) + } + 2 -> { + secondParticipantJoinedEvent.value = Event(true) + } + else -> {} } } @@ -428,8 +430,11 @@ class ConferenceViewModel : ViewModel() { val devices = arrayListOf() val participantsList = conference.participantList - val activelySpeakingParticipantDevice = conference.activeSpeakerParticipantDevice Log.i("[Conference] Conference has ${participantsList.size} participants") + + val activelySpeakingParticipantDevice = conference.activeSpeakerParticipantDevice + var foundActivelySpeakingParticipantDevice = false + for (participant in participantsList) { val participantDevices = participant.devices Log.i("[Conference] Participant found: ${participant.address.asStringUriOnly()} with ${participantDevices.size} device(s)") @@ -442,10 +447,16 @@ class ConferenceViewModel : ViewModel() { if (activelySpeakingParticipantDevice == device) { Log.i("[Conference] Actively speaking participant device found: ${device.name} (${device.address.asStringUriOnly()})") speakingParticipant.value = deviceData + foundActivelySpeakingParticipantDevice = true } } } + if (!foundActivelySpeakingParticipantDevice && devices.isNotEmpty()) { + Log.w("[Conference] Actively speaking participant device not found, using first participant device available") + speakingParticipant.value = devices.first() + } + for (device in conference.me.devices) { Log.i("[Conference] Participant device for myself found: ${device.name} (${device.address.asStringUriOnly()})") val deviceData = ConferenceParticipantDeviceData(device, true) @@ -485,22 +496,33 @@ class ConferenceViewModel : ViewModel() { private fun removeParticipantDevice(device: ParticipantDevice) { val devices = arrayListOf() + var removedDeviceWasActiveSpeaker = false for (participantDevice in conferenceParticipantDevices.value.orEmpty()) { if (participantDevice.participantDevice.address.asStringUriOnly() != device.address.asStringUriOnly()) { devices.add(participantDevice) } else { + if (speakingParticipant.value == participantDevice) { + Log.w("[Conference] Removed participant device was the actively speaking participant device") + removedDeviceWasActiveSpeaker = true + } participantDevice.destroy() } } - if (devices.size == conferenceParticipantDevices.value.orEmpty().size) { + + val devicesCount = devices.size + if (devicesCount == conferenceParticipantDevices.value.orEmpty().size) { Log.e("[Conference] Failed to remove participant device: ${device.name} (${device.address.asStringUriOnly()})") - } else { - Log.i("[Conference] Participant device removed: ${device.name} (${device.address.asStringUriOnly()})") + } + + if (removedDeviceWasActiveSpeaker && devicesCount > 1) { + Log.w("[Conference] Updating actively speaking participant device using first one available") + // Using second device as first is ourselves + speakingParticipant.value = devices[1] } conferenceParticipantDevices.value = devices - moreThanTwoParticipants.value = devices.size > 2 + moreThanTwoParticipants.value = devicesCount > 2 } private fun sortDevicesDataList(devices: List): ArrayList { diff --git a/app/src/main/res/layout-land/voip_conference_active_speaker.xml b/app/src/main/res/layout-land/voip_conference_active_speaker.xml index ea023c7f9..8c47312d6 100644 --- a/app/src/main/res/layout-land/voip_conference_active_speaker.xml +++ b/app/src/main/res/layout-land/voip_conference_active_speaker.xml @@ -179,7 +179,6 @@ android:layout_height="0dp" android:contentDescription="@null" coilVoipContact="@{conferenceViewModel.speakingParticipant}" - android:visibility="@{conferenceViewModel.speakingParticipant.isJoining ? View.GONE : View.VISIBLE}" android:background="@drawable/generated_avatar_bg" app:layout_constraintDimensionRatio="1:1" app:layout_constraintBottom_toBottomOf="@id/active_speaker_background" diff --git a/app/src/main/res/layout/voip_conference_active_speaker.xml b/app/src/main/res/layout/voip_conference_active_speaker.xml index 66eca4be2..584ec0697 100644 --- a/app/src/main/res/layout/voip_conference_active_speaker.xml +++ b/app/src/main/res/layout/voip_conference_active_speaker.xml @@ -139,7 +139,6 @@ android:layout_margin="10dp" android:contentDescription="@null" coilVoipContact="@{conferenceViewModel.speakingParticipant}" - android:visibility="@{conferenceViewModel.speakingParticipant.isJoining ? View.GONE : View.VISIBLE}" android:background="@drawable/generated_avatar_bg" app:layout_constraintDimensionRatio="1:1" app:layout_constraintBottom_toBottomOf="@id/active_speaker_background"