diff --git a/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt b/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt index 226e5f4f1..26d35549c 100644 --- a/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt +++ b/app/src/main/java/org/linphone/activities/voip/fragments/ConferenceCallFragment.kt @@ -81,6 +81,15 @@ class ConferenceCallFragment : GenericFragment @@ -101,6 +110,16 @@ class ConferenceCallFragment : GenericFragment { + controlsViewModel.fullScreenMode.value = false + } + else -> { + val conference = conferenceViewModel.conference.value + if (conference != null) switchToFullScreenIfPossible(conference) + } + } } conferenceViewModel.conferenceParticipantDevices.observe( @@ -111,7 +130,7 @@ class ConferenceCallFragment : GenericFragment conferenceViewModel.maxParticipantsForMosaicLayout ) { Log.w("[Conference Call] More than ${conferenceViewModel.maxParticipantsForMosaicLayout} participants (${it.size}), forcing active speaker layout") - conferenceViewModel.changeLayout(ConferenceDisplayMode.ACTIVE_SPEAKER) + conferenceViewModel.changeLayout(ConferenceDisplayMode.ACTIVE_SPEAKER, false) refreshConferenceFragment() // Can't use SnackBar whilst changing fragment Toast.makeText(requireContext(), R.string.conference_too_many_participants_for_mosaic_layout, Toast.LENGTH_LONG).show() @@ -149,20 +168,6 @@ class ConferenceCallFragment : GenericFragment - when (layout) { - ConferenceDisplayMode.AUDIO_ONLY -> { - controlsViewModel.fullScreenMode.value = false - } - else -> { - val conference = conferenceViewModel.conference.value - if (conference != null) switchToFullScreenIfPossible(conference) - } - } - } - conferenceViewModel.firstToJoinEvent.observe( viewLifecycleOwner ) { @@ -272,14 +277,14 @@ class ConferenceCallFragment : GenericFragment { - Log.w("[Conference Call] Conference has video enabled but either our device hasn't joined yet") + Log.i("[Conference Call] Conference has video enabled but our device hasn't joined yet") } conference.me.devices.find { it.isInConference && it.getStreamAvailability(StreamType.Video) } != null -> { Log.i("[Conference Call] Conference has video enabled & our device has video enabled, enabling full screen mode") controlsViewModel.fullScreenMode.value = true } else -> { - Log.w("[Conference Call] Conference has video enabled but our device video is disabled") + Log.i("[Conference Call] Conference has video enabled but our device video is disabled") } } } 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 d8b21bc3a..2573e38df 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 @@ -78,6 +78,12 @@ class ConferenceViewModel : ViewModel() { MutableLiveData>() } + private var waitForNextStreamsRunningToUpdateLayout = false + + val reloadConferenceFragmentEvent: MutableLiveData> by lazy { + MutableLiveData>() + } + private val conferenceListener = object : ConferenceListenerStub() { override fun onParticipantAdded(conference: Conference, participant: Participant) { Log.i("[Conference] Participant added: ${participant.address.asStringUriOnly()}") @@ -218,6 +224,18 @@ class ConferenceViewModel : ViewModel() { } } } + + override fun onCallStateChanged( + core: Core, + call: Call, + state: Call.State?, + message: String + ) { + if (state == Call.State.StreamsRunning && waitForNextStreamsRunningToUpdateLayout) { + waitForNextStreamsRunningToUpdateLayout = false + reloadConferenceFragmentEvent.value = Event(true) + } + } } init { @@ -340,7 +358,14 @@ class ConferenceViewModel : ViewModel() { } } - fun changeLayout(layout: ConferenceDisplayMode) { + fun switchLayoutFromAudioOnlyToActiveSpeaker() { + if (conferenceDisplayMode.value == ConferenceDisplayMode.AUDIO_ONLY) { + changeLayout(ConferenceDisplayMode.ACTIVE_SPEAKER, true) + waitForNextStreamsRunningToUpdateLayout = true + } + } + + fun changeLayout(layout: ConferenceDisplayMode, forceSendingVideo: Boolean) { Log.i("[Conference] Trying to change conference layout to $layout") val conference = conference.value if (conference != null) { @@ -353,6 +378,7 @@ class ConferenceViewModel : ViewModel() { } params.isVideoEnabled = layout != ConferenceDisplayMode.AUDIO_ONLY + if (forceSendingVideo) params.videoDirection = MediaDirection.SendRecv params.conferenceVideoLayout = when (layout) { ConferenceDisplayMode.GRID -> ConferenceLayout.Grid else -> ConferenceLayout.ActiveSpeaker diff --git a/app/src/main/res/layout/voip_buttons.xml b/app/src/main/res/layout/voip_buttons.xml index 6b0c6fcb8..3c2047e5e 100644 --- a/app/src/main/res/layout/voip_buttons.xml +++ b/app/src/main/res/layout/voip_buttons.xml @@ -96,8 +96,8 @@ android:layout_marginStart="5dp" android:background="@drawable/button_background_reverse" android:contentDescription="@{controlsViewModel.isVideoEnabled && controlsViewModel.isSendingVideo ? @string/content_description_disable_video : @string/content_description_enable_video}" - android:enabled="@{controlsViewModel.isVideoAvailable && !controlsViewModel.isVideoUpdateInProgress && conferenceViewModel.conferenceDisplayMode != ConferenceDisplayMode.AUDIO_ONLY}" - android:onClick="@{() -> controlsViewModel.toggleVideo()}" + android:enabled="@{controlsViewModel.isVideoAvailable && !controlsViewModel.isVideoUpdateInProgress}" + android:onClick="@{() -> conferenceViewModel.conferenceDisplayMode != ConferenceDisplayMode.AUDIO_ONLY ? controlsViewModel.toggleVideo() : conferenceViewModel.switchLayoutFromAudioOnlyToActiveSpeaker()}" android:padding="5dp" android:selected="@{controlsViewModel.isVideoEnabled && controlsViewModel.isSendingVideo}" android:src="@drawable/icon_toggle_camera" diff --git a/app/src/main/res/layout/voip_conference_layout_fragment.xml b/app/src/main/res/layout/voip_conference_layout_fragment.xml index cf52c8b89..1e25ab088 100644 --- a/app/src/main/res/layout/voip_conference_layout_fragment.xml +++ b/app/src/main/res/layout/voip_conference_layout_fragment.xml @@ -79,7 +79,7 @@ android:drawableEnd="@drawable/icon_conference_layout_grid" android:drawableTint="?attr/voipDrawableColor" android:enabled="@{conferenceViewModel.conferenceParticipantDevices.size() > conferenceViewModel.maxParticipantsForMosaicLayout ? false : true}" - android:onClickListener="@{() -> conferenceViewModel.changeLayout(ConferenceDisplayMode.GRID)}" + android:onClickListener="@{() -> conferenceViewModel.changeLayout(ConferenceDisplayMode.GRID, false)}" android:text="@string/conference_display_mode_mosaic" />