From b10b51f839faa99c979c59ac86d83ef9360f72e2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 27 Nov 2023 16:39:04 +0100 Subject: [PATCH] Do update conference layout in dialog --- .../ConferenceLayoutMenuDialogFragment.kt | 3 + .../linphone/ui/call/model/ConferenceModel.kt | 85 +++++++++++++++++++ .../layout/call_conference_layout_menu.xml | 6 +- 3 files changed, 91 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/linphone/ui/call/fragment/ConferenceLayoutMenuDialogFragment.kt b/app/src/main/java/org/linphone/ui/call/fragment/ConferenceLayoutMenuDialogFragment.kt index 06bcfb8ff..427340b83 100644 --- a/app/src/main/java/org/linphone/ui/call/fragment/ConferenceLayoutMenuDialogFragment.kt +++ b/app/src/main/java/org/linphone/ui/call/fragment/ConferenceLayoutMenuDialogFragment.kt @@ -58,12 +58,15 @@ class ConferenceLayoutMenuDialogFragment( view.viewModel = conferenceModel view.setGridClickListener { + conferenceModel.changeLayout(ConferenceModel.GRID_LAYOUT) dismiss() } view.setActiveSpeakerClickListener { + conferenceModel.changeLayout(ConferenceModel.ACTIVE_SPEAKER_LAYOUT) dismiss() } view.setAudioOnlyClickListener { + conferenceModel.changeLayout(ConferenceModel.AUDIO_ONLY_LAYOUT) dismiss() } diff --git a/app/src/main/java/org/linphone/ui/call/model/ConferenceModel.kt b/app/src/main/java/org/linphone/ui/call/model/ConferenceModel.kt index 02fc5c423..d38fe5df1 100644 --- a/app/src/main/java/org/linphone/ui/call/model/ConferenceModel.kt +++ b/app/src/main/java/org/linphone/ui/call/model/ConferenceModel.kt @@ -22,10 +22,12 @@ package org.linphone.ui.call.model import androidx.annotation.UiThread import androidx.annotation.WorkerThread import androidx.lifecycle.MutableLiveData +import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.core.Call import org.linphone.core.Conference import org.linphone.core.ConferenceListenerStub +import org.linphone.core.MediaDirection import org.linphone.core.Participant import org.linphone.core.ParticipantDevice import org.linphone.core.tools.Log @@ -35,6 +37,10 @@ import org.linphone.utils.Event class ConferenceModel { companion object { private const val TAG = "[Conference ViewModel]" + + const val AUDIO_ONLY_LAYOUT = -1 + const val GRID_LAYOUT = 0 // Conference.Layout.Grid + const val ACTIVE_SPEAKER_LAYOUT = 1 // Conference.Layout.ActiveSpeaker } val subject = MutableLiveData() @@ -49,6 +55,8 @@ class ConferenceModel { val isCurrentCallInConference = MutableLiveData() + val conferenceLayout = MutableLiveData() + val showLayoutMenuEvent: MutableLiveData> by lazy { MutableLiveData>() } @@ -158,6 +166,9 @@ class ConferenceModel { if (conference.state == Conference.State.Created) { computeParticipants() } + + val currentLayout = getCurrentLayout(call) + conferenceLayout.postValue(currentLayout) } @UiThread @@ -165,6 +176,80 @@ class ConferenceModel { showLayoutMenuEvent.value = Event(true) } + @UiThread + fun changeLayout(newLayout: Int) { + coreContext.postOnCoreThread { + val call = conference.call + if (call != null) { + val params = call.core.createCallParams(call) + if (params != null) { + val currentLayout = getCurrentLayout(call) + if (currentLayout != newLayout) { + when (newLayout) { + AUDIO_ONLY_LAYOUT -> { + Log.i("$TAG Changing conference layout to [Audio Only]") + params.isVideoEnabled = false + } + ACTIVE_SPEAKER_LAYOUT -> { + Log.i("$TAG Changing conference layout to [Active Speaker]") + params.conferenceVideoLayout = Conference.Layout.ActiveSpeaker + } + GRID_LAYOUT -> { + Log.i("$TAG Changing conference layout to [Grid]") + params.conferenceVideoLayout = Conference.Layout.Grid + } + } + + if (currentLayout == AUDIO_ONLY_LAYOUT) { + // Previous layout was audio only, make sure video isn't sent without user consent when switching layout + Log.i( + "$TAG Previous layout was [Audio Only], enabling video but in receive only direction" + ) + params.isVideoEnabled = true + params.videoDirection = MediaDirection.RecvOnly + } + + Log.i("$TAG Updating conference's call params") + call.update(params) + conferenceLayout.postValue(newLayout) + } else { + Log.w( + "$TAG The conference is already using selected layout, aborting layout change" + ) + } + } else { + Log.e("$TAG Failed to create call params, aborting layout change") + } + } else { + Log.e("$TAG Failed to get call from conference, aborting layout change") + } + } + } + + @WorkerThread + private fun getCurrentLayout(call: Call): Int { + // DO NOT USE call.currentParams, information won't be reliable ! + return if (!call.params.isVideoEnabled) { + Log.i("$TAG Current conference layout is [Audio Only]") + AUDIO_ONLY_LAYOUT + } else { + when (val layout = call.params.conferenceVideoLayout) { + Conference.Layout.Grid -> { + Log.i("$TAG Current conference layout is [Grid]") + GRID_LAYOUT + } + Conference.Layout.ActiveSpeaker -> { + Log.i("$TAG Current conference layout is [Active Speaker]") + ACTIVE_SPEAKER_LAYOUT + } + else -> { + Log.e("$TAG Unexpected conference layout value [$layout]") + -2 + } + } + } + } + @WorkerThread private fun computeParticipants() { participants.value.orEmpty().forEach(ConferenceParticipantModel::destroy) diff --git a/app/src/main/res/layout/call_conference_layout_menu.xml b/app/src/main/res/layout/call_conference_layout_menu.xml index b917ca78b..46d9d6dc2 100644 --- a/app/src/main/res/layout/call_conference_layout_menu.xml +++ b/app/src/main/res/layout/call_conference_layout_menu.xml @@ -37,7 +37,7 @@ android:layout_marginBottom="1dp" android:drawableEnd="@drawable/squares_four" android:drawableTint="@color/white" - android:checked="true" + android:checked="@{viewModel.conferenceLayout == 0}" app:useMaterialThemeColors="false" app:buttonTint="@color/white"/> @@ -54,7 +54,7 @@ android:layout_marginBottom="1dp" android:drawableEnd="@drawable/picture_in_picture" android:drawableTint="@color/white" - android:checked="false" + android:checked="@{viewModel.conferenceLayout == 1}" app:useMaterialThemeColors="false" app:buttonTint="@color/white"/> @@ -71,7 +71,7 @@ android:layout_marginBottom="1dp" android:drawableEnd="@drawable/waveform" android:drawableTint="@color/white" - android:checked="false" + android:checked="@{viewModel.conferenceLayout == -1}" app:useMaterialThemeColors="false" app:buttonTint="@color/white"/>