mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 03:18:06 +00:00
Migrated deprecated chat room & conference scheduler APIs
This commit is contained in:
parent
50cb162bd3
commit
257352927d
15 changed files with 248 additions and 78 deletions
|
|
@ -25,6 +25,8 @@ import android.content.BroadcastReceiver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.ConferenceParams
|
||||
import org.linphone.core.tools.Log
|
||||
|
||||
class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||
|
|
@ -110,7 +112,15 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
return@postOnCoreThread
|
||||
}
|
||||
|
||||
val room = core.searchChatRoom(null, localAddress, remoteAddress, arrayOfNulls(0))
|
||||
val params: ConferenceParams? = null
|
||||
val room = core.searchChatRoom(
|
||||
params,
|
||||
localAddress,
|
||||
remoteAddress,
|
||||
arrayOfNulls<Address>(
|
||||
0
|
||||
)
|
||||
)
|
||||
if (room == null) {
|
||||
Log.e(
|
||||
"$TAG Couldn't find conversation for remote address [$remoteSipAddress] and local address [$localIdentity]"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ import org.linphone.core.CallStats
|
|||
import org.linphone.core.ChatMessage
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.ChatRoomListenerStub
|
||||
import org.linphone.core.ChatRoomParams
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.ConferenceParams
|
||||
import org.linphone.core.Core
|
||||
import org.linphone.core.CoreListenerStub
|
||||
import org.linphone.core.MediaDirection
|
||||
|
|
@ -711,7 +712,7 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
else -> device.deviceName
|
||||
}
|
||||
val currentDevice = currentCall.outputAudioDevice
|
||||
val isCurrentlyInUse = device.type == currentDevice?.type && device.deviceName == currentDevice?.deviceName
|
||||
val isCurrentlyInUse = device.type == currentDevice?.type && device.deviceName == currentDevice.deviceName
|
||||
val model = AudioDeviceModel(device, name, device.type, isCurrentlyInUse, true) {
|
||||
// onSelected
|
||||
coreContext.postOnCoreThread {
|
||||
|
|
@ -1281,7 +1282,7 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
val params = getChatRoomParams(call) ?: return // TODO: show error to user
|
||||
val conversation = core.createChatRoom(params, localAddress, participants)
|
||||
if (conversation != null) {
|
||||
if (params.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (params.chatParams?.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (conversation.state == ChatRoom.State.Created) {
|
||||
val id = LinphoneUtils.getChatRoomId(conversation)
|
||||
Log.i("$TAG 1-1 conversation [$id] has been created")
|
||||
|
|
@ -1323,37 +1324,39 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun getChatRoomParams(call: Call): ChatRoomParams? {
|
||||
private fun getChatRoomParams(call: Call): ConferenceParams? {
|
||||
val localAddress = call.callLog.localAddress
|
||||
val remoteAddress = call.remoteAddress
|
||||
val core = call.core
|
||||
val account = LinphoneUtils.getAccountForAddress(localAddress) ?: LinphoneUtils.getDefaultAccount() ?: return null
|
||||
|
||||
val params: ChatRoomParams = core.createDefaultChatRoomParams()
|
||||
val params = coreContext.core.createConferenceParams(call.conference)
|
||||
params.isChatEnabled = true
|
||||
params.isGroupEnabled = false
|
||||
params.subject = AppUtils.getString(R.string.conversation_one_to_one_hidden_subject)
|
||||
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
val chatParams = params.chatParams ?: return null
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
|
||||
val sameDomain = remoteAddress.domain == corePreferences.defaultDomain && remoteAddress.domain == account.params.domain
|
||||
if (account.params.instantMessagingEncryptionMandatory && sameDomain) {
|
||||
Log.i(
|
||||
"$TAG Account is in secure mode & domain matches, requesting E2E encryption"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else if (!account.params.instantMessagingEncryptionMandatory) {
|
||||
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME is available, requesting E2E encryption"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME isn't available, disabling E2E encryption"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.Basic
|
||||
params.isEncryptionEnabled = false
|
||||
chatParams.backend = ChatRoom.Backend.Basic
|
||||
params.securityLevel = Conference.SecurityLevel.None
|
||||
}
|
||||
} else {
|
||||
Log.e(
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ import androidx.annotation.WorkerThread
|
|||
import androidx.lifecycle.MutableLiveData
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.R
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.ConferenceParams
|
||||
import org.linphone.core.ConferenceScheduler
|
||||
import org.linphone.core.ConferenceSchedulerListenerStub
|
||||
import org.linphone.core.Factory
|
||||
|
|
@ -149,11 +151,12 @@ abstract class AbstractConversationViewModel : GenericViewModel() {
|
|||
|
||||
if (localAddress != null && remoteAddress != null) {
|
||||
Log.i("$TAG Searching for conversation in Core using local & peer SIP addresses")
|
||||
val params: ConferenceParams? = null
|
||||
val found = core.searchChatRoom(
|
||||
null,
|
||||
params,
|
||||
localAddress,
|
||||
remoteAddress,
|
||||
arrayOfNulls(
|
||||
arrayOfNulls<Address>(
|
||||
0
|
||||
)
|
||||
)
|
||||
|
|
@ -229,7 +232,7 @@ abstract class AbstractConversationViewModel : GenericViewModel() {
|
|||
Log.i(
|
||||
"$TAG Creating group call with subject ${conferenceInfo.subject} and ${participants.size} participant(s)"
|
||||
)
|
||||
val conferenceScheduler = core.createConferenceScheduler()
|
||||
val conferenceScheduler = LinphoneUtils.createConferenceScheduler(account)
|
||||
conferenceScheduler.addListener(conferenceSchedulerListener)
|
||||
conferenceScheduler.account = account
|
||||
// Will trigger the conference creation/update automatically
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import org.linphone.contacts.getListOfSipAddressesAndPhoneNumbers
|
|||
import org.linphone.core.Address
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.ChatRoomListenerStub
|
||||
import org.linphone.core.ChatRoomParams
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener
|
||||
import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel
|
||||
|
|
@ -189,29 +189,31 @@ class ConversationForwardMessageViewModel @UiThread constructor() : AddressSelec
|
|||
|
||||
operationInProgress.postValue(true)
|
||||
|
||||
val params: ChatRoomParams = coreContext.core.createDefaultChatRoomParams()
|
||||
val params = coreContext.core.createConferenceParams(null)
|
||||
params.isChatEnabled = true
|
||||
params.isGroupEnabled = false
|
||||
params.subject = AppUtils.getString(R.string.conversation_one_to_one_hidden_subject)
|
||||
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
val chatParams = params.chatParams ?: return
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
|
||||
val sameDomain = remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
|
||||
if (account.params.instantMessagingEncryptionMandatory && sameDomain) {
|
||||
Log.i("$TAG Account is in secure mode & domain matches, creating a E2E conversation")
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else if (!account.params.instantMessagingEncryptionMandatory) {
|
||||
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.Basic
|
||||
params.isEncryptionEnabled = false
|
||||
chatParams.backend = ChatRoom.Backend.Basic
|
||||
params.securityLevel = Conference.SecurityLevel.None
|
||||
}
|
||||
} else {
|
||||
Log.e(
|
||||
|
|
@ -238,7 +240,7 @@ class ConversationForwardMessageViewModel @UiThread constructor() : AddressSelec
|
|||
)
|
||||
val chatRoom = core.createChatRoom(params, localAddress, participants)
|
||||
if (chatRoom != null) {
|
||||
if (params.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatRoom.state == ChatRoom.State.Created) {
|
||||
val id = LinphoneUtils.getChatRoomId(chatRoom)
|
||||
Log.i("$TAG 1-1 conversation [$id] has been created")
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import org.linphone.R
|
|||
import org.linphone.core.Address
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.ChatRoomListenerStub
|
||||
import org.linphone.core.ChatRoomParams
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.viewmodel.AddressSelectionViewModel
|
||||
import org.linphone.utils.AppUtils
|
||||
|
|
@ -112,11 +112,14 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM
|
|||
operationInProgress.postValue(true)
|
||||
|
||||
val groupChatRoomSubject = subject.value.orEmpty()
|
||||
val params: ChatRoomParams = coreContext.core.createDefaultChatRoomParams()
|
||||
val params = coreContext.core.createConferenceParams(null)
|
||||
params.isChatEnabled = true
|
||||
params.isGroupEnabled = true
|
||||
params.subject = groupChatRoomSubject
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
val chatParams = params.chatParams ?: return@postOnCoreThread
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
|
||||
val participants = arrayListOf<Address>()
|
||||
for (participant in selection.value.orEmpty()) {
|
||||
|
|
@ -131,7 +134,7 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM
|
|||
participants.toArray(participantsArray)
|
||||
)
|
||||
if (chatRoom != null) {
|
||||
if (params.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatRoom.state == ChatRoom.State.Created) {
|
||||
val id = LinphoneUtils.getChatRoomId(chatRoom)
|
||||
Log.i(
|
||||
|
|
@ -188,29 +191,31 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM
|
|||
|
||||
operationInProgress.postValue(true)
|
||||
|
||||
val params: ChatRoomParams = coreContext.core.createDefaultChatRoomParams()
|
||||
val params = coreContext.core.createConferenceParams(null)
|
||||
params.isChatEnabled = true
|
||||
params.isGroupEnabled = false
|
||||
params.subject = AppUtils.getString(R.string.conversation_one_to_one_hidden_subject)
|
||||
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
val chatParams = params.chatParams ?: return
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
|
||||
val sameDomain = remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
|
||||
if (account.params.instantMessagingEncryptionMandatory && sameDomain) {
|
||||
Log.i("$TAG Account is in secure mode & domain matches, creating a E2E conversation")
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else if (!account.params.instantMessagingEncryptionMandatory) {
|
||||
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.Basic
|
||||
params.isEncryptionEnabled = false
|
||||
chatParams.backend = ChatRoom.Backend.Basic
|
||||
params.securityLevel = Conference.SecurityLevel.None
|
||||
}
|
||||
} else {
|
||||
Log.e(
|
||||
|
|
@ -232,7 +237,7 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM
|
|||
)
|
||||
val chatRoom = core.createChatRoom(params, localAddress, participants)
|
||||
if (chatRoom != null) {
|
||||
if (params.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatRoom.state == ChatRoom.State.Created) {
|
||||
val id = LinphoneUtils.getChatRoomId(chatRoom)
|
||||
Log.i("$TAG 1-1 conversation [$id] has been created")
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ import org.linphone.core.Address
|
|||
import org.linphone.core.Call
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.ChatRoomListenerStub
|
||||
import org.linphone.core.ChatRoomParams
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.Core
|
||||
import org.linphone.core.CoreListenerStub
|
||||
import org.linphone.core.Friend
|
||||
|
|
@ -501,31 +501,33 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
|
|||
"$TAG Looking for existing conversation between [$localSipUri] and [$remoteSipUri]"
|
||||
)
|
||||
|
||||
val params: ChatRoomParams = coreContext.core.createDefaultChatRoomParams()
|
||||
val params = coreContext.core.createConferenceParams(null)
|
||||
params.isChatEnabled = true
|
||||
params.isGroupEnabled = false
|
||||
params.subject = AppUtils.getString(R.string.conversation_one_to_one_hidden_subject)
|
||||
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
val chatParams = params.chatParams ?: return
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
|
||||
val sameDomain = remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
|
||||
if (account.params.instantMessagingEncryptionMandatory && sameDomain) {
|
||||
Log.i(
|
||||
"$TAG Account is in secure mode & domain matches, creating a E2E conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else if (!account.params.instantMessagingEncryptionMandatory) {
|
||||
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.Basic
|
||||
params.isEncryptionEnabled = false
|
||||
chatParams.backend = ChatRoom.Backend.Basic
|
||||
params.securityLevel = Conference.SecurityLevel.None
|
||||
}
|
||||
} else {
|
||||
Log.e(
|
||||
|
|
@ -554,7 +556,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
|
|||
operationInProgress.postValue(true)
|
||||
val chatRoom = core.createChatRoom(params, localAddress, participants)
|
||||
if (chatRoom != null) {
|
||||
if (params.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatRoom.state == ChatRoom.State.Created) {
|
||||
val id = LinphoneUtils.getChatRoomId(chatRoom)
|
||||
Log.i("$TAG 1-1 conversation [$id] has been created")
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import org.linphone.R
|
|||
import org.linphone.core.Address
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.ChatRoomListenerStub
|
||||
import org.linphone.core.ChatRoomParams
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.GenericViewModel
|
||||
import org.linphone.ui.main.history.model.CallLogHistoryModel
|
||||
|
|
@ -184,31 +184,33 @@ class HistoryViewModel @UiThread constructor() : GenericViewModel() {
|
|||
"$TAG Looking for existing conversation between [$localSipUri] and [$remoteSipUri]"
|
||||
)
|
||||
|
||||
val params: ChatRoomParams = coreContext.core.createDefaultChatRoomParams()
|
||||
val params = coreContext.core.createConferenceParams(null)
|
||||
params.isChatEnabled = true
|
||||
params.isGroupEnabled = false
|
||||
params.subject = AppUtils.getString(R.string.conversation_one_to_one_hidden_subject)
|
||||
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
val chatParams = params.chatParams ?: return@postOnCoreThread
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
|
||||
val sameDomain = remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
|
||||
if (account.params.instantMessagingEncryptionMandatory && sameDomain) {
|
||||
Log.i(
|
||||
"$TAG Account is in secure mode & domain matches, creating a E2E conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else if (!account.params.instantMessagingEncryptionMandatory) {
|
||||
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.isEncryptionEnabled = true
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
params.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Account is in interop mode but LIME isn't available, creating a SIP simple conversation"
|
||||
)
|
||||
params.backend = ChatRoom.Backend.Basic
|
||||
params.isEncryptionEnabled = false
|
||||
chatParams.backend = ChatRoom.Backend.Basic
|
||||
params.securityLevel = Conference.SecurityLevel.None
|
||||
}
|
||||
} else {
|
||||
Log.e(
|
||||
|
|
@ -237,7 +239,7 @@ class HistoryViewModel @UiThread constructor() : GenericViewModel() {
|
|||
operationInProgress.postValue(true)
|
||||
val chatRoom = core.createChatRoom(params, localAddress, participants)
|
||||
if (chatRoom != null) {
|
||||
if (params.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatParams.backend == ChatRoom.Backend.FlexisipChat) {
|
||||
if (chatRoom.state == ChatRoom.State.Created) {
|
||||
val id = LinphoneUtils.getChatRoomId(chatRoom)
|
||||
Log.i("$TAG 1-1 conversation [$id] has been created")
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ class StartCallViewModel @UiThread constructor() : AddressSelectionViewModel() {
|
|||
Log.i(
|
||||
"$TAG Creating group call with subject ${subject.value} and ${participants.size} participant(s)"
|
||||
)
|
||||
val conferenceScheduler = core.createConferenceScheduler()
|
||||
val conferenceScheduler = LinphoneUtils.createConferenceScheduler(account)
|
||||
conferenceScheduler.addListener(conferenceSchedulerListener)
|
||||
conferenceScheduler.account = account
|
||||
// Will trigger the conference creation/update automatically
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
|||
import org.linphone.R
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.databinding.MeetingsListFragmentBinding
|
||||
import org.linphone.ui.GenericActivity
|
||||
import org.linphone.ui.main.fragment.AbstractMainFragment
|
||||
import org.linphone.ui.main.history.model.ConfirmationDialogModel
|
||||
import org.linphone.ui.main.meetings.adapter.MeetingsListAdapter
|
||||
|
|
@ -59,6 +60,8 @@ class MeetingsListFragment : AbstractMainFragment() {
|
|||
|
||||
private var bottomSheetDialog: BottomSheetDialogFragment? = null
|
||||
|
||||
private var meetingViewModelBeingCancelled: MeetingModel? = null
|
||||
|
||||
private val dataObserver = object : AdapterDataObserver() {
|
||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||
if (positionStart == 0 && adapter.itemCount == itemCount) {
|
||||
|
|
@ -161,6 +164,24 @@ class MeetingsListFragment : AbstractMainFragment() {
|
|||
listViewModel.fetchInProgress.value = false
|
||||
}
|
||||
|
||||
listViewModel.conferenceCancelledEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
Log.i("$TAG Meeting has been cancelled successfully, deleting it")
|
||||
(requireActivity() as GenericActivity).showGreenToast(
|
||||
getString(R.string.meeting_info_cancelled_toast),
|
||||
R.drawable.trash_simple
|
||||
)
|
||||
|
||||
meetingViewModelBeingCancelled?.delete()
|
||||
meetingViewModelBeingCancelled = null
|
||||
listViewModel.applyFilter()
|
||||
(requireActivity() as GenericActivity).showGreenToast(
|
||||
getString(R.string.meeting_info_deleted_toast),
|
||||
R.drawable.trash_simple
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
adapter.meetingLongClickedEvent.observe(viewLifecycleOwner) {
|
||||
it.consume { model ->
|
||||
val modalBottomSheet = MeetingsMenuDialogFragment(
|
||||
|
|
@ -168,12 +189,17 @@ class MeetingsListFragment : AbstractMainFragment() {
|
|||
adapter.resetSelection()
|
||||
},
|
||||
{ // onDelete
|
||||
if (model.isOrganizer()) {
|
||||
if (model.isOrganizer() && !model.isCancelled) {
|
||||
showCancelMeetingDialog(model)
|
||||
} else {
|
||||
Log.i("$TAG Deleting meeting [${model.id}]")
|
||||
model.delete()
|
||||
listViewModel.applyFilter()
|
||||
|
||||
(requireActivity() as GenericActivity).showGreenToast(
|
||||
getString(R.string.meeting_info_deleted_toast),
|
||||
R.drawable.trash_simple
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
@ -296,16 +322,20 @@ class MeetingsListFragment : AbstractMainFragment() {
|
|||
Log.i("$TAG Deleting meeting [${meetingModel.id}]")
|
||||
meetingModel.delete()
|
||||
listViewModel.applyFilter()
|
||||
|
||||
dialog.dismiss()
|
||||
(requireActivity() as GenericActivity).showGreenToast(
|
||||
getString(R.string.meeting_info_deleted_toast),
|
||||
R.drawable.trash_simple
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
model.confirmEvent.observe(viewLifecycleOwner) {
|
||||
it.consume {
|
||||
Log.i("$TAG Cancelling meeting [${meetingModel.id}]")
|
||||
meetingViewModelBeingCancelled = meetingModel
|
||||
listViewModel.cancelMeeting(meetingModel.conferenceInfo)
|
||||
meetingModel.delete()
|
||||
listViewModel.applyFilter()
|
||||
dialog.dismiss()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import androidx.lifecycle.MutableLiveData
|
|||
import java.util.TimeZone
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.ConferenceInfo
|
||||
import org.linphone.core.ConferenceScheduler
|
||||
import org.linphone.core.ConferenceSchedulerListenerStub
|
||||
|
|
@ -36,6 +35,7 @@ import org.linphone.ui.GenericViewModel
|
|||
import org.linphone.ui.main.meetings.model.ParticipantModel
|
||||
import org.linphone.ui.main.meetings.model.TimeZoneModel
|
||||
import org.linphone.utils.Event
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
import org.linphone.utils.TimestampUtils
|
||||
|
||||
class MeetingViewModel @UiThread constructor() : GenericViewModel() {
|
||||
|
|
@ -90,12 +90,12 @@ class MeetingViewModel @UiThread constructor() : GenericViewModel() {
|
|||
Log.i(
|
||||
"$TAG Conference ${conferenceScheduler.info?.subject} cancelled"
|
||||
)
|
||||
val chatRoomParams = coreContext.core.createDefaultChatRoomParams()
|
||||
chatRoomParams.isGroupEnabled = false
|
||||
chatRoomParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
chatRoomParams.isEncryptionEnabled = true
|
||||
chatRoomParams.subject = "Meeting cancelled" // Won't be used
|
||||
conferenceScheduler.sendInvitations(chatRoomParams) // Send cancel ICS
|
||||
val params = LinphoneUtils.getChatRoomParamsToCancelMeeting()
|
||||
if (params != null) {
|
||||
conferenceScheduler.sendInvitations(params)
|
||||
} else {
|
||||
operationInProgress.postValue(false)
|
||||
}
|
||||
} else if (state == ConferenceScheduler.State.Error) {
|
||||
operationInProgress.postValue(false)
|
||||
}
|
||||
|
|
@ -185,7 +185,9 @@ class MeetingViewModel @UiThread constructor() : GenericViewModel() {
|
|||
if (::conferenceInfo.isInitialized) {
|
||||
Log.i("$TAG Cancelling conference information [$conferenceInfo]")
|
||||
operationInProgress.postValue(true)
|
||||
val conferenceScheduler = core.createConferenceScheduler()
|
||||
val conferenceScheduler = LinphoneUtils.createConferenceScheduler(
|
||||
LinphoneUtils.getDefaultAccount()
|
||||
)
|
||||
conferenceScheduler.addListener(conferenceSchedulerListener)
|
||||
conferenceScheduler.cancelConference(conferenceInfo)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,18 @@ import androidx.annotation.UiThread
|
|||
import androidx.annotation.WorkerThread
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.ConferenceInfo
|
||||
import org.linphone.core.ConferenceScheduler
|
||||
import org.linphone.core.ConferenceSchedulerListenerStub
|
||||
import org.linphone.core.Core
|
||||
import org.linphone.core.CoreListenerStub
|
||||
import org.linphone.core.tools.Log
|
||||
import org.linphone.ui.main.meetings.model.MeetingListItemModel
|
||||
import org.linphone.ui.main.meetings.model.MeetingModel
|
||||
import org.linphone.ui.main.viewmodel.AbstractMainViewModel
|
||||
import org.linphone.utils.Event
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
import org.linphone.utils.TimestampUtils
|
||||
|
||||
class MeetingsListViewModel @UiThread constructor() : AbstractMainViewModel() {
|
||||
|
|
@ -41,6 +46,12 @@ class MeetingsListViewModel @UiThread constructor() : AbstractMainViewModel() {
|
|||
|
||||
val fetchInProgress = MutableLiveData<Boolean>()
|
||||
|
||||
val operationInProgress = MutableLiveData<Boolean>()
|
||||
|
||||
val conferenceCancelledEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
||||
private val coreListener = object : CoreListenerStub() {
|
||||
@WorkerThread
|
||||
override fun onConferenceInfoReceived(core: Core, conferenceInfo: ConferenceInfo) {
|
||||
|
|
@ -49,7 +60,51 @@ class MeetingsListViewModel @UiThread constructor() : AbstractMainViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
Log.i(
|
||||
"$TAG Conference ${conferenceScheduler.info?.subject} cancelled"
|
||||
)
|
||||
val params = LinphoneUtils.getChatRoomParamsToCancelMeeting()
|
||||
if (params != null) {
|
||||
conferenceScheduler.sendInvitations(params)
|
||||
} else {
|
||||
operationInProgress.postValue(false)
|
||||
}
|
||||
} else if (state == ConferenceScheduler.State.Error) {
|
||||
operationInProgress.postValue(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInvitationsSent(
|
||||
conferenceScheduler: ConferenceScheduler,
|
||||
failedInvitations: Array<out Address>?
|
||||
) {
|
||||
if (failedInvitations?.isNotEmpty() == true) {
|
||||
for (address in failedInvitations) {
|
||||
Log.e(
|
||||
"$TAG Conference cancelled ICS wasn't sent to participant ${address.asStringUriOnly()}"
|
||||
)
|
||||
}
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Conference cancelled ICS successfully sent to all participants"
|
||||
)
|
||||
}
|
||||
conferenceScheduler.removeListener(this)
|
||||
|
||||
operationInProgress.postValue(false)
|
||||
conferenceCancelledEvent.postValue(Event(true))
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
operationInProgress.value = false
|
||||
fetchInProgress.value = true
|
||||
|
||||
coreContext.postOnCoreThread { core ->
|
||||
|
|
@ -79,7 +134,11 @@ class MeetingsListViewModel @UiThread constructor() : AbstractMainViewModel() {
|
|||
fun cancelMeeting(conferenceInfo: ConferenceInfo) {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
Log.w("$TAG Cancelling conference info [${conferenceInfo.uri?.asStringUriOnly()}]")
|
||||
val conferenceScheduler = core.createConferenceScheduler()
|
||||
operationInProgress.postValue(true)
|
||||
val conferenceScheduler = LinphoneUtils.createConferenceScheduler(
|
||||
LinphoneUtils.getDefaultAccount()
|
||||
)
|
||||
conferenceScheduler.addListener(conferenceSchedulerListener)
|
||||
conferenceScheduler.cancelConference(conferenceInfo)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.linphone.LinphoneApplication.Companion.corePreferences
|
|||
import org.linphone.R
|
||||
import org.linphone.core.Address
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.ConferenceInfo
|
||||
import org.linphone.core.ConferenceScheduler
|
||||
import org.linphone.core.ConferenceSchedulerListenerStub
|
||||
|
|
@ -41,6 +42,7 @@ import org.linphone.ui.GenericViewModel
|
|||
import org.linphone.ui.main.meetings.model.TimeZoneModel
|
||||
import org.linphone.ui.main.model.SelectedAddressModel
|
||||
import org.linphone.utils.Event
|
||||
import org.linphone.utils.LinphoneUtils
|
||||
import org.linphone.utils.TimestampUtils
|
||||
|
||||
class ScheduleMeetingViewModel @UiThread constructor() : GenericViewModel() {
|
||||
|
|
@ -129,11 +131,15 @@ class ScheduleMeetingViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
if (sendInvitations.value == true) {
|
||||
Log.i("$TAG User asked for invitations to be sent, let's do it")
|
||||
val chatRoomParams = coreContext.core.createDefaultChatRoomParams()
|
||||
|
||||
val chatRoomParams = coreContext.core.createConferenceParams(null)
|
||||
chatRoomParams.isChatEnabled = true
|
||||
chatRoomParams.isGroupEnabled = false
|
||||
chatRoomParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
chatRoomParams.isEncryptionEnabled = true
|
||||
chatRoomParams.subject = "Meeting invitation" // Won't be used
|
||||
val chatParams = chatRoomParams.chatParams ?: return
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
chatRoomParams.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
conferenceScheduler.sendInvitations(chatRoomParams)
|
||||
} else {
|
||||
Log.i("$TAG User didn't asked for invitations to be sent")
|
||||
|
|
@ -459,7 +465,7 @@ class ScheduleMeetingViewModel @UiThread constructor() : GenericViewModel() {
|
|||
conferenceInfo.setParticipantInfos(participantsInfoArray)
|
||||
|
||||
if (!::conferenceScheduler.isInitialized) {
|
||||
conferenceScheduler = core.createConferenceScheduler()
|
||||
conferenceScheduler = LinphoneUtils.createConferenceScheduler(localAccount)
|
||||
conferenceScheduler.addListener(conferenceSchedulerListener)
|
||||
}
|
||||
|
||||
|
|
@ -511,7 +517,9 @@ class ScheduleMeetingViewModel @UiThread constructor() : GenericViewModel() {
|
|||
conferenceInfo.setParticipantInfos(participantsInfoArray)
|
||||
|
||||
if (!::conferenceScheduler.isInitialized) {
|
||||
conferenceScheduler = core.createConferenceScheduler()
|
||||
conferenceScheduler = LinphoneUtils.createConferenceScheduler(
|
||||
LinphoneUtils.getDefaultAccount()
|
||||
)
|
||||
conferenceScheduler.addListener(conferenceSchedulerListener)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,10 @@ import org.linphone.core.Call.Status
|
|||
import org.linphone.core.CallLog
|
||||
import org.linphone.core.ChatMessage
|
||||
import org.linphone.core.ChatRoom
|
||||
import org.linphone.core.Conference
|
||||
import org.linphone.core.ConferenceInfo
|
||||
import org.linphone.core.ConferenceParams
|
||||
import org.linphone.core.ConferenceScheduler
|
||||
import org.linphone.core.Core
|
||||
import org.linphone.core.Factory
|
||||
import org.linphone.core.Friend
|
||||
|
|
@ -213,6 +216,39 @@ class LinphoneUtils {
|
|||
return core.defaultAccount?.params?.audioVideoConferenceFactoryAddress != null
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun createConferenceScheduler(account: Account?): ConferenceScheduler {
|
||||
if (!account?.params?.ccmpServerUrl.isNullOrEmpty()) {
|
||||
Log.i(
|
||||
"$TAG CCMP server URL has been set in Account's params, using CCMP conference scheduler"
|
||||
)
|
||||
return coreContext.core.createConferenceSchedulerWithType(
|
||||
account,
|
||||
ConferenceScheduler.Type.CCMP
|
||||
)
|
||||
}
|
||||
Log.i(
|
||||
"$TAG CCMP server URL hasn't been set in Account's params, using SIP conference scheduler"
|
||||
)
|
||||
return coreContext.core.createConferenceSchedulerWithType(
|
||||
account,
|
||||
ConferenceScheduler.Type.SIP
|
||||
)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun getChatRoomParamsToCancelMeeting(): ConferenceParams? {
|
||||
val chatRoomParams = coreContext.core.createConferenceParams(null)
|
||||
chatRoomParams.isChatEnabled = true
|
||||
chatRoomParams.isGroupEnabled = false
|
||||
chatRoomParams.subject = "Meeting invitation" // Won't be used
|
||||
val chatParams = chatRoomParams.chatParams ?: return null
|
||||
chatParams.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
|
||||
chatParams.backend = ChatRoom.Backend.FlexisipChat
|
||||
chatRoomParams.securityLevel = Conference.SecurityLevel.EndToEnd
|
||||
return chatRoomParams
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun arePushNotificationsAvailable(core: Core): Boolean {
|
||||
if (!core.isPushNotificationAvailable) {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,10 @@
|
|||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/operation_in_progress"
|
||||
bind:visibility="@{viewModel.operationInProgress}" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
|
|
|
|||
|
|
@ -103,6 +103,10 @@
|
|||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<include
|
||||
layout="@layout/operation_in_progress"
|
||||
bind:visibility="@{viewModel.operationInProgress}" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue