diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt index 3d4223e6d..514c2a7f2 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt @@ -37,7 +37,11 @@ import org.linphone.core.FriendList import org.linphone.core.FriendListListenerStub import org.linphone.core.tools.Log import org.linphone.ui.main.MainActivity +import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener +import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel +import org.linphone.ui.main.model.isInSecureMode import org.linphone.utils.ImageUtils +import org.linphone.utils.PhoneNumberUtils class ContactsManager @UiThread constructor(context: Context) { companion object { @@ -139,6 +143,10 @@ class ContactsManager @UiThread constructor(context: Context) { list.removeListener(friendListListener) } } + + interface ContactsListener { + fun onContactsLoaded() + } } @WorkerThread @@ -168,6 +176,84 @@ fun Friend.getPerson(): Person { return personBuilder.build() } -interface ContactsListener { - fun onContactsLoaded() +@WorkerThread +fun Friend.getListOfSipAddressesAndPhoneNumbers(listener: ContactNumberOrAddressClickListener): ArrayList { + val addressesAndNumbers = arrayListOf() + + for (address in addresses) { + val data = ContactNumberOrAddressModel( + address, + address.asStringUriOnly(), + true, // SIP addresses are always enabled + listener, + true + ) + addressesAndNumbers.add(data) + } + val indexOfLastSipAddress = addressesAndNumbers.count() + Log.i( + "[Friend] Contact [$name] has [$indexOfLastSipAddress] SIP ${if (indexOfLastSipAddress > 1) "addresses" else "address"}" + ) + + for (number in phoneNumbersWithLabel) { + val presenceModel = getPresenceModelForUriOrTel(number.phoneNumber) + val hasPresenceInfo = !presenceModel?.contact.isNullOrEmpty() + var presenceAddress: Address? = null + + if (presenceModel != null && hasPresenceInfo) { + Log.i("[Friend] Phone number [${number.phoneNumber}] has presence information") + // Show linked SIP address if not already stored as-is + val contact = presenceModel.contact + val found = addressesAndNumbers.find { + it.displayedValue == contact + } + if (!contact.isNullOrEmpty() && found == null) { + val address = core.interpretUrl(contact, false) + if (address != null) { + address.clean() // To remove ;user=phone + presenceAddress = address + val data = ContactNumberOrAddressModel( + address, + address.asStringUriOnly(), + true, // SIP addresses are always enabled + listener, + true + ) + addressesAndNumbers.add(indexOfLastSipAddress, data) + Log.i( + "[Friend] Phone number [${number.phoneNumber}] is linked to SIP address [${presenceAddress.asStringUriOnly()}]" + ) + } + } else if (found != null) { + presenceAddress = found.address + Log.i( + "[Friend] Phone number [${number.phoneNumber}] is linked to existing SIP address [${presenceAddress?.asStringUriOnly()}]" + ) + } + } + + // phone numbers are disabled is secure mode unless linked to a SIP address + val enablePhoneNumbers = hasPresenceInfo || core.defaultAccount?.isInSecureMode() != true + val address = presenceAddress ?: core.interpretUrl(number.phoneNumber, true) + val label = PhoneNumberUtils.vcardParamStringToAddressBookLabel( + coreContext.context.resources, + number.label ?: "" + ) + val data = ContactNumberOrAddressModel( + address, + number.phoneNumber, + enablePhoneNumbers, + listener, + false, + label, + presenceAddress != null + ) + addressesAndNumbers.add(data) + } + + val phoneNumbersCount = addressesAndNumbers.count() - indexOfLastSipAddress + Log.i( + "[Friend] Contact [$name] has [$phoneNumbersCount] phone ${if (phoneNumbersCount > 1) "numbers" else "number"}" + ) + return addressesAndNumbers } diff --git a/app/src/main/java/org/linphone/ui/main/calls/fragment/StartCallFragment.kt b/app/src/main/java/org/linphone/ui/main/calls/fragment/StartCallFragment.kt index 3cea39d7a..3b9f3bc8c 100644 --- a/app/src/main/java/org/linphone/ui/main/calls/fragment/StartCallFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/calls/fragment/StartCallFragment.kt @@ -30,6 +30,7 @@ import androidx.navigation.navGraphViewModels import androidx.recyclerview.widget.LinearLayoutManager import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.R +import org.linphone.contacts.getListOfSipAddressesAndPhoneNumbers import org.linphone.core.tools.Log import org.linphone.databinding.CallStartFragmentBinding import org.linphone.ui.main.calls.viewmodel.StartCallViewModel @@ -160,32 +161,7 @@ class StartCallFragment : GenericFragment() { coreContext.startCall(address) } } else { - val list = arrayListOf() - for (address in friend.addresses) { - val addressModel = ContactNumberOrAddressModel( - address, - address.asStringUriOnly(), - true, - listener, - true - ) - list.add(addressModel) - } - - if (enablePhoneNumbers) { - for (number in friend.phoneNumbersWithLabel) { - val address = core.interpretUrl(number.phoneNumber, true) - val addressModel = ContactNumberOrAddressModel( - address, - number.phoneNumber, - true, - listener, - false, - number.label.orEmpty() - ) - list.add(addressModel) - } - } + val list = friend.getListOfSipAddressesAndPhoneNumbers(listener) coreContext.postOnMainThread { val model = NumberOrAddressPickerDialogModel(list) diff --git a/app/src/main/java/org/linphone/ui/main/calls/viewmodel/StartCallViewModel.kt b/app/src/main/java/org/linphone/ui/main/calls/viewmodel/StartCallViewModel.kt index 4b9981999..6705a9033 100644 --- a/app/src/main/java/org/linphone/ui/main/calls/viewmodel/StartCallViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/calls/viewmodel/StartCallViewModel.kt @@ -26,7 +26,7 @@ import androidx.lifecycle.ViewModel import java.util.ArrayList import org.linphone.LinphoneApplication import org.linphone.LinphoneApplication.Companion.coreContext -import org.linphone.contacts.ContactsListener +import org.linphone.contacts.ContactsManager.ContactsListener import org.linphone.core.Address import org.linphone.core.Friend import org.linphone.core.MagicSearch diff --git a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactNumberOrAddressModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactNumberOrAddressModel.kt index c3b82f32b..435e01660 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/model/ContactNumberOrAddressModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/model/ContactNumberOrAddressModel.kt @@ -20,10 +20,11 @@ package org.linphone.ui.main.contacts.model import androidx.annotation.UiThread +import androidx.annotation.WorkerThread import androidx.lifecycle.MutableLiveData import org.linphone.core.Address -class ContactNumberOrAddressModel @UiThread constructor( +class ContactNumberOrAddressModel @WorkerThread constructor( val address: Address?, val displayedValue: String, val isEnabled: Boolean, diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt index 0d3cdd86e..50647b561 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactViewModel.kt @@ -27,17 +27,15 @@ import java.io.File import java.util.Locale import kotlinx.coroutines.launch import org.linphone.LinphoneApplication.Companion.coreContext -import org.linphone.core.Address +import org.linphone.contacts.getListOfSipAddressesAndPhoneNumbers import org.linphone.core.Friend import org.linphone.core.tools.Log import org.linphone.ui.main.contacts.model.ContactAvatarModel import org.linphone.ui.main.contacts.model.ContactDeviceModel import org.linphone.ui.main.contacts.model.ContactNumberOrAddressClickListener import org.linphone.ui.main.contacts.model.ContactNumberOrAddressModel -import org.linphone.ui.main.model.isInSecureMode import org.linphone.utils.Event import org.linphone.utils.FileUtils -import org.linphone.utils.PhoneNumberUtils class ContactViewModel @UiThread constructor() : ViewModel() { companion object { @@ -124,7 +122,7 @@ class ContactViewModel @UiThread constructor() : ViewModel() { @UiThread fun findContactByRefKey(refKey: String) { - coreContext.postOnCoreThread { core -> + coreContext.postOnCoreThread { val friend = coreContext.contactsManager.findContactById(refKey) if (friend != null) { Log.i("$TAG Found contact [${friend.name}] matching ref key [$refKey]") @@ -142,82 +140,7 @@ class ContactViewModel @UiThread constructor() : ViewModel() { title.postValue(jobTitle!!) } - val addressesAndNumbers = arrayListOf() - for (address in friend.addresses) { - val data = ContactNumberOrAddressModel( - address, - address.asStringUriOnly(), - true, // SIP addresses are always enabled - listener, - true - ) - addressesAndNumbers.add(data) - } - val indexOfLastSipAddress = addressesAndNumbers.count() - Log.i( - "$TAG Contact [${friend.name}] has [$indexOfLastSipAddress] SIP ${if (indexOfLastSipAddress > 1) "addresses" else "address"}" - ) - - for (number in friend.phoneNumbersWithLabel) { - val presenceModel = friend.getPresenceModelForUriOrTel(number.phoneNumber) - val hasPresenceInfo = !presenceModel?.contact.isNullOrEmpty() - var presenceAddress: Address? = null - - if (presenceModel != null && hasPresenceInfo) { - Log.i("$TAG Phone number [${number.phoneNumber}] has presence information") - // Show linked SIP address if not already stored as-is - val contact = presenceModel.contact - val found = addressesAndNumbers.find { - it.displayedValue == contact - } - if (!contact.isNullOrEmpty() && found == null) { - val address = core.interpretUrl(contact, false) - if (address != null) { - address.clean() // To remove ;user=phone - presenceAddress = address - val data = ContactNumberOrAddressModel( - address, - address.asStringUriOnly(), - true, // SIP addresses are always enabled - listener, - true - ) - addressesAndNumbers.add(indexOfLastSipAddress, data) - Log.i( - "$TAG Phone number [${number.phoneNumber}] is linked to SIP address [${presenceAddress.asStringUriOnly()}]" - ) - } - } else if (found != null) { - presenceAddress = found.address - Log.i( - "$TAG Phone number [${number.phoneNumber}] is linked to existing SIP address [${presenceAddress?.asStringUriOnly()}]" - ) - } - } - - // phone numbers are disabled is secure mode unless linked to a SIP address - val enablePhoneNumbers = hasPresenceInfo || core.defaultAccount?.isInSecureMode() != true - val address = presenceAddress ?: core.interpretUrl(number.phoneNumber, true) - val label = PhoneNumberUtils.vcardParamStringToAddressBookLabel( - coreContext.context.resources, - number.label ?: "" - ) - val data = ContactNumberOrAddressModel( - address, - number.phoneNumber, - enablePhoneNumbers, - listener, - false, - label, - presenceAddress != null - ) - addressesAndNumbers.add(data) - } - - val phoneNumbersCount = addressesAndNumbers.count() - indexOfLastSipAddress - Log.i( - "$TAG Contact [${friend.name}] has [$phoneNumbersCount] phone ${if (phoneNumbersCount > 1) "numbers" else "number"}" - ) + val addressesAndNumbers = friend.getListOfSipAddressesAndPhoneNumbers(listener) sipAddressesAndPhoneNumbers.postValue(addressesAndNumbers) val devicesList = arrayListOf() diff --git a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt index 731d756e7..fecc8c653 100644 --- a/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/contacts/viewmodel/ContactsListViewModel.kt @@ -29,7 +29,7 @@ import java.util.Locale import kotlinx.coroutines.launch import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences -import org.linphone.contacts.ContactsListener +import org.linphone.contacts.ContactsManager.ContactsListener import org.linphone.core.Friend import org.linphone.core.MagicSearch import org.linphone.core.MagicSearchListenerStub diff --git a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt index 270cee1a6..c213c6a9e 100644 --- a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationViewModel.kt @@ -24,7 +24,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.contacts.ContactData -import org.linphone.contacts.ContactsListener +import org.linphone.contacts.ContactsManager.ContactsListener import org.linphone.core.Address import org.linphone.core.ChatRoom import org.linphone.core.ChatRoomListenerStub diff --git a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt index 7f7259757..ec317ea06 100644 --- a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/ConversationsListViewModel.kt @@ -24,7 +24,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import java.util.ArrayList import org.linphone.LinphoneApplication.Companion.coreContext -import org.linphone.contacts.ContactsListener +import org.linphone.contacts.ContactsManager.ContactsListener import org.linphone.core.ChatMessage import org.linphone.core.ChatRoom import org.linphone.core.Core diff --git a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt index 873ffdb64..ce63ad676 100644 --- a/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/conversations/viewmodel/NewConversationViewModel.kt @@ -24,7 +24,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.contacts.ContactData -import org.linphone.contacts.ContactsListener +import org.linphone.contacts.ContactsManager.ContactsListener import org.linphone.core.MagicSearch import org.linphone.core.MagicSearchListenerStub import org.linphone.core.SearchResult