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 b9a7f5143..b15c782d9 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 @@ -25,10 +25,7 @@ import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.contact.GenericContactData -import org.linphone.core.MediaDirection -import org.linphone.core.ParticipantDevice -import org.linphone.core.ParticipantDeviceListenerStub -import org.linphone.core.StreamType +import org.linphone.core.* import org.linphone.core.tools.Log class ConferenceParticipantDeviceData( @@ -42,12 +39,14 @@ class ConferenceParticipantDeviceData( val isSendingVideo = MutableLiveData() - val activeSpeaker = MutableLiveData() + val isSpeaking = MutableLiveData() - val micMuted = MutableLiveData() + val isMuted = MutableLiveData() val isInConference = MutableLiveData() + val isJoining = MutableLiveData() + private var textureView: TextureView? = null private val listener = object : ParticipantDeviceListenerStub() { @@ -56,23 +55,31 @@ class ConferenceParticipantDeviceData( isSpeaking: Boolean ) { Log.i("[Conference Participant Device] Participant [${participantDevice.address.asStringUriOnly()}] is ${if (isSpeaking) "speaking" else "not speaking"}") - activeSpeaker.value = isSpeaking + this@ConferenceParticipantDeviceData.isSpeaking.value = isSpeaking } override fun onIsMuted(participantDevice: ParticipantDevice, isMuted: Boolean) { Log.i("[Conference Participant Device] Participant [${participantDevice.address.asStringUriOnly()}] is ${if (isMuted) "muted" else "not muted"}") - micMuted.value = isMuted + this@ConferenceParticipantDeviceData.isMuted.value = isMuted } - override fun onConferenceJoined(participantDevice: ParticipantDevice) { - Log.i("[Conference Participant Device] Participant [${participantDevice.address.asStringUriOnly()}] has joined the conference") - isInConference.value = true - updateWindowId(textureView) - } - - override fun onConferenceLeft(participantDevice: ParticipantDevice) { - Log.i("[Conference Participant Device] Participant [${participantDevice.address.asStringUriOnly()}] has left the conference") - isInConference.value = false + override fun onStateChanged( + participantDevice: ParticipantDevice, + state: ParticipantDeviceState + ) { + Log.i("[Conference Participant Device] Participant [${participantDevice.address.asStringUriOnly()}] state has changed: $state") + when (state) { + ParticipantDeviceState.Joining, ParticipantDeviceState.Alerting -> isJoining.value = true + ParticipantDeviceState.OnHold -> { + isInConference.value = false + } + ParticipantDeviceState.Present -> { + isJoining.value = false + isInConference.value = true + updateWindowId(textureView) + } + else -> {} + } } override fun onStreamCapabilityChanged( @@ -105,14 +112,17 @@ class ConferenceParticipantDeviceData( Log.i("[Conference Participant Device] Created device width Address [${participantDevice.address.asStringUriOnly()}], is it myself? $isMe") participantDevice.addListener(listener) - activeSpeaker.value = false - micMuted.value = participantDevice.isMuted + isSpeaking.value = false + isMuted.value = participantDevice.isMuted videoAvailable.value = participantDevice.getStreamAvailability(StreamType.Video) val videoCapability = participantDevice.getStreamCapability(StreamType.Video) isSendingVideo.value = videoCapability == MediaDirection.SendRecv || videoCapability == MediaDirection.SendOnly isInConference.value = participantDevice.isInConference + val state = participantDevice.state + isJoining.value = state == ParticipantDeviceState.Joining || state == ParticipantDeviceState.Alerting + videoEnabled.value = isVideoAvailableAndSendReceive() videoEnabled.addSource(videoAvailable) { videoEnabled.value = isVideoAvailableAndSendReceive() @@ -121,7 +131,7 @@ class ConferenceParticipantDeviceData( videoEnabled.value = isVideoAvailableAndSendReceive() } - Log.i("[Conference Participant Device] Participant [${participantDevice.address.asStringUriOnly()}], is in conf? ${isInConference.value}, is video available? ${videoAvailable.value} ($videoCapability), is mic muted? ${micMuted.value}") + Log.i("[Conference Participant Device] Participant [${participantDevice.address.asStringUriOnly()}], is in conf? ${isInConference.value}, is video available? ${videoAvailable.value} ($videoCapability), is mic muted? ${isMuted.value}") } override fun destroy() { 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 55ff3b8bf..d03a497af 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 @@ -124,17 +124,23 @@ class ConferenceViewModel : ViewModel() { this@ConferenceViewModel.subject.value = subject } - override fun onParticipantDeviceJoined(conference: Conference, device: ParticipantDevice) { + override fun onParticipantDeviceStateChanged( + conference: Conference, + device: ParticipantDevice, + state: ParticipantDeviceState + ) { if (conference.isMe(device.address)) { - Log.i("[Conference] Entered conference") - isConferenceLocallyPaused.value = false - } - } - - override fun onParticipantDeviceLeft(conference: Conference, device: ParticipantDevice) { - if (conference.isMe(device.address)) { - Log.i("[Conference] Left conference") - isConferenceLocallyPaused.value = true + when (state) { + ParticipantDeviceState.Present -> { + Log.i("[Conference] Entered conference") + isConferenceLocallyPaused.value = false + } + ParticipantDeviceState.OnHold -> { + Log.i("[Conference] Left conference") + isConferenceLocallyPaused.value = true + } + else -> {} + } } } 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 17a59b45d..5040095d7 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 @@ -34,7 +34,7 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - android:layout_marginTop="@{controlsViewModel.folded || controlsViewModel.fullScreenMode ? @dimen/margin_0dp : conferenceViewModel.isRemotelyRecorded ? @dimen/voip_single_call_header_size_with_record_info : @dimen/voip_single_call_header_size, default=@dimen/voip_single_call_header_size}"/> + android:layout_marginTop="@{controlsViewModel.folded || controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? @dimen/margin_0dp : conferenceViewModel.isRemotelyRecorded ? @dimen/voip_single_call_header_size_with_record_info : @dimen/voip_single_call_header_size, default=@dimen/voip_single_call_header_size}"/> + android:layout_marginTop="@{controlsViewModel.fullScreenMode || controlsViewModel.pipMode || controlsViewModel.folded ? @dimen/margin_0dp : conferenceViewModel.isRemotelyRecorded ? @dimen/voip_single_call_header_size_with_record_info : @dimen/voip_single_call_header_size, default=@dimen/voip_single_call_header_size}"/> 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 a63ca08d6..7e644a6e1 100644 --- a/app/src/main/res/layout/voip_conference_active_speaker.xml +++ b/app/src/main/res/layout/voip_conference_active_speaker.xml @@ -34,7 +34,7 @@ app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - android:layout_marginTop="@{controlsViewModel.folded || controlsViewModel.fullScreenMode ? @dimen/margin_0dp : conferenceViewModel.isRemotelyRecorded ? @dimen/voip_single_call_header_size_with_record_info : @dimen/voip_single_call_header_size, default=@dimen/voip_single_call_header_size}"/> + android:layout_marginTop="@{controlsViewModel.folded || controlsViewModel.fullScreenMode || controlsViewModel.pipMode ? @dimen/margin_0dp : conferenceViewModel.isRemotelyRecorded ? @dimen/voip_single_call_header_size_with_record_info : @dimen/voip_single_call_header_size, default=@dimen/voip_single_call_header_size}"/> + android:layout_marginTop="@{controlsViewModel.fullScreenMode || controlsViewModel.pipMode || controlsViewModel.folded ? @dimen/margin_0dp : conferenceViewModel.isRemotelyRecorded ? @dimen/voip_single_call_header_size_with_record_info : @dimen/voip_single_call_header_size, default=@dimen/voip_single_call_header_size}"/> diff --git a/app/src/main/res/layout/voip_conference_participant_remote_active_speaker_miniature.xml b/app/src/main/res/layout/voip_conference_participant_remote_active_speaker_miniature.xml index a4d5921e9..c64221b77 100644 --- a/app/src/main/res/layout/voip_conference_participant_remote_active_speaker_miniature.xml +++ b/app/src/main/res/layout/voip_conference_participant_remote_active_speaker_miniature.xml @@ -15,14 +15,15 @@ android:layout_width="@dimen/voip_active_speaker_miniature_size" android:layout_height="@dimen/voip_active_speaker_miniature_size" android:layout_margin="5dp" - android:background="@{!data.isInConference ? @drawable/shape_remote_paused_background : data.videoEnabled ? @drawable/shape_remote_video_background : @drawable/shape_remote_background, default=@drawable/shape_remote_background}" + android:background="@{!data.isInConference && !data.isJoining ? @drawable/shape_remote_paused_background : data.videoEnabled ? @drawable/shape_remote_video_background : @drawable/shape_remote_background, default=@drawable/shape_remote_background}" app:layout_alignSelf="flex_end" app:layout_flexShrink="0"> - + diff --git a/app/src/main/res/layout/voip_conference_participant_remote_audio_only.xml b/app/src/main/res/layout/voip_conference_participant_remote_audio_only.xml index 8edab2113..25084ebe9 100644 --- a/app/src/main/res/layout/voip_conference_participant_remote_audio_only.xml +++ b/app/src/main/res/layout/voip_conference_participant_remote_audio_only.xml @@ -36,7 +36,7 @@ android:adjustViewBounds="true" android:contentDescription="@null" android:src="@drawable/shape_conference_audio_only_border" - android:visibility="@{data.activeSpeaker ? View.VISIBLE : View.GONE, default=gone}" + android:visibility="@{data.isSpeaking ? View.VISIBLE : View.GONE, default=gone}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -48,10 +48,10 @@ android:layout_height="@dimen/voip_conference_audio_only_participant_avatar_size" android:layout_marginStart="10dp" android:contentDescription="@null" - android:visibility="@{data.isInConference ? View.VISIBLE : View.GONE}" + android:visibility="@{data.isInConference || data.isJoining ? View.VISIBLE : View.GONE}" coilVoipContact="@{data}" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/paused_avatar" + app:layout_constraintEnd_toStartOf="@id/paused_avatar" app:layout_constraintHorizontal_chainStyle="spread_inside" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -64,10 +64,10 @@ android:background="@drawable/shape_button_background" android:contentDescription="@string/content_description_participant_is_paused" android:src="@drawable/icon_pause" - android:visibility="@{data.isInConference ? View.GONE : View.VISIBLE, default=gone}" + android:visibility="@{data.isInConference || data.isJoining ? View.GONE : View.VISIBLE, default=gone}" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/participant_name" - app:layout_constraintStart_toEndOf="@+id/participant_avatar" + app:layout_constraintEnd_toStartOf="@id/participant_name" + app:layout_constraintStart_toEndOf="@id/participant_avatar" app:layout_constraintTop_toTopOf="parent" /> + + + + diff --git a/app/src/main/res/layout/voip_conference_participant_remote_grid.xml b/app/src/main/res/layout/voip_conference_participant_remote_grid.xml index 1c7e24578..4df851b2d 100644 --- a/app/src/main/res/layout/voip_conference_participant_remote_grid.xml +++ b/app/src/main/res/layout/voip_conference_participant_remote_grid.xml @@ -20,18 +20,19 @@ android:layout_width="0dp" android:layout_height="0dp" android:layout_margin="5dp" - android:background="@{!data.isInConference ? @drawable/shape_remote_paused_background : data.videoEnabled ? @drawable/shape_remote_video_background : @drawable/shape_remote_background, default=@drawable/shape_remote_background}" + android:background="@{!data.isInConference && !data.isJoining ? @drawable/shape_remote_paused_background : data.videoEnabled ? @drawable/shape_remote_video_background : @drawable/shape_remote_background, default=@drawable/shape_remote_background}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - - + + diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index 240babe9a..b36fef9ab 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -59,7 +59,9 @@ 10dp 50dp 30dp + 30dp 25dp + 35dp 137dp 180dp 80sp