Removed secureMode/interopMode related code for now, will do it again the day it will be available in SDK + minor improvements

This commit is contained in:
Sylvain Berfini 2024-06-04 11:19:29 +02:00
parent cfe7a8ed38
commit 88c230f136
26 changed files with 40 additions and 165 deletions

View file

@ -57,7 +57,7 @@ class ContactLoader : LoaderManager.LoaderCallbacks<Cursor> {
private const val MIN_INTERVAL_TO_WAIT_BEFORE_REFRESH = 300000L // 5 minutes
}
val friends = HashMap<String, Friend>()
private val friends = HashMap<String, Friend>()
@MainThread
override fun onCreateLoader(id: Int, args: Bundle?): Loader<Cursor> {

View file

@ -749,7 +749,7 @@ fun Friend.getListOfSipAddressesAndPhoneNumbers(listener: ContactNumberOrAddress
// phone numbers are disabled is secure mode unless linked to a SIP address
val defaultAccount = LinphoneUtils.getDefaultAccount()
val enablePhoneNumbers = hasPresenceInfo || defaultAccount?.isEndToEndEncryptionMandatory() == false
val enablePhoneNumbers = hasPresenceInfo || isEndToEndEncryptionMandatory() == false
val address = presenceAddress ?: core.interpretUrl(
number.phoneNumber,
LinphoneUtils.applyInternationalPrefix(defaultAccount)

View file

@ -35,8 +35,6 @@ import org.linphone.core.Reason
import org.linphone.core.RegistrationState
import org.linphone.core.tools.Log
import org.linphone.ui.GenericViewModel
import org.linphone.ui.main.model.setEndToEndEncryptionMandatory
import org.linphone.ui.main.model.setInteroperabilityMode
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
@ -67,8 +65,6 @@ open class AccountLoginViewModel @UiThread constructor() : GenericViewModel() {
val registrationInProgress = MutableLiveData<Boolean>()
val isCurrentlySelectedModeSecure = MutableLiveData<Boolean>()
val accountLoggedInEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
@ -144,8 +140,6 @@ open class AccountLoginViewModel @UiThread constructor() : GenericViewModel() {
loginEnabled.addSource(password) {
loginEnabled.value = isLoginButtonEnabled()
}
isCurrentlySelectedModeSecure.value = true
}
@UiThread
@ -246,37 +240,6 @@ open class AccountLoginViewModel @UiThread constructor() : GenericViewModel() {
showPassword.value = showPassword.value == false
}
@UiThread
fun switchToSecureMode() {
isCurrentlySelectedModeSecure.value = true
}
@UiThread
fun switchToInteropMode() {
isCurrentlySelectedModeSecure.value = false
}
@UiThread
fun applySelectedMode() {
coreContext.postOnCoreThread { core ->
if (::newlyCreatedAccount.isInitialized) {
if (isCurrentlySelectedModeSecure.value == true) {
Log.i(
"$TAG Selected mode is end-to-end encrypted, forcing media & im encryption to mandatory and setting media encryption to ZRTP"
)
newlyCreatedAccount.setEndToEndEncryptionMandatory()
} else {
Log.i(
"$TAG Selected mode is interoperable, not forcing media & im encryption to mandatory and setting media encryption to SRTP"
)
newlyCreatedAccount.setInteroperabilityMode()
}
} else {
Log.e("$TAG Failed to find newlyCreatedAccount!")
}
}
}
@UiThread
private fun isLoginButtonEnabled(): Boolean {
return sipIdentity.value.orEmpty().trim().isNotEmpty() && password.value.orEmpty().isNotEmpty()

View file

@ -225,7 +225,7 @@ abstract class AbstractNewTransferCallFragment : GenericCallFragment() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
val enablePhoneNumbers = core.defaultAccount?.isEndToEndEncryptionMandatory() != true
val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(

View file

@ -803,13 +803,13 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
val sameDomain =
remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
if (account.isEndToEndEncryptionMandatory() && sameDomain) {
if (isEndToEndEncryptionMandatory() && sameDomain) {
Log.i(
"$TAG Account is in secure mode & domain matches, creating a E2E conversation"
)
params.backend = ChatRoom.Backend.FlexisipChat
params.isEncryptionEnabled = true
} else if (!account.isEndToEndEncryptionMandatory()) {
} else if (!isEndToEndEncryptionMandatory()) {
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
Log.i(
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"

View file

@ -199,7 +199,7 @@ class ConversationEventAdapter :
model = message
executePendingBindings()
binding.root.doOnPreDraw {
root.doOnPreDraw {
binding.deliveryStatus.startAnimatedDrawable()
}
}
@ -214,7 +214,7 @@ class ConversationEventAdapter :
model = message
executePendingBindings()
binding.root.doOnPreDraw {
root.doOnPreDraw {
binding.deliveryStatus.startAnimatedDrawable()
}
}

View file

@ -133,7 +133,7 @@ class ConversationFragment : SlidingPaneChildFragment() {
maxItems = SendMessageInConversationViewModel.MAX_FILES_TO_ATTACH
)
) { list ->
if (!list.isNullOrEmpty()) {
if (list.isNotEmpty()) {
for (uri in list) {
lifecycleScope.launch {
withContext(Dispatchers.IO) {

View file

@ -101,7 +101,7 @@ class MessageModel @WorkerThread constructor(
val time = TimestampUtils.toString(timestamp)
val chatRoomIsReadOnly = chatMessage.chatRoom.isReadOnly ||
(!chatMessage.chatRoom.hasCapability(ChatRoom.Capabilities.Encrypted.toInt()) && LinphoneUtils.getDefaultAccount()?.isEndToEndEncryptionMandatory() == true)
(!chatMessage.chatRoom.hasCapability(ChatRoom.Capabilities.Encrypted.toInt()) && isEndToEndEncryptionMandatory() == true)
val groupedWithNextMessage = MutableLiveData<Boolean>()

View file

@ -498,8 +498,7 @@ class ConversationViewModel @UiThread constructor() : AbstractConversationViewMo
@WorkerThread
fun checkIfConversationShouldBeDisabledForSecurityReasons() {
if (!chatRoom.hasCapability(ChatRoom.Capabilities.Encrypted.toInt())) {
val account = LinphoneUtils.getDefaultAccount()
if (account?.isEndToEndEncryptionMandatory() == true) {
if (isEndToEndEncryptionMandatory() == true) {
Log.w(
"$TAG Conversation with subject [${chatRoom.subject}] has been disabled because it isn't encrypted and default account is in secure mode"
)

View file

@ -193,11 +193,11 @@ class StartConversationViewModel @UiThread constructor() : AddressSelectionViewM
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
val sameDomain = remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
if (account.isEndToEndEncryptionMandatory() && sameDomain) {
if (isEndToEndEncryptionMandatory() && sameDomain) {
Log.i("$TAG Account is in secure mode & domain matches, creating a E2E conversation")
params.backend = ChatRoom.Backend.FlexisipChat
params.isEncryptionEnabled = true
} else if (!account.isEndToEndEncryptionMandatory()) {
} else if (!isEndToEndEncryptionMandatory()) {
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
Log.i(
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"

View file

@ -250,7 +250,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
)
// Only expand contacts' devices & trust by default if in E2E encrypted mode
expandDevicesTrust.postValue(
LinphoneUtils.getDefaultAccount()?.isEndToEndEncryptionMandatory() == true
isEndToEndEncryptionMandatory() == true
)
coreContext.contactsManager.addListener(contactsListener)
}
@ -427,7 +427,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
val enablePhoneNumbers = core.defaultAccount?.isEndToEndEncryptionMandatory() != true
val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(
@ -464,7 +464,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
val enablePhoneNumbers = core.defaultAccount?.isEndToEndEncryptionMandatory() != true
val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(
@ -501,7 +501,7 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
val enablePhoneNumbers = core.defaultAccount?.isEndToEndEncryptionMandatory() != true
val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
Log.i(
@ -547,13 +547,13 @@ class ContactViewModel @UiThread constructor() : GenericViewModel() {
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
val sameDomain = remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
if (account.isEndToEndEncryptionMandatory() && sameDomain) {
if (isEndToEndEncryptionMandatory() && sameDomain) {
Log.i(
"$TAG Account is in secure mode & domain matches, creating a E2E conversation"
)
params.backend = ChatRoom.Backend.FlexisipChat
params.isEncryptionEnabled = true
} else if (!account.isEndToEndEncryptionMandatory()) {
} else if (!isEndToEndEncryptionMandatory()) {
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
Log.i(
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"

View file

@ -161,10 +161,9 @@ class ContactsListViewModel @UiThread constructor() : AbstractMainViewModel() {
@WorkerThread
private fun updateDomainFilter() {
val defaultAccount = coreContext.core.defaultAccount
isDefaultAccountLinphone.postValue(
defaultAccount?.isEndToEndEncryptionMandatory() == true && defaultAccount.params.domain == corePreferences.defaultDomain
)
domainFilter = if (defaultAccount?.isEndToEndEncryptionMandatory() == true) {
val defaultDomain = defaultAccount?.params?.domain == corePreferences.defaultDomain
isDefaultAccountLinphone.postValue(defaultDomain)
domainFilter = if (isEndToEndEncryptionMandatory() == true) {
corePreferences.defaultDomain
} else {
"*"

View file

@ -150,8 +150,8 @@ class DrawerMenuFragment : GenericMainFragment() {
val popupWindow = PopupWindow(
popupView.root,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT,
true
)

View file

@ -162,7 +162,7 @@ abstract class GenericAddressPickerFragment : GenericMainFragment() {
val numbersCount = friend.phoneNumbers.size
// Do not consider phone numbers if default account is in secure mode
val enablePhoneNumbers = core.defaultAccount?.isEndToEndEncryptionMandatory() != true
val enablePhoneNumbers = isEndToEndEncryptionMandatory() != true
if (addressesCount == 1 && (numbersCount == 0 || !enablePhoneNumbers)) {
val address = friend.addresses.first()

View file

@ -189,13 +189,13 @@ class HistoryViewModel @UiThread constructor() : GenericViewModel() {
params.ephemeralLifetime = 0 // Make sure ephemeral is disabled by default
val sameDomain = remote.domain == corePreferences.defaultDomain && remote.domain == account.params.domain
if (account.isEndToEndEncryptionMandatory() && sameDomain) {
if (isEndToEndEncryptionMandatory() && sameDomain) {
Log.i(
"$TAG Account is in secure mode & domain matches, creating a E2E conversation"
)
params.backend = ChatRoom.Backend.FlexisipChat
params.isEncryptionEnabled = true
} else if (!account.isEndToEndEncryptionMandatory()) {
} else if (!isEndToEndEncryptionMandatory()) {
if (LinphoneUtils.isEndToEndEncryptedChatAvailable(core)) {
Log.i(
"$TAG Account is in interop mode but LIME is available, creating a E2E conversation"

View file

@ -24,7 +24,6 @@ import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.contacts.AbstractAvatarModel
import org.linphone.core.Account
@ -170,7 +169,7 @@ class AccountModel @WorkerThread constructor(
)
trust.postValue(SecurityLevel.EndToEndEncryptedAndVerified)
showTrust.postValue(account.isEndToEndEncryptionMandatory())
showTrust.postValue(isEndToEndEncryptionMandatory())
val name = LinphoneUtils.getDisplayName(account.params.identityAddress)
displayName.postValue(name)
@ -240,36 +239,6 @@ class AccountModel @WorkerThread constructor(
}
@WorkerThread
fun Account.isEndToEndEncryptionMandatory(): Boolean {
val defaultDomain = params.identityAddress?.domain == corePreferences.defaultDomain
val encryption = params.instantMessagingEncryptionMandatory
return defaultDomain && encryption
}
@WorkerThread
fun Account.setEndToEndEncryptionMandatory() {
val clone = params.clone()
clone.instantMessagingEncryptionMandatory = true
params = clone
if (this == core.defaultAccount) {
coreContext.contactsManager.updateContactsModelDependingOnDefaultAccountMode()
}
Log.i(
"[Account] End-to-end encryption is now mandatory on account [${params.identityAddress?.asStringUriOnly()}]"
)
}
@WorkerThread
fun Account.setInteroperabilityMode() {
val clone = params.clone()
clone.instantMessagingEncryptionMandatory = false
params = clone
if (this == core.defaultAccount) {
coreContext.contactsManager.updateContactsModelDependingOnDefaultAccountMode()
}
Log.i(
"[Account] End-to-end encryption is no longer mandatory on account [${params.identityAddress?.asStringUriOnly()}]"
)
fun isEndToEndEncryptionMandatory(): Boolean {
return false // TODO: Will be done later in SDK
}

View file

@ -47,7 +47,7 @@ class RecordingMediaPlayerViewModel @UiThread constructor() : GenericViewModel()
lateinit var recordingModel: RecordingModel
lateinit var player: Player
private lateinit var player: Player
val isVideo = MutableLiveData<Boolean>()
@ -217,7 +217,7 @@ class RecordingMediaPlayerViewModel @UiThread constructor() : GenericViewModel()
if (!::player.isInitialized) return
Log.i("$TAG Stopping player")
pause()
pausePlayback()
position.postValue(0)
player.seek(0)
player.close()

View file

@ -30,7 +30,6 @@ import org.linphone.core.tools.Log
import org.linphone.databinding.AccountProfileSecureModeFragmentBinding
import org.linphone.ui.main.fragment.GenericMainFragment
import org.linphone.ui.main.settings.viewmodel.AccountProfileViewModel
import org.linphone.utils.DialogUtils
@UiThread
class AccountProfileModeFragment : GenericMainFragment() {
@ -64,21 +63,5 @@ class AccountProfileModeFragment : GenericMainFragment() {
Log.i("$TAG Leaving without saving changes...")
goBack()
}
binding.setContinueClickListener {
Log.i("$TAG Applying changes and leaving...")
viewModel.applySelectedMode()
goBack()
}
binding.setDefaultModeTooltipClickListener {
val dialog = DialogUtils.getAccountModeExplanationDialog(requireActivity(), true)
dialog.show()
}
binding.setInteropModeTooltipClickListener {
val dialog = DialogUtils.getAccountModeExplanationDialog(requireActivity(), false)
dialog.show()
}
}
}

View file

@ -30,8 +30,6 @@ import org.linphone.core.tools.Log
import org.linphone.ui.GenericViewModel
import org.linphone.ui.main.model.AccountModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
import org.linphone.ui.main.model.setEndToEndEncryptionMandatory
import org.linphone.ui.main.model.setInteroperabilityMode
import org.linphone.ui.main.settings.model.AccountDeviceModel
import org.linphone.utils.Event
@ -109,7 +107,7 @@ class AccountProfileViewModel @UiThread constructor() : GenericViewModel() {
Log.i("$TAG Found matching account [$found]")
account = found
accountModel.postValue(AccountModel(account))
isCurrentlySelectedModeSecure.postValue(account.isEndToEndEncryptionMandatory())
isCurrentlySelectedModeSecure.postValue(isEndToEndEncryptionMandatory())
registerEnabled.postValue(account.params.isRegisterEnabled)
sipAddress.postValue(account.params.identityAddress?.asStringUriOnly())
@ -267,31 +265,4 @@ class AccountProfileViewModel @UiThread constructor() : GenericViewModel() {
)
}
}
@UiThread
fun switchToSecureMode() {
isCurrentlySelectedModeSecure.value = true
}
@UiThread
fun switchToInteropMode() {
isCurrentlySelectedModeSecure.value = false
}
@UiThread
fun applySelectedMode() {
coreContext.postOnCoreThread { core ->
if (isCurrentlySelectedModeSecure.value == true) {
Log.i(
"$TAG Selected mode is end-to-end encrypted, forcing media & im encryption to mandatory and setting media encryption to ZRTP"
)
account.setEndToEndEncryptionMandatory()
} else {
Log.i(
"$TAG Selected mode is interoperable, not forcing media & im encryption to mandatory and setting media encryption to SRTP"
)
account.setInteroperabilityMode()
}
}
}
}

View file

@ -85,8 +85,7 @@ abstract class AddressSelectionViewModel @UiThread constructor() : DefaultAccoun
multipleSelectionMode.value = false
coreContext.postOnCoreThread { core ->
val defaultAccount = core.defaultAccount
limitSearchToLinphoneAccounts = defaultAccount?.isEndToEndEncryptionMandatory() ?: false
limitSearchToLinphoneAccounts = isEndToEndEncryptionMandatory() ?: false
coreContext.contactsManager.addListener(contactsListener)
magicSearch = core.createMagicSearch()

View file

@ -66,7 +66,7 @@ class ShortcutUtils {
var count = 0
for (chatRoom in defaultAccount.chatRooms) {
if (defaultAccount.isEndToEndEncryptionMandatory() && !chatRoom.currentParams.isEncryptionEnabled) {
if (isEndToEndEncryptionMandatory() && !chatRoom.currentParams.isEncryptionEnabled) {
Log.w(
"$TAG Account is in secure mode, skipping not encrypted conversation [${LinphoneUtils.getChatRoomId(
chatRoom

View file

@ -230,6 +230,7 @@ class TimestampUtils {
)
hours >= 1L -> {
String.format(
Locale.getDefault(),
"%02d:%02d:%02d",
seconds / 3600,
(seconds % 3600) / 60,
@ -237,6 +238,7 @@ class TimestampUtils {
)
}
else -> String.format(
Locale.getDefault(),
"%02d:%02d",
(seconds % 3600) / 60,
(seconds % 60)

View file

@ -81,7 +81,6 @@
<com.google.android.material.radiobutton.MaterialRadioButton
style="@style/default_text_style_800"
android:id="@+id/default_mode"
android:onClick="@{() -> viewModel.switchToSecureMode()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
@ -111,7 +110,6 @@
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/default_mode_summary"
android:onClick="@{() -> viewModel.switchToSecureMode()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
@ -142,7 +140,6 @@
<com.google.android.material.radiobutton.MaterialRadioButton
style="@style/default_text_style_800"
android:id="@+id/interop_mode"
android:onClick="@{() -> viewModel.switchToInteropMode()}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
@ -173,7 +170,6 @@
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
android:id="@+id/interop_mode_summary"
android:onClick="@{() -> viewModel.switchToInteropMode()}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"

View file

@ -67,6 +67,7 @@
android:layout_marginEnd="10dp"
android:padding="12dp"
android:src="@drawable/play_fill"
android:contentDescription="@string/content_description_play_call_recording"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:tint="?attr/color_main1_500" />

View file

@ -141,9 +141,6 @@
<string name="assistant_third_party_sip_account_create_linphone_account">Je préfère créer un compte</string>
<string name="assistant_third_party_sip_account_warning_ok">J\'ai compris</string>
<string name="assistant_third_party_sip_account_username_or_identity">Nom d\'utilisateur ou identité SIP*</string>
<string name="assistant_account_secure_mode_title">Choisissez votre mode</string>
<string name="assistant_account_secure_mode_subtitle">Vous pourrez le changer plus tard</string>
<string name="assistant_secure_mode_finish_account_login">Continuer</string>
<string name="assistant_account_register_unavailable_no_push_toast">Les notifications poussées ne sont pas disponibles, la création de compte est donc désactivée.</string>
<string name="assistant_account_register_username_already_in_use_error">Ce compte existe déjà</string>
<string name="assistant_account_register_username_invalid_characters_error">Caractère(s) invalide(s): les majuscules et les caractères spéciaux ne sont pas autorisés</string>
@ -304,10 +301,9 @@
<string name="manage_account_status_cleared_summary">Compte désactivé, vous ne recevrez ni appel ni message.</string>
<string name="manage_account_status_progress_summary">Connexion en cours, merci de patienter…</string>
<string name="manage_account_status_failed_summary">Erreur de connexion, vérifiez vos paramètres.</string>
<string name="manage_account_change_mode">Changer de mode</string>
<string name="manage_account_international_prefix">Préfixe international</string>
<string name="manage_account_dialog_international_prefix_help_title">Pourquoi en avons-nous besoin ?</string>
<string name="manage_account_dialog_international_prefix_help_message">Blah blah blah</string>
<string name="manage_account_dialog_international_prefix_help_message">Blah blah blah</string> <!-- TODO -->
<string name="manage_account_settings">Paramètres de compte</string>
<string name="manage_account_delete">Supprimer le compte</string>
<string name="manage_account_choose_mode_title">Choisir le mode</string>

View file

@ -176,9 +176,6 @@
<string name="assistant_third_party_sip_account_create_linphone_account">I prefer to create an account</string>
<string name="assistant_third_party_sip_account_warning_ok">I understand</string>
<string name="assistant_third_party_sip_account_username_or_identity">Username or SIP identity*</string>
<string name="assistant_account_secure_mode_title">Personalize your profile mode</string>
<string name="assistant_account_secure_mode_subtitle">You may change that mode later</string>
<string name="assistant_secure_mode_finish_account_login">Continue</string>
<string name="assistant_account_register_unavailable_no_push_toast">Push notifications not available, account creation disabled</string>
<string name="assistant_account_register_username_already_in_use_error">This account already exists</string>
<string name="assistant_account_register_username_invalid_characters_error">Invalid characters: capital letters and special characters are not allowed</string>
@ -339,10 +336,9 @@
<string name="manage_account_status_cleared_summary">Account has been disabled, you won\'t receive any call or message.</string>
<string name="manage_account_status_progress_summary">Account is connecting to the server, please wait…</string>
<string name="manage_account_status_failed_summary">Account connection failed, check your settings.</string>
<string name="manage_account_change_mode">Change mode</string>
<string name="manage_account_international_prefix">International Prefix</string>
<string name="manage_account_dialog_international_prefix_help_title">Why do we need it?</string>
<string name="manage_account_dialog_international_prefix_help_message">Blah blah blah</string>
<string name="manage_account_dialog_international_prefix_help_message">Blah blah blah</string> <!-- TODO -->
<string name="manage_account_settings">Account settings</string>
<string name="manage_account_delete">Delete account</string>
<string name="manage_account_choose_mode_title">Choose account mode</string>
@ -828,4 +824,5 @@
<string name="content_description_carddav_save">Save CardDAV configuration</string>
<string name="content_description_ldap_delete">Delete this LDAP configuration</string>
<string name="content_description_ldap_save">Save LDAP configuration</string>
<string name="content_description_play_call_recording">Plays the call recording</string>
</resources>