From daa789e6726eaac23d3459002dc015e7c3b15f8f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 21 Oct 2020 09:22:52 +0200 Subject: [PATCH] Replaced deprecated ProxyConfig object by Account --- .../linphone/activities/main/MainActivity.kt | 4 +- .../ChatRoomCreationContactsAdapter.kt | 2 +- .../viewmodels/ChatRoomCreationViewModel.kt | 7 +- .../chat/viewmodels/GroupInfoViewModel.kt | 2 +- .../contact/viewmodels/ContactViewModel.kt | 6 +- .../main/fragments/StatusFragment.kt | 10 +- .../fragments/AccountSettingsFragment.kt | 8 +- .../settings/fragments/SettingsFragment.kt | 6 +- .../viewmodels/AccountSettingsViewModel.kt | 239 ++++++++++++------ .../settings/viewmodels/SettingsViewModel.kt | 6 +- .../sidemenu/fragments/SideMenuFragment.kt | 6 +- .../sidemenu/viewmodels/SideMenuViewModel.kt | 26 +- .../main/viewmodels/SharedMainViewModel.kt | 2 +- .../main/viewmodels/StatusViewModel.kt | 18 +- .../org/linphone/contact/ContactsManager.kt | 2 +- .../java/org/linphone/core/CoreContext.kt | 14 +- .../java/org/linphone/core/CorePreferences.kt | 3 + .../java/org/linphone/utils/LinphoneUtils.kt | 10 +- .../res/layout/settings_account_fragment.xml | 17 +- .../main/res/layout/side_menu_fragment.xml | 10 +- app/src/main/res/values-es/strings.xml | 5 +- app/src/main/res/values-fr/strings.xml | 5 +- app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 4 +- app/src/main/res/values/strings.xml | 7 +- 25 files changed, 264 insertions(+), 159 deletions(-) diff --git a/app/src/main/java/org/linphone/activities/main/MainActivity.kt b/app/src/main/java/org/linphone/activities/main/MainActivity.kt index 54ff2bd73..2721215e3 100644 --- a/app/src/main/java/org/linphone/activities/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/activities/main/MainActivity.kt @@ -102,7 +102,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin startActivity(intent) } - if (coreContext.core.proxyConfigList.isEmpty()) { + if (coreContext.core.accountList.isEmpty()) { if (corePreferences.firstStart) { corePreferences.firstStart = false startActivity(Intent(this, AssistantActivity::class.java)) @@ -371,7 +371,7 @@ class MainActivity : GenericActivity(), SnackBarActivity, NavController.OnDestin val peerAddress = coreContext.core.interpretUrl(addressToIM)?.asStringUriOnly() val localAddress = - coreContext.core.defaultProxyConfig?.contact?.asStringUriOnly() + coreContext.core.defaultAccount?.params?.identityAddress?.asStringUriOnly() val deepLink = "linphone-android://chat-room/$localAddress/$peerAddress" Log.i("[Main Activity] Starting deep link: $deepLink") findNavController(R.id.nav_host_fragment).navigate(Uri.parse(deepLink)) diff --git a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatRoomCreationContactsAdapter.kt b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatRoomCreationContactsAdapter.kt index 1fc360fd2..a77f07fe7 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatRoomCreationContactsAdapter.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/adapters/ChatRoomCreationContactsAdapter.kt @@ -101,7 +101,7 @@ class ChatRoomCreationContactsAdapter( securityEnabled: Boolean ) { val searchAddress = searchResult.address - val isMyself = securityEnabled && searchAddress != null && coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(searchAddress) ?: false + val isMyself = securityEnabled && searchAddress != null && coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(searchAddress) ?: false val limeCheck = !securityEnabled || (securityEnabled && searchResult.hasCapability(FriendCapability.LimeX3Dh)) val groupCheck = !groupChatEnabled || (groupChatEnabled && searchResult.hasCapability(FriendCapability.GroupChat)) val disabled = if (searchResult.friend != null) !limeCheck || !groupCheck || isMyself else false // Generated entry from search filter diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomCreationViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomCreationViewModel.kt index 3297cbe0d..9f10ab947 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomCreationViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/ChatRoomCreationViewModel.kt @@ -107,7 +107,7 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() { } fun updateContactsList() { - val domain = if (sipContactsSelected.value == true) coreContext.core.defaultProxyConfig?.domain ?: "" else "" + val domain = if (sipContactsSelected.value == true) coreContext.core.defaultAccount?.params?.domain ?: "" else "" val results = coreContext.contactsManager.magicSearch.getContactListFromFilter(filter.value.orEmpty(), domain) val list = arrayListOf() @@ -145,7 +145,7 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() { fun createOneToOneChat(searchResult: SearchResult) { waitForChatRoomCreation.value = true - val defaultProxyConfig = coreContext.core.defaultProxyConfig + val defaultAccount = coreContext.core.defaultAccount var room: ChatRoom? val address = searchResult.address ?: coreContext.core.interpretUrl(searchResult.phoneNumber ?: "") @@ -167,12 +167,13 @@ class ChatRoomCreationViewModel : ErrorReportingViewModel() { } val participants = arrayOf(address) - val localAddress = defaultProxyConfig?.identityAddress + val localAddress: Address? = defaultAccount?.params?.identityAddress room = coreContext.core.searchChatRoom(params, localAddress, null, participants) if (room == null) { Log.w("[Chat Room Creation] Couldn't find existing 1-1 chat room with remote ${address.asStringUriOnly()}, encryption=$encrypted and local identity ${localAddress?.asStringUriOnly()}") room = coreContext.core.createChatRoom(params, localAddress, participants) + if (encrypted) { room?.addListener(listener) } else { diff --git a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt index a865b2077..b10e8a3d5 100644 --- a/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/chat/viewmodels/GroupInfoViewModel.kt @@ -125,7 +125,7 @@ class GroupInfoViewModel(val chatRoom: ChatRoom?) : ErrorReportingViewModel() { index += 1 } - val chatRoom: ChatRoom? = coreContext.core.createChatRoom(params, coreContext.core.defaultProxyConfig?.identityAddress, addresses) + val chatRoom: ChatRoom? = coreContext.core.createChatRoom(params, coreContext.core.defaultAccount?.params?.identityAddress, addresses) chatRoom?.addListener(listener) if (chatRoom == null) { Log.e("[Chat Room Group Info] Couldn't create chat room!") diff --git a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt index c788020e7..3180ba7e3 100644 --- a/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/contact/viewmodels/ContactViewModel.kt @@ -169,9 +169,9 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont val value = address.asStringUriOnly() val presenceModel = contact.friend?.getPresenceModelForUriOrTel(value) val hasPresence = presenceModel?.basicStatus == PresenceBasicStatus.Open - val isMe = coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(address) ?: false + val isMe = coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(value)?.hasCapability(FriendCapability.LimeX3Dh) ?: false - val displayValue = if (coreContext.core.defaultProxyConfig?.domain == address.domain) (address.username ?: value) else value + val displayValue = if (coreContext.core.defaultAccount?.params?.domain == address.domain) (address.username ?: value) else value val noa = ContactNumberOrAddressViewModel(address, hasPresence, displayValue, showSecureChat = secureChatAllowed, listener = listener) list.add(noa) } @@ -181,7 +181,7 @@ class ContactViewModel(private val c: Contact) : ErrorReportingViewModel(), Cont val hasPresence = presenceModel != null && presenceModel.basicStatus == PresenceBasicStatus.Open val contactAddress = presenceModel?.contact ?: number val address = coreContext.core.interpretUrl(contactAddress) - val isMe = if (address != null) coreContext.core.defaultProxyConfig?.identityAddress?.weakEqual(address) ?: false else false + val isMe = if (address != null) coreContext.core.defaultAccount?.params?.identityAddress?.weakEqual(address) ?: false else false val secureChatAllowed = !isMe && contact.friend?.getPresenceModelForUriOrTel(number)?.hasCapability(FriendCapability.LimeX3Dh) ?: false val noa = ContactNumberOrAddressViewModel(address, hasPresence, number, isSip = false, showSecureChat = secureChatAllowed, typeLabel = phoneNumber.typeLabel, listener = listener) list.add(noa) diff --git a/app/src/main/java/org/linphone/activities/main/fragments/StatusFragment.kt b/app/src/main/java/org/linphone/activities/main/fragments/StatusFragment.kt index 40654baed..874e933d8 100644 --- a/app/src/main/java/org/linphone/activities/main/fragments/StatusFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/fragments/StatusFragment.kt @@ -48,11 +48,11 @@ class StatusFragment : GenericFragment() { ViewModelProvider(this).get(SharedMainViewModel::class.java) } - sharedViewModel.proxyConfigRemoved.observe(viewLifecycleOwner, { - Log.i("[Status Fragment] A proxy config was removed, update default proxy state") - val defaultProxy = coreContext.core.defaultProxyConfig - if (defaultProxy != null) { - viewModel.updateDefaultProxyConfigRegistrationStatus(defaultProxy.state) + sharedViewModel.accountRemoved.observe(viewLifecycleOwner, { + Log.i("[Status Fragment] An account was removed, update default account state") + val defaultAccount = coreContext.core.defaultAccount + if (defaultAccount != null) { + viewModel.updateDefaultAccountRegistrationStatus(defaultAccount.state) } }) diff --git a/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt b/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt index 9d600d8d7..6510d57c5 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/fragments/AccountSettingsFragment.kt @@ -56,9 +56,9 @@ class AccountSettingsFragment : GenericFragment( viewModel.linkPhoneNumberEvent.observe(viewLifecycleOwner, { it.consume { - val authInfo = viewModel.proxyConfig.findAuthInfo() + val authInfo = viewModel.account.findAuthInfo() if (authInfo == null) { - Log.e("[Account Settings] Failed to find auth info for proxy config ${viewModel.proxyConfig}") + Log.e("[Account Settings] Failed to find auth info for account ${viewModel.account}") } else { val args = Bundle() args.putString("Username", authInfo.username) @@ -69,9 +69,9 @@ class AccountSettingsFragment : GenericFragment( } }) - viewModel.proxyConfigRemovedEvent.observe(viewLifecycleOwner, { + viewModel.accountRemovedEvent.observe(viewLifecycleOwner, { it.consume { - sharedViewModel.proxyConfigRemoved.value = true + sharedViewModel.accountRemoved.value = true findNavController().navigateUp() } }) diff --git a/app/src/main/java/org/linphone/activities/main/settings/fragments/SettingsFragment.kt b/app/src/main/java/org/linphone/activities/main/settings/fragments/SettingsFragment.kt index 9bd0a3c6b..746245e91 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/fragments/SettingsFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/fragments/SettingsFragment.kt @@ -54,8 +54,8 @@ class SettingsFragment : SecureFragment() { binding.setBackClickListener { findNavController().popBackStack() } - sharedViewModel.proxyConfigRemoved.observe(viewLifecycleOwner, { - Log.i("[Settings] Proxy config removed, update accounts list") + sharedViewModel.accountRemoved.observe(viewLifecycleOwner, { + Log.i("[Settings] Account removed, update accounts list") viewModel.updateAccountsList() }) @@ -68,7 +68,7 @@ class SettingsFragment : SecureFragment() { viewModel.accountsSettingsListener = object : SettingListenerStub() { override fun onAccountClicked(identity: String) { - Log.i("[Settings] Navigation to settings for proxy with identity: $identity") + Log.i("[Settings] Navigation to settings for account with identity: $identity") navigateToAccountSettings(identity) } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt index 67274d4ef..0530fa5b4 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/AccountSettingsViewModel.kt @@ -38,16 +38,16 @@ class AccountSettingsViewModelFactory(private val identity: String) : @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - for (proxy in coreContext.core.proxyConfigList) { - if (proxy.identityAddress?.asStringUriOnly() == identity) { - return AccountSettingsViewModel(proxy) as T + for (account in coreContext.core.accountList) { + if (account.params.identityAddress?.asStringUriOnly() == identity) { + return AccountSettingsViewModel(account) as T } } - return AccountSettingsViewModel(coreContext.core.defaultProxyConfig!!) as T + return AccountSettingsViewModel(coreContext.core.defaultAccount!!) as T } } -class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsViewModel() { +class AccountSettingsViewModel(val account: Account) : GenericSettingsViewModel() { val isDefault = MutableLiveData() val displayName = MutableLiveData() @@ -61,25 +61,24 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi val waitForUnregister = MutableLiveData() - val proxyConfigRemovedEvent: MutableLiveData> by lazy { + val accountRemovedEvent: MutableLiveData> by lazy { MutableLiveData>() } val displayUsernameInsteadOfIdentity = corePreferences.replaceSipUriByUsername - private var proxyConfigToDelete: ProxyConfig? = null + private var accountToDelete: Account? = null - val listener: CoreListenerStub = object : CoreListenerStub() { + val listener: AccountListenerStub = object : AccountListenerStub() { override fun onRegistrationStateChanged( - core: Core, - cfg: ProxyConfig, + account: Account, state: RegistrationState, message: String ) { - if (state == RegistrationState.Cleared && cfg == proxyConfigToDelete) { - Log.i("[Account Settings] Proxy config to remove registration is now cleared") + if (state == RegistrationState.Cleared && account == accountToDelete) { + Log.i("[Account Settings] Account to remove registration is now cleared") waitForUnregister.value = false - deleteProxyConfig(cfg) + deleteAccount(account) } else { update() } @@ -90,44 +89,94 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi val userNameListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - // TODO + val params = account.params.clone() + val identity = params.identityAddress + if (identity != null) { + identity.username = newValue + params.identityAddress = identity + account.params = params + } else { + Log.e("[Account Settings] Account doesn't have an identity yet") + } } } val userName = MutableLiveData() val userIdListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - // TODO + val authInfo = account.findAuthInfo() + if (authInfo != null) { + authInfo.userid = newValue + } else { + Log.e("[Account Settings] Failed to find the matching auth info") + } } } val userId = MutableLiveData() val passwordListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - // TODO + val authInfo = account.findAuthInfo() + if (authInfo != null) { + authInfo.password = newValue + } else { + Log.w("[Account Settings] Failed to find the matching auth info") + val params = account.params + val identity = params.identityAddress + if (identity != null && identity.username != null) { + val newAuthInfo = Factory.instance() + .createAuthInfo(identity.username!!, userId.value, newValue, null, null, identity.domain) + core.addAuthInfo(newAuthInfo) + } else { + Log.e("[Account Settings] Failed to find the user's identity, can't create a new auth info") + } + } } } val password = MutableLiveData() val domainListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - // TODO + val params = account.params.clone() + val identity = params.identityAddress + if (identity != null) { + val authInfo = account.findAuthInfo() + if (authInfo != null) { + authInfo.domain = newValue + } else { + Log.e("[Account Settings] Failed to find the matching auth info") + } + + identity.domain = newValue + params.identityAddress = identity + account.params = params + } else { + Log.e("[Account Settings] Account doesn't have an identity yet") + } } } val domain = MutableLiveData() val displayNameListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - proxyConfig.identityAddress?.displayName = newValue + val params = account.params.clone() + val identity = params.identityAddress + if (identity != null) { + identity.displayName = newValue + params.identityAddress = identity + account.params = params + } else { + Log.e("[Account Settings] Account doesn't have an identity yet") + } } } // displayName mutable is above val disableListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { - proxyConfig.edit() - proxyConfig.enableRegister(!newValue) - proxyConfig.done() + val params = account.params.clone() + params.registerEnabled = !newValue + account.params = params } } val disable = MutableLiveData() @@ -135,14 +184,14 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi val isDefaultListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { if (newValue) { - core.defaultProxyConfig = proxyConfig + core.defaultAccount = account } } } // isDefault mutable is above - private fun deleteProxyConfig(cfg: ProxyConfig) { - val authInfo = cfg.findAuthInfo() + private fun deleteAccount(account: Account) { + val authInfo = account.findAuthInfo() if (authInfo != null) { Log.i("[Account Settings] Found auth info $authInfo, removing it.") core.removeAuthInfo(authInfo) @@ -150,42 +199,44 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi Log.w("[Account Settings] Couldn't find matching auth info...") } - core.removeProxyConfig(cfg) - proxyConfigRemovedEvent.value = Event(true) + core.removeAccount(account) + accountRemovedEvent.value = Event(true) } val deleteListener = object : SettingListenerStub() { override fun onClicked() { - proxyConfigToDelete = proxyConfig + accountToDelete = account - val registered = proxyConfig.state == RegistrationState.Ok + val registered = account.state == RegistrationState.Ok waitForUnregister.value = registered - if (core.defaultProxyConfig == proxyConfig) { - Log.i("[Account Settings] Proxy config was default, let's look for a replacement") - for (proxyConfigIterator in core.proxyConfigList) { - if (proxyConfig != proxyConfigIterator) { - core.defaultProxyConfig = proxyConfigIterator - Log.i("[Account Settings] New default proxy config is $proxyConfigIterator") + if (core.defaultAccount == account) { + Log.i("[Account Settings] Account was default, let's look for a replacement") + for (accountIterator in core.accountList) { + if (account != accountIterator) { + core.defaultAccount = accountIterator + Log.i("[Account Settings] New default account is $accountIterator") break } } } - proxyConfig.edit() - proxyConfig.enableRegister(false) - proxyConfig.done() + val params = account.params.clone() + params.registerEnabled = false + account.params = params if (!registered) { - Log.w("[Account Settings] Proxy config isn't registered, don't unregister before removing it") - deleteProxyConfig(proxyConfig) + Log.w("[Account Settings] Account isn't registered, don't unregister before removing it") + deleteAccount(account) } } } val pushNotificationListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { - proxyConfig.isPushNotificationAllowed = newValue + val params = account.params.clone() + params.pushNotificationAllowed = newValue + account.params = params } } val pushNotification = MutableLiveData() @@ -193,7 +244,10 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi val transportListener = object : SettingListenerStub() { override fun onListValueChanged(position: Int) { - // TODO + val params = account.params.clone() + params.transport = TransportType.fromInt(position) + account.params = params + proxy.value = account.params.serverAddr } } val transportIndex = MutableLiveData() @@ -201,40 +255,48 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi val proxyListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - proxyConfig.serverAddr = newValue - if (outboundProxy.value == true) { - // TODO - } + val params = account.params.clone() + params.serverAddr = newValue + account.params = params + transportIndex.value = account.params.transport.toInt() } } val proxy = MutableLiveData() val outboundProxyListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { - // TODO + val params = account.params.clone() + params.outboundProxyEnabled = newValue + account.params = params } } val outboundProxy = MutableLiveData() val stunServerListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - proxyConfig.natPolicy?.stunServer = newValue + val params = account.params.clone() + params.natPolicy?.stunServer = newValue if (newValue.isEmpty()) ice.value = false stunServer.value = newValue + account.params = params } } val stunServer = MutableLiveData() val iceListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { - proxyConfig.natPolicy?.enableIce(newValue) + val params = account.params.clone() + params.natPolicy?.enableIce(newValue) + account.params = params } } val ice = MutableLiveData() val avpfListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { - proxyConfig.avpfMode = if (newValue) AVPFMode.Enabled else AVPFMode.Disabled + val params = account.params.clone() + params.avpfMode = if (newValue) AVPFMode.Enabled else AVPFMode.Disabled + account.params = params } } val avpf = MutableLiveData() @@ -242,8 +304,11 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi val avpfRrIntervalListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { try { - proxyConfig.avpfRrInterval = newValue.toInt() + val params = account.params.clone() + params.avpfRrInterval = newValue.toInt() + account.params = params } catch (nfe: NumberFormatException) { + Log.e("[Account Settings] Failed to set AVPF RR interval ($newValue): $nfe") } } } @@ -252,23 +317,39 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi val expiresListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { try { - proxyConfig.expires = newValue.toInt() + val params = account.params.clone() + params.expires = newValue.toInt() + account.params = params } catch (nfe: NumberFormatException) { + Log.e("[Account Settings] Failed to set expires ($newValue): $nfe") } } } val expires = MutableLiveData() - val dialPrefixListener = object : SettingListenerStub() { + val prefixListener = object : SettingListenerStub() { override fun onTextValueChanged(newValue: String) { - proxyConfig.dialPrefix = newValue + val params = account.params.clone() + params.internationalPrefix = newValue + account.params = params } } - val dialPrefix = MutableLiveData() + val prefix = MutableLiveData() + + val dialPrefixListener = object : SettingListenerStub() { + override fun onBoolValueChanged(newValue: Boolean) { + val params = account.params.clone() + params.useInternationalPrefixForCallsAndChats = newValue + account.params = params + } + } + val dialPrefix = MutableLiveData() val escapePlusListener = object : SettingListenerStub() { override fun onBoolValueChanged(newValue: Boolean) { - proxyConfig.dialEscapePlus = newValue + val params = account.params.clone() + params.dialEscapePlusEnabled = newValue + account.params = params } } val escapePlus = MutableLiveData() @@ -282,61 +363,67 @@ class AccountSettingsViewModel(val proxyConfig: ProxyConfig) : GenericSettingsVi init { update() - core.addListener(listener) + account.addListener(listener) initTransportList() } override fun onCleared() { - core.removeListener(listener) + account.removeListener(listener) super.onCleared() } private fun update() { - isDefault.value = core.defaultProxyConfig == proxyConfig - val identityAddress = proxyConfig.identityAddress + isDefault.value = core.defaultAccount == account + val params = account.params + val identityAddress = params.identityAddress if (identityAddress != null) { displayName.value = identityAddress.displayName ?: "" identity.value = identityAddress.asStringUriOnly() } - iconResource.value = when (proxyConfig.state) { + iconResource.value = when (account.state) { RegistrationState.Ok -> R.drawable.led_registered RegistrationState.Failed -> R.drawable.led_error RegistrationState.Progress -> R.drawable.led_registration_in_progress else -> R.drawable.led_not_registered } - iconContentDescription.value = when (proxyConfig.state) { + iconContentDescription.value = when (account.state) { RegistrationState.Ok -> R.string.status_connected RegistrationState.Progress -> R.string.status_in_progress RegistrationState.Failed -> R.string.status_error else -> R.string.status_not_connected } - userName.value = proxyConfig.identityAddress?.username - userId.value = proxyConfig.findAuthInfo()?.userid - domain.value = proxyConfig.identityAddress?.domain - disable.value = !proxyConfig.registerEnabled() - pushNotification.value = proxyConfig.isPushNotificationAllowed + userName.value = params.identityAddress?.username + userId.value = account.findAuthInfo()?.userid + domain.value = params.identityAddress?.domain + disable.value = !params.registerEnabled + pushNotification.value = params.pushNotificationAllowed pushNotificationsAvailable.value = core.isPushNotificationAvailable - proxy.value = proxyConfig.serverAddr - outboundProxy.value = proxyConfig.serverAddr == proxyConfig.routes.firstOrNull() - stunServer.value = proxyConfig.natPolicy?.stunServer - ice.value = proxyConfig.natPolicy?.iceEnabled() - avpf.value = proxyConfig.avpfEnabled() - avpfRrInterval.value = proxyConfig.avpfRrInterval - expires.value = proxyConfig.expires - dialPrefix.value = proxyConfig.dialPrefix - escapePlus.value = proxyConfig.dialEscapePlus + proxy.value = params.serverAddr + outboundProxy.value = params.outboundProxyEnabled + stunServer.value = params.natPolicy?.stunServer + ice.value = params.natPolicy?.iceEnabled() + avpf.value = params.avpfMode == AVPFMode.Enabled + avpfRrInterval.value = params.avpfRrInterval + expires.value = params.expires + prefix.value = params.internationalPrefix + dialPrefix.value = params.useInternationalPrefixForCallsAndChats + escapePlus.value = params.dialEscapePlusEnabled } private fun initTransportList() { val labels = arrayListOf() + // Keep following in the same order as TransportType enum labels.add(prefs.getString(R.string.account_settings_transport_udp)) labels.add(prefs.getString(R.string.account_settings_transport_tcp)) labels.add(prefs.getString(R.string.account_settings_transport_tls)) + if (corePreferences.allowDtlsTransport) { + labels.add(prefs.getString(R.string.account_settings_transport_dtls)) + } transportLabels.value = labels - transportIndex.value = labels.indexOf(proxyConfig.transport.toUpperCase(Locale.getDefault())) + transportIndex.value = account.params.transport.toInt() } } diff --git a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt index 5ee45e404..1af8c8b06 100644 --- a/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/settings/viewmodels/SettingsViewModel.kt @@ -70,9 +70,9 @@ class SettingsViewModel : ViewModel() { fun updateAccountsList() { val list = arrayListOf() - if (coreContext.core.proxyConfigList.isNotEmpty()) { - for (proxy in coreContext.core.proxyConfigList) { - val viewModel = AccountSettingsViewModel(proxy) + if (coreContext.core.accountList.isNotEmpty()) { + for (account in coreContext.core.accountList) { + val viewModel = AccountSettingsViewModel(account) viewModel.accountsSettingsListener = accountClickListener list.add(viewModel) } diff --git a/app/src/main/java/org/linphone/activities/main/sidemenu/fragments/SideMenuFragment.kt b/app/src/main/java/org/linphone/activities/main/sidemenu/fragments/SideMenuFragment.kt index ebc4ce0a0..a5a99a182 100644 --- a/app/src/main/java/org/linphone/activities/main/sidemenu/fragments/SideMenuFragment.kt +++ b/app/src/main/java/org/linphone/activities/main/sidemenu/fragments/SideMenuFragment.kt @@ -67,8 +67,8 @@ class SideMenuFragment : GenericFragment() { ViewModelProvider(this).get(SharedMainViewModel::class.java) } - sharedViewModel.proxyConfigRemoved.observe(viewLifecycleOwner, { - Log.i("[Side Menu] Proxy config removed, update accounts list") + sharedViewModel.accountRemoved.observe(viewLifecycleOwner, { + Log.i("[Side Menu] Account removed, update accounts list") viewModel.updateAccountsList() }) @@ -76,7 +76,7 @@ class SideMenuFragment : GenericFragment() { override fun onAccountClicked(identity: String) { val args = Bundle() args.putString("Identity", identity) - Log.i("[Side Menu] Navigation to settings for proxy with identity: $identity") + Log.i("[Side Menu] Navigation to settings for account with identity: $identity") sharedViewModel.toggleDrawerEvent.value = Event(true) navigateToAccountSettings(identity) diff --git a/app/src/main/java/org/linphone/activities/main/sidemenu/viewmodels/SideMenuViewModel.kt b/app/src/main/java/org/linphone/activities/main/sidemenu/viewmodels/SideMenuViewModel.kt index 8c9a645fe..2703aab62 100644 --- a/app/src/main/java/org/linphone/activities/main/sidemenu/viewmodels/SideMenuViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/sidemenu/viewmodels/SideMenuViewModel.kt @@ -35,7 +35,7 @@ class SideMenuViewModel : ViewModel() { val showAbout: Boolean = corePreferences.showAboutInSideMenu val showQuit: Boolean = corePreferences.showQuitInSideMenu - val defaultAccount = MutableLiveData() + val defaultAccountViewModel = MutableLiveData() val defaultAccountFound = MutableLiveData() val defaultAccountAvatar = MutableLiveData() @@ -50,14 +50,14 @@ class SideMenuViewModel : ViewModel() { } private val listener: CoreListenerStub = object : CoreListenerStub() { - override fun onRegistrationStateChanged( + override fun onAccountRegistrationStateChanged( core: Core, - cfg: ProxyConfig, + account: Account, state: RegistrationState, message: String ) { - if (coreContext.core.proxyConfigList.size != accounts.value?.size) { - // Only refresh the list if a proxy has been added or removed + if (coreContext.core.accountList.size != accounts.value?.size) { + // Only refresh the list if an account has been added or removed updateAccountsList() } } @@ -77,18 +77,18 @@ class SideMenuViewModel : ViewModel() { fun updateAccountsList() { val list = arrayListOf() - if (coreContext.core.proxyConfigList.isNotEmpty()) { - val defaultProxyConfig = coreContext.core.defaultProxyConfig - if (defaultProxyConfig != null) { - val defaultViewModel = AccountSettingsViewModel(defaultProxyConfig) + if (coreContext.core.accountList.isNotEmpty()) { + val defaultAccount = coreContext.core.defaultAccount + if (defaultAccount != null) { + val defaultViewModel = AccountSettingsViewModel(defaultAccount) defaultViewModel.accountsSettingsListener = accountClickListener - defaultAccount.value = defaultViewModel + defaultAccountViewModel.value = defaultViewModel defaultAccountFound.value = true } - for (proxy in coreContext.core.proxyConfigList) { - if (proxy != coreContext.core.defaultProxyConfig) { - val viewModel = AccountSettingsViewModel(proxy) + for (account in coreContext.core.accountList) { + if (account != coreContext.core.defaultAccount) { + val viewModel = AccountSettingsViewModel(account) viewModel.accountsSettingsListener = accountClickListener list.add(viewModel) } diff --git a/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt b/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt index 82921b544..b5de92c5f 100644 --- a/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/viewmodels/SharedMainViewModel.kt @@ -58,7 +58,7 @@ class SharedMainViewModel : ViewModel() { /* Accounts */ - val proxyConfigRemoved = MutableLiveData() + val accountRemoved = MutableLiveData() /* Call */ diff --git a/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt b/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt index d72bb2263..e27f3b456 100644 --- a/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt +++ b/app/src/main/java/org/linphone/activities/main/viewmodels/StatusViewModel.kt @@ -35,13 +35,15 @@ open class StatusViewModel : ViewModel() { val voiceMailCount = MutableLiveData() private val listener: CoreListenerStub = object : CoreListenerStub() { - override fun onRegistrationStateChanged( + override fun onAccountRegistrationStateChanged( core: Core, - proxyConfig: ProxyConfig, + account: Account, state: RegistrationState, message: String ) { - updateDefaultProxyConfigRegistrationStatus(state) + if (account == core.defaultAccount) { + updateDefaultAccountRegistrationStatus(state) + } } override fun onNotifyReceived( @@ -71,11 +73,11 @@ open class StatusViewModel : ViewModel() { core.addListener(listener) var state: RegistrationState = RegistrationState.None - val defaultProxyConfig = core.defaultProxyConfig - if (defaultProxyConfig != null) { - state = defaultProxyConfig.state + val defaultAccount = core.defaultAccount + if (defaultAccount != null) { + state = defaultAccount.state } - updateDefaultProxyConfigRegistrationStatus(state) + updateDefaultAccountRegistrationStatus(state) } override fun onCleared() { @@ -87,7 +89,7 @@ open class StatusViewModel : ViewModel() { coreContext.core.refreshRegisters() } - fun updateDefaultProxyConfigRegistrationStatus(state: RegistrationState) { + fun updateDefaultAccountRegistrationStatus(state: RegistrationState) { registrationStatusText.value = getStatusIconText(state) registrationStatusDrawable.value = getStatusIconResource(state) } diff --git a/app/src/main/java/org/linphone/contact/ContactsManager.kt b/app/src/main/java/org/linphone/contact/ContactsManager.kt index 73d1a9585..3ad86e2ad 100644 --- a/app/src/main/java/org/linphone/contact/ContactsManager.kt +++ b/app/src/main/java/org/linphone/contact/ContactsManager.kt @@ -133,7 +133,7 @@ class ContactsManager(private val context: Context) { } fun shouldDisplaySipContactsList(): Boolean { - return coreContext.core.defaultProxyConfig?.identityAddress?.domain == corePreferences.defaultDomain + return coreContext.core.defaultAccount?.params?.identityAddress?.domain == corePreferences.defaultDomain } @Synchronized diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index 4a417bca4..8386cc359 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -312,15 +312,15 @@ class CoreContext(val context: Context, coreConfig: Config) { computeUserAgent() - for (lpc in core.proxyConfigList) { - if (lpc.identityAddress?.domain == corePreferences.defaultDomain) { + for (account in core.accountList) { + if (account.params.identityAddress?.domain == corePreferences.defaultDomain) { // Ensure conference URI is set on sip.linphone.org proxy configs - if (lpc.conferenceFactoryUri == null) { - lpc.edit() + if (account.params.conferenceFactoryUri == null) { + val params = account.params.clone() val uri = corePreferences.conferenceServerUri - Log.i("[Context] Setting conference factory on proxy config ${lpc.identityAddress?.asString()} to default value: $uri") - lpc.conferenceFactoryUri = uri - lpc.done() + Log.i("[Context] Setting conference factory on proxy config ${params.identityAddress?.asString()} to default value: $uri") + params.conferenceFactoryUri = uri + account.params = params } // Ensure LIME server URL is set if at least one sip.linphone.org proxy diff --git a/app/src/main/java/org/linphone/core/CorePreferences.kt b/app/src/main/java/org/linphone/core/CorePreferences.kt index 2c8d58dbc..241876986 100644 --- a/app/src/main/java/org/linphone/core/CorePreferences.kt +++ b/app/src/main/java/org/linphone/core/CorePreferences.kt @@ -391,6 +391,9 @@ class CorePreferences constructor(private val context: Context) { /* Settings */ + val allowDtlsTransport: Boolean + get() = config.getBool("app", "allow_dtls_transport", false) + val showAccountSettings: Boolean get() = config.getBool("app", "settings_accounts", true) diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt index 04d114499..13dcf7f48 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.kt +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.kt @@ -56,17 +56,17 @@ class LinphoneUtils { val core = coreContext.core return core.limeX3DhAvailable() && core.limeX3DhEnabled() && core.limeX3DhServerUrl != null && - core.defaultProxyConfig?.conferenceFactoryUri != null + core.defaultAccount?.params?.conferenceFactoryUri != null } fun isGroupChatAvailable(): Boolean { val core = coreContext.core - return core.defaultProxyConfig?.conferenceFactoryUri != null + return core.defaultAccount?.params?.conferenceFactoryUri != null } fun createOneToOneChatRoom(participant: Address, isSecured: Boolean = false): ChatRoom? { val core: Core = coreContext.core - val defaultProxyConfig = core.defaultProxyConfig + val defaultAccount = core.defaultAccount val params = core.createDefaultChatRoomParams() params.enableGroup(false) @@ -79,8 +79,8 @@ class LinphoneUtils { val participants = arrayOf(participant) - return core.searchChatRoom(params, defaultProxyConfig?.contact, null, participants) - ?: core.createChatRoom(params, defaultProxyConfig?.contact, participants) + return core.searchChatRoom(params, defaultAccount?.contactAddress, null, participants) + ?: core.createChatRoom(params, defaultAccount?.contactAddress, participants) } fun deleteFilesAttachedToEventLog(eventLog: EventLog) { diff --git a/app/src/main/res/layout/settings_account_fragment.xml b/app/src/main/res/layout/settings_account_fragment.xml index 384254f6b..24a1c2e47 100644 --- a/app/src/main/res/layout/settings_account_fragment.xml +++ b/app/src/main/res/layout/settings_account_fragment.xml @@ -88,7 +88,7 @@ linphone:subtitle="@{@string/account_settings_password_summary}" linphone:listener="@{viewModel.passwordListener}" linphone:defaultValue="@{viewModel.password}" - linphone:inputType="@{InputType.TYPE_TEXT_VARIATION_PASSWORD}"/> + linphone:inputType="@{InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD}"/> + + @@ -100,8 +100,8 @@ Transporte TCP TLS + DTLS Proxy SIP Enruta todas las llamadas a través del proxy SIP de arriba Servidor STUN / TURN @@ -549,8 +550,8 @@ AVPF de intervalo regular de RTCP Caduce en segundos - Prefijo de tu país - sin el + + Prefijo de tu país + sin el + Reemplazar + por 00 &appName; notificaciones de llamadas entrantes &appName; notificaciones de mensajes diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index dcbd81ab0..72d6da939 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -389,6 +389,7 @@ UDP TCP TLS + DTLS Proxy SIP Outbound proxy Serveur TURN / STUN @@ -397,8 +398,8 @@ en secondes (entre 1 et 5) Expiration en secondes - (sans le +) - Préfixe de votre pays + (sans le +) + Préfixe de votre pays Remplacer + par 00 Notifications d\'appels entrants &appName; Appel entrant diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 0c56e7f6e..7ff36cd9a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -160,8 +160,8 @@ 以秒为单位(1到5之间) 到期 以秒为单位 - 您所在国家的前缀 - 不包含 + + 您所在国家的前缀 + 不包含 + 用00代替+ &appName; 服务通知 &appName; 即时通讯通知 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index cedd37927..cb586c84f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -421,8 +421,8 @@ 以秒為單位(1到5之間) 到期 以秒為單位 - 您所在國家的前綴 - 不包含+ + 您所在國家的前綴 + 不包含+ 用00代替+ &appName;來電通知 &appName;即時通訊通知 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1a554b761..a36d43ba0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -528,6 +528,7 @@ UDP TCP TLS + DTLS SIP proxy Outbound proxy @@ -542,8 +543,10 @@ in seconds (between 1 and 5) Expire in seconds - Prefix for your country - without the + + Prefix for your country + without the + + Apply prefix for outgoing calls and chat + If a number is entered, apply prefix to number Replace + by 00