Conference: disable video when using audio only layout + sort participants device depending on layout
This commit is contained in:
parent
26f06436f4
commit
ab0cc34b24
4 changed files with 61 additions and 51 deletions
|
@ -106,7 +106,7 @@ class ConferenceWaitingRoomViewModel : ViewModel() {
|
|||
isAudioOnlyLayoutSelected.value = false
|
||||
updateLayout()
|
||||
|
||||
isVideoAvailable.value = core.isVideoCaptureEnabled || core.isVideoPreviewEnabled
|
||||
isVideoAvailable.value = isAudioOnlyLayoutSelected.value == false && (core.isVideoCaptureEnabled || core.isVideoPreviewEnabled)
|
||||
callParams.isVideoEnabled = isVideoAvailable.value == true
|
||||
callParams.videoDirection = if (core.videoActivationPolicy.automaticallyInitiate) MediaDirection.SendRecv else MediaDirection.RecvOnly
|
||||
Log.i("[Conference Waiting Room] Video will be ${if (callParams.isVideoEnabled) "enabled" else "disabled"}")
|
||||
|
@ -233,6 +233,7 @@ class ConferenceWaitingRoomViewModel : ViewModel() {
|
|||
askPermissionEvent.value = Event(Manifest.permission.CAMERA)
|
||||
return
|
||||
}
|
||||
callParams.isVideoEnabled = isVideoAvailable.value == true
|
||||
callParams.videoDirection = if (callParams.videoDirection == MediaDirection.SendRecv) MediaDirection.RecvOnly else MediaDirection.SendRecv
|
||||
Log.i("[Conference Waiting Room] Video will be ${if (callParams.isVideoEnabled) "enabled" else "disabled"}")
|
||||
updateVideoState()
|
||||
|
@ -240,6 +241,7 @@ class ConferenceWaitingRoomViewModel : ViewModel() {
|
|||
|
||||
fun enableVideo() {
|
||||
Log.i("[Conference Waiting Room] Video will be enabled")
|
||||
callParams.isVideoEnabled = isVideoAvailable.value == true
|
||||
callParams.videoDirection = MediaDirection.SendRecv
|
||||
updateVideoState()
|
||||
}
|
||||
|
@ -288,13 +290,19 @@ class ConferenceWaitingRoomViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
private fun updateLayout() {
|
||||
val layout = coreContext.core.defaultConferenceLayout
|
||||
val core = coreContext.core
|
||||
val layout = core.defaultConferenceLayout
|
||||
isActiveSpeakerLayoutSelected.value = layout == ConferenceLayout.ActiveSpeaker
|
||||
isAudioOnlyLayoutSelected.value = layout == ConferenceLayout.Legacy // TODO: FIXME: Replace Legacy by AudioOnly
|
||||
|
||||
isVideoAvailable.value = isAudioOnlyLayoutSelected.value == false && (core.isVideoCaptureEnabled || core.isVideoPreviewEnabled)
|
||||
callParams.isVideoEnabled = isVideoAvailable.value == true && isAudioOnlyLayoutSelected.value == false
|
||||
if (isAudioOnlyLayoutSelected.value == true) callParams.videoDirection = MediaDirection.RecvOnly
|
||||
updateVideoState()
|
||||
}
|
||||
|
||||
private fun updateVideoState() {
|
||||
isVideoEnabled.value = callParams.videoDirection == MediaDirection.SendRecv
|
||||
isVideoEnabled.value = callParams.isVideoEnabled && callParams.videoDirection == MediaDirection.SendRecv
|
||||
isSwitchCameraAvailable.value = callParams.isVideoEnabled && coreContext.showSwitchCameraButton()
|
||||
coreContext.core.isVideoPreviewEnabled = callParams.isVideoEnabled
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@ import androidx.navigation.navGraphViewModels
|
|||
import org.linphone.R
|
||||
import org.linphone.activities.GenericFragment
|
||||
import org.linphone.activities.voip.viewmodels.ConferenceViewModel
|
||||
import org.linphone.core.ConferenceLayout
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.VoipConferenceLayoutFragmentBinding
|
||||
|
||||
class ConferenceLayoutFragment : GenericFragment<VoipConferenceLayoutFragmentBinding>() {
|
||||
|
@ -46,48 +44,6 @@ class ConferenceLayoutFragment : GenericFragment<VoipConferenceLayoutFragmentBin
|
|||
goBack()
|
||||
}
|
||||
|
||||
conferenceViewModel.conferenceMosaicDisplayMode.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
if (it) {
|
||||
Log.i("[Conference] Trying to change conference layout to Grid")
|
||||
val conference = conferenceViewModel.conference.value
|
||||
if (conference != null) {
|
||||
conference.layout = ConferenceLayout.Grid
|
||||
} else {
|
||||
Log.e("[Conference] Conference is null in ConferenceViewModel")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conferenceViewModel.conferenceActiveSpeakerDisplayMode.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
if (it) {
|
||||
Log.i("[Conference] Trying to change conference layout to ActiveSpeaker")
|
||||
val conference = conferenceViewModel.conference.value
|
||||
if (conference != null) {
|
||||
conference.layout = ConferenceLayout.ActiveSpeaker
|
||||
} else {
|
||||
Log.e("[Conference] Conference is null in ConferenceViewModel")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conferenceViewModel.conferenceAudioOnlyDisplayMode.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
if (it) {
|
||||
Log.i("[Conference] Trying to change conference layout to AudioOnly")
|
||||
val conference = conferenceViewModel.conference.value
|
||||
if (conference != null) {
|
||||
conference.layout = ConferenceLayout.Legacy // TODO: FIXME: Use AudioOnly
|
||||
} else {
|
||||
Log.e("[Conference] Conference is null in ConferenceViewModel")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
conferenceViewModel.conferenceParticipantDevices.observe(
|
||||
viewLifecycleOwner
|
||||
) {
|
||||
|
|
|
@ -290,11 +290,26 @@ class ConferenceViewModel : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
fun changeLayout(layout: ConferenceLayout) {
|
||||
Log.i("[Conference] Trying to change conference layout to $layout")
|
||||
val conference = conference.value
|
||||
if (conference != null) {
|
||||
conference.layout = layout
|
||||
updateConferenceLayout(conference)
|
||||
} else {
|
||||
Log.e("[Conference] Conference is null in ConferenceViewModel")
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateConferenceLayout(conference: Conference) {
|
||||
val layout = conference.layout
|
||||
conferenceMosaicDisplayMode.value = layout == ConferenceLayout.Grid
|
||||
conferenceActiveSpeakerDisplayMode.value = layout == ConferenceLayout.ActiveSpeaker
|
||||
conferenceAudioOnlyDisplayMode.value = layout == ConferenceLayout.Legacy // TODO: FIXME: Use AudioOnly layout
|
||||
|
||||
val list = sortDevicesDataList(conferenceParticipantDevices.value.orEmpty())
|
||||
conferenceParticipantDevices.value = list
|
||||
|
||||
Log.i("[Conference] Conference current layout is: $layout")
|
||||
}
|
||||
|
||||
|
@ -372,11 +387,13 @@ class ConferenceViewModel : ViewModel() {
|
|||
val deviceData = ConferenceParticipantDeviceData(device, false)
|
||||
devices.add(deviceData)
|
||||
|
||||
val sortedDevices = sortDevicesDataList(devices)
|
||||
|
||||
if (speakingParticipant.value == null) {
|
||||
speakingParticipant.value = deviceData
|
||||
}
|
||||
|
||||
conferenceParticipantDevices.value = devices
|
||||
conferenceParticipantDevices.value = sortedDevices
|
||||
}
|
||||
|
||||
private fun removeParticipantDevice(device: ParticipantDevice) {
|
||||
|
@ -395,4 +412,28 @@ class ConferenceViewModel : ViewModel() {
|
|||
|
||||
conferenceParticipantDevices.value = devices
|
||||
}
|
||||
|
||||
private fun sortDevicesDataList(devices: List<ConferenceParticipantDeviceData>): ArrayList<ConferenceParticipantDeviceData> {
|
||||
val sortedList = arrayListOf<ConferenceParticipantDeviceData>()
|
||||
sortedList.addAll(devices)
|
||||
|
||||
val meDeviceData = sortedList.find {
|
||||
it.isMe
|
||||
}
|
||||
if (meDeviceData != null) {
|
||||
val index = sortedList.indexOf(meDeviceData)
|
||||
val expectedIndex = if (conferenceActiveSpeakerDisplayMode.value == true) {
|
||||
0
|
||||
} else {
|
||||
sortedList.size - 1
|
||||
}
|
||||
if (index != expectedIndex) {
|
||||
Log.i("[Conference] Me device data is at index $index, moving it to index $expectedIndex")
|
||||
sortedList.removeAt(index)
|
||||
sortedList.add(expectedIndex, meDeviceData)
|
||||
}
|
||||
}
|
||||
|
||||
return sortedList
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="org.linphone.core.ConferenceLayout" />
|
||||
<variable
|
||||
name="cancelClickListener"
|
||||
type="android.view.View.OnClickListener"/>
|
||||
|
@ -59,6 +60,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<RadioButton
|
||||
android:onClickListener="@{() -> conferenceViewModel.changeLayout(ConferenceLayout.Grid)}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
|
@ -67,7 +69,7 @@
|
|||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/conference_display_mode_mosaic"
|
||||
android:enabled="@{conferenceViewModel.conferenceParticipantDevices.size() > conferenceViewModel.maxParticipantsForMosaicLayout ? false : true}"
|
||||
android:checked="@={conferenceViewModel.conferenceMosaicDisplayMode}"
|
||||
android:checked="@{conferenceViewModel.conferenceMosaicDisplayMode}"
|
||||
android:drawableEnd="@drawable/icon_conference_layout_grid"
|
||||
android:drawableTint="?attr/voipDrawableColor"/>
|
||||
|
||||
|
@ -77,6 +79,7 @@
|
|||
android:background="?attr/dividerColor" />
|
||||
|
||||
<RadioButton
|
||||
android:onClickListener="@{() -> conferenceViewModel.changeLayout(ConferenceLayout.ActiveSpeaker)}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
|
@ -85,7 +88,7 @@
|
|||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/conference_display_mode_active_speaker"
|
||||
android:enabled="@{conferenceViewModel.conferenceParticipantDevices.size() > conferenceViewModel.maxParticipantsForMosaicLayout ? false : true}"
|
||||
android:checked="@={conferenceViewModel.conferenceActiveSpeakerDisplayMode}"
|
||||
android:checked="@{conferenceViewModel.conferenceActiveSpeakerDisplayMode}"
|
||||
android:drawableEnd="@drawable/icon_conference_layout_active_speaker"
|
||||
android:drawableTint="?attr/voipDrawableColor"/>
|
||||
|
||||
|
@ -94,7 +97,9 @@
|
|||
android:layout_height="1dp"
|
||||
android:background="?attr/dividerColor" />
|
||||
|
||||
<!-- TODO: FIXME: Use AudioOnly layout -->
|
||||
<RadioButton
|
||||
android:onClickListener="@{() -> conferenceViewModel.changeLayout(ConferenceLayout.Legacy)}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
|
@ -102,7 +107,7 @@
|
|||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/conference_display_mode_audio_only"
|
||||
android:checked="@={conferenceViewModel.conferenceAudioOnlyDisplayMode}"
|
||||
android:checked="@{conferenceViewModel.conferenceAudioOnlyDisplayMode}"
|
||||
android:drawableEnd="@drawable/icon_conference_layout_audio_only"
|
||||
android:drawableTint="?attr/voipDrawableColor"/>
|
||||
|
||||
|
|
Loading…
Reference in a new issue