diff --git a/app/src/main/java/org/linphone/ui/call/viewmodel/CallsViewModel.kt b/app/src/main/java/org/linphone/ui/call/viewmodel/CallsViewModel.kt index d2dcdcaec..db2cd71d1 100644 --- a/app/src/main/java/org/linphone/ui/call/viewmodel/CallsViewModel.kt +++ b/app/src/main/java/org/linphone/ui/call/viewmodel/CallsViewModel.kt @@ -228,12 +228,20 @@ class CallsViewModel AppUtils.getString(R.string.conference_locally_hosted_title) } - val params = core.createConferenceParams(null) - params.subject = subject - // Prevent group call to start in audio only layout - params.isVideoEnabled = true - val conference = core.createConferenceWithParams(params) - conference?.addParticipants(core.calls) + val conference = LinphoneUtils.createGroupCall(defaultAccount, subject) + if (conference == null) { + Log.e("$TAG Failed to create conference!") + showRedToastEvent.postValue( + Event( + Pair( + R.string.conference_failed_to_merge_calls_into_conference_toast, + R.drawable.warning_circle + ) + ) + ) + } else { + conference.addParticipants(core.calls) + } } } diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/AbstractConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/AbstractConversationViewModel.kt index 5b8067d2f..ca647937a 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/AbstractConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/AbstractConversationViewModel.kt @@ -28,14 +28,9 @@ import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R import org.linphone.core.Address import org.linphone.core.ChatRoom -import org.linphone.core.Conference import org.linphone.core.ConferenceParams -import org.linphone.core.ConferenceScheduler -import org.linphone.core.ConferenceSchedulerListenerStub import org.linphone.core.Factory -import org.linphone.core.Participant -import org.linphone.core.ParticipantInfo -import org.linphone.core.StreamType +import org.linphone.core.MediaDirection import org.linphone.core.tools.Log import org.linphone.ui.GenericViewModel import org.linphone.utils.Event @@ -64,47 +59,6 @@ abstract class AbstractConversationViewModel : GenericViewModel() { return ::chatRoom.isInitialized } - private val conferenceSchedulerListener = object : ConferenceSchedulerListenerStub() { - override fun onStateChanged( - conferenceScheduler: ConferenceScheduler, - state: ConferenceScheduler.State - ) { - Log.i("$TAG Conference scheduler state is $state") - if (state == ConferenceScheduler.State.Ready) { - conferenceScheduler.removeListener(this) - - val conferenceAddress = conferenceScheduler.info?.uri - if (conferenceAddress != null) { - Log.i( - "$TAG Conference info created, address is ${conferenceAddress.asStringUriOnly()}" - ) - coreContext.startVideoCall(conferenceAddress) - } else { - Log.e("$TAG Conference info URI is null!") - showRedToastEvent.postValue( - Event( - Pair( - R.string.conference_failed_to_create_group_call_toast, - R.drawable.warning_circle - ) - ) - ) - } - } else if (state == ConferenceScheduler.State.Error) { - conferenceScheduler.removeListener(this) - Log.e("$TAG Failed to create group call!") - showRedToastEvent.postValue( - Event( - Pair( - R.string.conference_failed_to_create_group_call_toast, - R.drawable.warning_circle - ) - ) - ) - } - } - } - @WorkerThread open fun beforeNotifyingChatRoomFound(sameOne: Boolean) { } @@ -216,41 +170,44 @@ abstract class AbstractConversationViewModel : GenericViewModel() { return@postOnCoreThread } - val conferenceInfo = Factory.instance().createConferenceInfo() - conferenceInfo.organizer = account.params.identityAddress - conferenceInfo.subject = chatRoom.subject - - // Allows to have a chat room within the conference - conferenceInfo.setCapability(StreamType.Text, true) - - // Enable end-to-end encryption if client supports it - conferenceInfo.securityLevel = if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) { - Log.i("$TAG Requesting EndToEnd security level for conference") - Conference.SecurityLevel.EndToEnd - } else { - Log.i("$TAG Requesting PointToPoint security level for conference") - Conference.SecurityLevel.PointToPoint + val conference = LinphoneUtils.createGroupCall(account, chatRoom.subject.orEmpty()) + if (conference == null) { + Log.e("$TAG Failed to create group call!") + showRedToastEvent.postValue( + Event( + Pair( + R.string.conference_failed_to_create_group_call_toast, + R.drawable.warning_circle + ) + ) + ) + return@postOnCoreThread } - val participants = arrayOfNulls(chatRoom.participants.size) + val callParams = core.createCallParams(null) + callParams?.isVideoEnabled = true + callParams?.videoDirection = MediaDirection.RecvOnly + + val participants = arrayOfNulls
(chatRoom.participants.size) var index = 0 for (participant in chatRoom.participants) { - val info = Factory.instance().createParticipantInfo(participant.address) - // For meetings, all participants must have Speaker role - info?.role = Participant.Role.Speaker - participants[index] = info + participants[index] = participant.address index += 1 } - conferenceInfo.setParticipantInfos(participants) - Log.i( - "$TAG Creating group call with subject ${conferenceInfo.subject} and ${participants.size} participant(s)" + "$TAG Inviting ${participants.size} participant(s) into newly created conference" ) - val conferenceScheduler = LinphoneUtils.createConferenceScheduler(account) - conferenceScheduler.addListener(conferenceSchedulerListener) - conferenceScheduler.account = account - // Will trigger the conference creation/update automatically - conferenceScheduler.info = conferenceInfo + if (conference.inviteParticipants(participants, callParams) != 0) { + Log.e("$TAG Failed to invite participants into group call!") + showRedToastEvent.postValue( + Event( + Pair( + R.string.conference_failed_to_create_group_call_toast, + R.drawable.warning_circle + ) + ) + ) + } } } } diff --git a/app/src/main/java/org/linphone/ui/main/history/viewmodel/StartCallViewModel.kt b/app/src/main/java/org/linphone/ui/main/history/viewmodel/StartCallViewModel.kt index 23ba2bac0..144f5b2d1 100644 --- a/app/src/main/java/org/linphone/ui/main/history/viewmodel/StartCallViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/history/viewmodel/StartCallViewModel.kt @@ -28,13 +28,8 @@ import kotlinx.coroutines.launch import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences import org.linphone.R -import org.linphone.core.Conference -import org.linphone.core.ConferenceScheduler -import org.linphone.core.ConferenceSchedulerListenerStub -import org.linphone.core.Factory -import org.linphone.core.Participant -import org.linphone.core.ParticipantInfo -import org.linphone.core.StreamType +import org.linphone.core.Address +import org.linphone.core.MediaDirection import org.linphone.core.tools.Log import org.linphone.ui.main.history.model.NumpadModel import org.linphone.ui.main.viewmodel.AddressSelectionViewModel @@ -82,50 +77,6 @@ class StartCallViewModel MutableLiveData>() } - private val conferenceSchedulerListener = object : ConferenceSchedulerListenerStub() { - override fun onStateChanged( - conferenceScheduler: ConferenceScheduler, - state: ConferenceScheduler.State - ) { - Log.i("$TAG Conference scheduler state is $state") - if (state == ConferenceScheduler.State.Ready) { - conferenceScheduler.removeListener(this) - - val conferenceAddress = conferenceScheduler.info?.uri - if (conferenceAddress != null) { - Log.i( - "$TAG Conference info created, address is ${conferenceAddress.asStringUriOnly()}" - ) - coreContext.startVideoCall(conferenceAddress) - leaveFragmentEvent.postValue(Event(true)) - } else { - Log.e("$TAG Conference info URI is null!") - showRedToastEvent.postValue( - Event( - Pair( - R.string.conference_failed_to_create_group_call_toast, - R.drawable.warning_circle - ) - ) - ) - } - operationInProgress.postValue(false) - } else if (state == ConferenceScheduler.State.Error) { - conferenceScheduler.removeListener(this) - Log.e("$TAG Failed to create group call!") - showRedToastEvent.postValue( - Event( - Pair( - R.string.conference_failed_to_create_group_call_toast, - R.drawable.warning_circle - ) - ) - ) - operationInProgress.postValue(false) - } - } - } - init { isNumpadVisible.value = false numpadModel = NumpadModel( @@ -217,44 +168,48 @@ class StartCallViewModel ) return@postOnCoreThread } - operationInProgress.postValue(true) - val conferenceInfo = Factory.instance().createConferenceInfo() - conferenceInfo.organizer = account.params.identityAddress - conferenceInfo.subject = subject.value - - // Allows to have a chat room within the conference - conferenceInfo.setCapability(StreamType.Text, true) - - // Enable end-to-end encryption if client supports it - conferenceInfo.securityLevel = if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) { - Log.i("$TAG Requesting EndToEnd security level for conference") - Conference.SecurityLevel.EndToEnd - } else { - Log.i("$TAG Requesting PointToPoint security level for conference") - Conference.SecurityLevel.PointToPoint + Log.i("$TAG Creating group call with subject ${subject.value}") + val conference = LinphoneUtils.createGroupCall(account, subject.value.orEmpty()) + if (conference == null) { + Log.e("$TAG Failed to create group call!") + showRedToastEvent.postValue( + Event( + Pair( + R.string.conference_failed_to_create_group_call_toast, + R.drawable.warning_circle + ) + ) + ) + return@postOnCoreThread } - val participants = arrayOfNulls(selection.value.orEmpty().size) + val callParams = core.createCallParams(null) + callParams?.isVideoEnabled = true + callParams?.videoDirection = MediaDirection.RecvOnly + + val participants = arrayOfNulls
(selection.value.orEmpty().size) var index = 0 for (participant in selection.value.orEmpty()) { - val info = Factory.instance().createParticipantInfo(participant.address) - // For meetings, all participants must have Speaker role - info?.role = Participant.Role.Speaker - participants[index] = info + participants[index] = participant.address index += 1 } - conferenceInfo.setParticipantInfos(participants) - Log.i( - "$TAG Creating group call with subject ${subject.value} and ${participants.size} participant(s)" + "$TAG Inviting ${participants.size} participant(s) into newly created conference" ) - val conferenceScheduler = LinphoneUtils.createConferenceScheduler(account) - conferenceScheduler.addListener(conferenceSchedulerListener) - conferenceScheduler.account = account - // Will trigger the conference creation/update automatically - conferenceScheduler.info = conferenceInfo + if (conference.inviteParticipants(participants, callParams) != 0) { + Log.e("$TAG Failed to invite participants into group call!") + showRedToastEvent.postValue( + Event( + Pair( + R.string.conference_failed_to_create_group_call_toast, + R.drawable.warning_circle + ) + ) + ) + } + operationInProgress.postValue(false) } } } diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt index e5440606c..7e77a3d4d 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt @@ -263,6 +263,30 @@ class LinphoneUtils { ) } + @WorkerThread + fun createGroupCall(account: Account?, subject: String): Conference? { + val core = coreContext.core + val conferenceParams = core.createConferenceParams(null) + conferenceParams.isVideoEnabled = true + conferenceParams.account = account + conferenceParams.subject = subject + + // Enable end-to-end encryption if client supports it + conferenceParams.securityLevel = if (isEndToEndEncryptedChatAvailable(core)) { + Log.i("$TAG Requesting EndToEnd security level for conference") + Conference.SecurityLevel.EndToEnd + } else { + Log.i("$TAG Requesting PointToPoint security level for conference") + Conference.SecurityLevel.PointToPoint + } + + // Allows to have a chat room within the conference + conferenceParams.isChatEnabled = true + + Log.i("$TAG Creating group call with subject ${conferenceParams.subject}") + return core.createConferenceWithParams(conferenceParams) + } + @WorkerThread fun getChatRoomParamsToCancelMeeting(): ConferenceParams? { val chatRoomParams = coreContext.core.createConferenceParams(null) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 7e78cacaf..c1935a704 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -697,6 +697,7 @@ Partage d\'écran Participants Echec de l\'appel de groupe + Echec de la fusion des appels %s participant %s participants diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index da5720aaa..74817aa90 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -737,6 +737,7 @@ Screen share Participants Failed to create a group call! + Failed to merge call! %s participant %s participants