From 5a7872222d93514c2a1cfefa0c5eda37ce6a639f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 29 Aug 2024 13:43:46 +0200 Subject: [PATCH] Added advanced account setting to manually update password --- .../java/org/linphone/ui/main/MainActivity.kt | 2 +- .../chat/fragment/ConversationInfoFragment.kt | 2 +- .../fragment/StartConversationFragment.kt | 2 +- .../history/fragment/StartCallFragment.kt | 2 +- .../AuthRequestedDialogModel.kt | 2 +- .../GroupSetOrEditSubjectDialogModel.kt | 2 +- .../fragment/AccountSettingsFragment.kt | 26 ++++ .../model/UpdatePasswordDialogModel.kt | 54 +++++++ .../viewmodel/AccountSettingsViewModel.kt | 23 +++ .../java/org/linphone/utils/DialogUtils.kt | 23 ++- .../res/layout/account_advanced_settings.xml | 30 +++- .../res/layout/account_settings_fragment.xml | 8 +- .../dialog_set_or_edit_group_subject.xml | 2 +- .../layout/dialog_update_account_password.xml | 24 +-- ...ccount_password_after_register_failure.xml | 143 ++++++++++++++++++ app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 17 files changed, 315 insertions(+), 32 deletions(-) rename app/src/main/java/org/linphone/ui/main/{fragment => model}/AuthRequestedDialogModel.kt (97%) rename app/src/main/java/org/linphone/ui/main/{fragment => model}/GroupSetOrEditSubjectDialogModel.kt (97%) create mode 100644 app/src/main/java/org/linphone/ui/main/settings/model/UpdatePasswordDialogModel.kt create mode 100644 app/src/main/res/layout/dialog_update_account_password_after_register_failure.xml diff --git a/app/src/main/java/org/linphone/ui/main/MainActivity.kt b/app/src/main/java/org/linphone/ui/main/MainActivity.kt index caddad140..75b84bb81 100644 --- a/app/src/main/java/org/linphone/ui/main/MainActivity.kt +++ b/app/src/main/java/org/linphone/ui/main/MainActivity.kt @@ -63,8 +63,8 @@ import org.linphone.databinding.MainActivityBinding import org.linphone.ui.GenericActivity import org.linphone.ui.assistant.AssistantActivity import org.linphone.ui.main.chat.fragment.ConversationsListFragmentDirections -import org.linphone.ui.main.fragment.AuthRequestedDialogModel import org.linphone.ui.main.help.fragment.DebugFragmentDirections +import org.linphone.ui.main.model.AuthRequestedDialogModel import org.linphone.ui.main.sso.fragment.SingleSignOnFragmentDirections import org.linphone.ui.main.viewmodel.MainViewModel import org.linphone.ui.main.viewmodel.SharedMainViewModel diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt index 1e3013d5e..41dc57346 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/ConversationInfoFragment.kt @@ -43,9 +43,9 @@ import org.linphone.ui.GenericActivity import org.linphone.ui.main.chat.adapter.ConversationParticipantsAdapter import org.linphone.ui.main.chat.model.ParticipantModel import org.linphone.ui.main.chat.viewmodel.ConversationInfoViewModel -import org.linphone.ui.main.fragment.GroupSetOrEditSubjectDialogModel import org.linphone.ui.main.fragment.SlidingPaneChildFragment import org.linphone.ui.main.history.model.ConfirmationDialogModel +import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel import org.linphone.utils.DialogUtils import org.linphone.utils.Event diff --git a/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt b/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt index 2745f8977..3c942984a 100644 --- a/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/chat/fragment/StartConversationFragment.kt @@ -35,7 +35,7 @@ import org.linphone.databinding.StartChatFragmentBinding import org.linphone.ui.GenericActivity import org.linphone.ui.main.chat.viewmodel.StartConversationViewModel import org.linphone.ui.main.fragment.GenericAddressPickerFragment -import org.linphone.ui.main.fragment.GroupSetOrEditSubjectDialogModel +import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel import org.linphone.utils.DialogUtils import org.linphone.utils.Event import org.linphone.utils.hideKeyboard diff --git a/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt b/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt index 2df7e1188..62344ec93 100644 --- a/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/history/fragment/StartCallFragment.kt @@ -38,8 +38,8 @@ import org.linphone.core.tools.Log import org.linphone.databinding.StartCallFragmentBinding import org.linphone.ui.GenericActivity import org.linphone.ui.main.fragment.GenericAddressPickerFragment -import org.linphone.ui.main.fragment.GroupSetOrEditSubjectDialogModel import org.linphone.ui.main.history.viewmodel.StartCallViewModel +import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel import org.linphone.utils.DialogUtils import org.linphone.utils.Event import org.linphone.utils.addCharacterAtPosition diff --git a/app/src/main/java/org/linphone/ui/main/fragment/AuthRequestedDialogModel.kt b/app/src/main/java/org/linphone/ui/main/model/AuthRequestedDialogModel.kt similarity index 97% rename from app/src/main/java/org/linphone/ui/main/fragment/AuthRequestedDialogModel.kt rename to app/src/main/java/org/linphone/ui/main/model/AuthRequestedDialogModel.kt index e7b355890..d2be0f9c7 100644 --- a/app/src/main/java/org/linphone/ui/main/fragment/AuthRequestedDialogModel.kt +++ b/app/src/main/java/org/linphone/ui/main/model/AuthRequestedDialogModel.kt @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.ui.main.fragment +package org.linphone.ui.main.model import androidx.annotation.UiThread import androidx.lifecycle.MutableLiveData diff --git a/app/src/main/java/org/linphone/ui/main/fragment/GroupSetOrEditSubjectDialogModel.kt b/app/src/main/java/org/linphone/ui/main/model/GroupSetOrEditSubjectDialogModel.kt similarity index 97% rename from app/src/main/java/org/linphone/ui/main/fragment/GroupSetOrEditSubjectDialogModel.kt rename to app/src/main/java/org/linphone/ui/main/model/GroupSetOrEditSubjectDialogModel.kt index 7a36c7063..055eeafc2 100644 --- a/app/src/main/java/org/linphone/ui/main/fragment/GroupSetOrEditSubjectDialogModel.kt +++ b/app/src/main/java/org/linphone/ui/main/model/GroupSetOrEditSubjectDialogModel.kt @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.linphone.ui.main.fragment +package org.linphone.ui.main.model import androidx.annotation.UiThread import androidx.lifecycle.MediatorLiveData diff --git a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt index 104a1e367..d17daf5b7 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/fragment/AccountSettingsFragment.kt @@ -37,7 +37,9 @@ import org.linphone.core.tools.Log import org.linphone.databinding.AccountSettingsFragmentBinding import org.linphone.ui.GenericActivity import org.linphone.ui.main.fragment.GenericMainFragment +import org.linphone.ui.main.settings.model.UpdatePasswordDialogModel import org.linphone.ui.main.settings.viewmodel.AccountSettingsViewModel +import org.linphone.utils.DialogUtils import org.linphone.utils.Event @UiThread @@ -99,6 +101,10 @@ class AccountSettingsFragment : GenericMainFragment() { goBack() } + binding.setUpdatePasswordClickListener { + showUpdatePasswordDialog() + } + viewModel.accountFoundEvent.observe(viewLifecycleOwner) { it.consume { found -> if (found) { @@ -140,4 +146,24 @@ class AccountSettingsFragment : GenericMainFragment() { // It is possible some value have changed, causing some menu to appear or disappear sharedViewModel.forceUpdateAvailableNavigationItems.value = Event(true) } + + private fun showUpdatePasswordDialog() { + val model = UpdatePasswordDialogModel() + val dialog = DialogUtils.getUpdatePasswordDialog(requireContext(), model) + + model.dismissEvent.observe(viewLifecycleOwner) { + it.consume { + dialog.dismiss() + } + } + + model.confirmEvent.observe(viewLifecycleOwner) { + it.consume { password -> + viewModel.updateAccountPassword(password) + dialog.dismiss() + } + } + + dialog.show() + } } diff --git a/app/src/main/java/org/linphone/ui/main/settings/model/UpdatePasswordDialogModel.kt b/app/src/main/java/org/linphone/ui/main/settings/model/UpdatePasswordDialogModel.kt new file mode 100644 index 000000000..74219d4e0 --- /dev/null +++ b/app/src/main/java/org/linphone/ui/main/settings/model/UpdatePasswordDialogModel.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010-2024 Belledonne Communications SARL. + * + * This file is part of linphone-android + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.linphone.ui.main.settings.model + +import androidx.annotation.UiThread +import androidx.lifecycle.MutableLiveData +import org.linphone.utils.Event + +@UiThread +class UpdatePasswordDialogModel { + val password = MutableLiveData() + + val showPassword = MutableLiveData() + + val dismissEvent = MutableLiveData>() + + val confirmEvent = MutableLiveData>() + + init { + showPassword.value = false + } + + @UiThread + fun toggleShowPassword() { + showPassword.value = showPassword.value == false + } + + @UiThread + fun dismiss() { + dismissEvent.value = Event(true) + } + + @UiThread + fun confirm() { + confirmEvent.value = Event(password.value.orEmpty()) + } +} diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt index 0ac4cb8bb..f6cda6447 100644 --- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt +++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountSettingsViewModel.kt @@ -77,6 +77,8 @@ class AccountSettingsViewModel @UiThread constructor() : GenericViewModel() { val accountFoundEvent = MutableLiveData>() + val showUpdatePasswordDialog = MutableLiveData>() + private lateinit var account: Account private lateinit var natPolicy: NatPolicy @@ -242,4 +244,25 @@ class AccountSettingsViewModel @UiThread constructor() : GenericViewModel() { fun toggleAdvancedSettingsExpand() { expandAdvancedSettings.value = expandAdvancedSettings.value == false } + + @UiThread + fun updateAccountPassword(newPassword: String) { + coreContext.postOnCoreThread { core -> + if (::account.isInitialized) { + val authInfo = account.findAuthInfo() + if (authInfo != null) { + Log.i( + "$TAG Updating password for username [${authInfo.username}] using auth info [$authInfo]" + ) + authInfo.password = newPassword + core.addAuthInfo(authInfo) + core.refreshRegisters() + } else { + Log.w( + "$TAG Failed to find auth info for account [${account.params.identityAddress?.asStringUriOnly()}]" + ) + } + } + } + } } diff --git a/app/src/main/java/org/linphone/utils/DialogUtils.kt b/app/src/main/java/org/linphone/utils/DialogUtils.kt index 8c3db92d6..17c0cc7e5 100644 --- a/app/src/main/java/org/linphone/utils/DialogUtils.kt +++ b/app/src/main/java/org/linphone/utils/DialogUtils.kt @@ -50,6 +50,7 @@ import org.linphone.databinding.DialogRemoveAllCallLogsBinding import org.linphone.databinding.DialogRemoveCallLogsBinding import org.linphone.databinding.DialogRemoveConversationHistoryBinding import org.linphone.databinding.DialogSetOrEditGroupSubjectBindingImpl +import org.linphone.databinding.DialogUpdateAccountPasswordAfterRegisterFailureBinding import org.linphone.databinding.DialogUpdateAccountPasswordBinding import org.linphone.databinding.DialogUpdateAvailableBinding import org.linphone.databinding.DialogZrtpSasValidationBinding @@ -61,9 +62,10 @@ import org.linphone.ui.call.model.ZrtpSasConfirmationDialogModel import org.linphone.ui.main.contacts.model.ContactTrustDialogModel import org.linphone.ui.main.contacts.model.NumberOrAddressPickerDialogModel import org.linphone.ui.main.contacts.model.TrustCallDialogModel -import org.linphone.ui.main.fragment.AuthRequestedDialogModel -import org.linphone.ui.main.fragment.GroupSetOrEditSubjectDialogModel import org.linphone.ui.main.history.model.ConfirmationDialogModel +import org.linphone.ui.main.model.AuthRequestedDialogModel +import org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel +import org.linphone.ui.main.settings.model.UpdatePasswordDialogModel class DialogUtils { companion object { @@ -335,6 +337,23 @@ class DialogUtils { fun getAuthRequestedDialog( context: Context, viewModel: AuthRequestedDialogModel + ): Dialog { + val binding: DialogUpdateAccountPasswordAfterRegisterFailureBinding = DataBindingUtil.inflate( + LayoutInflater.from(context), + R.layout.dialog_update_account_password_after_register_failure, + null, + false + ) + binding.viewModel = viewModel + binding.lifecycleOwner = context as LifecycleOwner + + return getDialog(context, binding) + } + + @UiThread + fun getUpdatePasswordDialog( + context: Context, + viewModel: UpdatePasswordDialogModel ): Dialog { val binding: DialogUpdateAccountPasswordBinding = DataBindingUtil.inflate( LayoutInflater.from(context), diff --git a/app/src/main/res/layout/account_advanced_settings.xml b/app/src/main/res/layout/account_advanced_settings.xml index bfb8e0e7d..fb08a6e7b 100644 --- a/app/src/main/res/layout/account_advanced_settings.xml +++ b/app/src/main/res/layout/account_advanced_settings.xml @@ -5,6 +5,9 @@ + @@ -371,7 +374,6 @@ android:layout_height="50dp" android:layout_marginEnd="16dp" android:layout_marginStart="16dp" - android:layout_marginBottom="@dimen/screen_bottom_margin" android:background="@drawable/edit_text_background" android:paddingStart="20dp" android:paddingEnd="20dp" @@ -382,6 +384,32 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/lime_server_title" + app:layout_constraintBottom_toTopOf="@id/update_password"/> + + diff --git a/app/src/main/res/layout/account_settings_fragment.xml b/app/src/main/res/layout/account_settings_fragment.xml index 95555bb77..ad60cf754 100644 --- a/app/src/main/res/layout/account_settings_fragment.xml +++ b/app/src/main/res/layout/account_settings_fragment.xml @@ -8,6 +8,9 @@ + @@ -157,8 +160,8 @@ android:hint="@string/account_settings_mwi_uri_title" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@id/mwi_uri_title"/> + app:layout_constraintTop_toBottomOf="@id/mwi_uri_title" + app:layout_constraintBottom_toBottomOf="parent"/> @@ -186,6 +189,7 @@ android:layout_marginBottom="@dimen/screen_bottom_margin" android:visibility="@{viewModel.expandAdvancedSettings ? View.VISIBLE : View.GONE}" layout="@layout/account_advanced_settings" + bind:updatePasswordClickListener="@{updatePasswordClickListener}" bind:viewModel="@{viewModel}"/> diff --git a/app/src/main/res/layout/dialog_set_or_edit_group_subject.xml b/app/src/main/res/layout/dialog_set_or_edit_group_subject.xml index 4ad2a5764..01083d6e8 100644 --- a/app/src/main/res/layout/dialog_set_or_edit_group_subject.xml +++ b/app/src/main/res/layout/dialog_set_or_edit_group_subject.xml @@ -7,7 +7,7 @@ + type="org.linphone.ui.main.model.GroupSetOrEditSubjectDialogModel" /> + type="org.linphone.ui.main.settings.model.UpdatePasswordDialogModel" /> - - + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toBottomOf="@id/title"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b7f9d0bc0..28f83abd1 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -295,6 +295,7 @@ Mode "bundle" Utiliser CPIM dans les conversations \"basiques\" URI du serveur de messagerie vocale + Mettre à jour le mot de passe Autentification requise La connexion a échoué pour le compte \n%s.\n\nVous pouvez renseigner votre mot de passe à nouveau ou bien vérifier les options de configuration de votre compte. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 44e18cb51..f60d307b5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -332,6 +332,7 @@ Bundle mode Use CPIM in \"basic\" conversations Voicemail URI + Update password Authentication needed Connection failed because authentication is missing or invalid for account \n%s.\n\nYou can provide password again, or check your account configuration in the settings.