Added fake implem for Account.isEndToEndEncryptionMandatory() + possibility to change mode

This commit is contained in:
Sylvain Berfini 2024-04-29 15:50:17 +02:00
parent 7633af198a
commit cf7dbb7f61
14 changed files with 137 additions and 53 deletions

View file

@ -138,17 +138,8 @@ class ContactsManager @UiThread constructor() {
@WorkerThread @WorkerThread
override fun onDefaultAccountChanged(core: Core, account: Account?) { override fun onDefaultAccountChanged(core: Core, account: Account?) {
Log.i("$TAG Default account changed, update all contact models showTrust value") Log.i("$TAG Default account changed, update all contacts' model showTrust value")
val showTrust = account?.isEndToEndEncryptionMandatory() updateContactsModelDependingOnDefaultAccountMode()
knownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
unknownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
conferenceAvatarMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
} }
} }
@ -212,6 +203,7 @@ class ContactsManager @UiThread constructor() {
coreContext.contactsManager.notifyContactsListChanged() coreContext.contactsManager.notifyContactsListChanged()
} }
@WorkerThread
fun contactRemoved(friend: Friend) { fun contactRemoved(friend: Friend) {
for (sipAddress in friend.addresses) { for (sipAddress in friend.addresses) {
val sipUri = sipAddress.asStringUriOnly() val sipUri = sipAddress.asStringUriOnly()
@ -611,6 +603,24 @@ class ContactsManager @UiThread constructor() {
return personBuilder.build() return personBuilder.build()
} }
@WorkerThread
fun updateContactsModelDependingOnDefaultAccountMode() {
val account = coreContext.core.defaultAccount
val showTrust = account?.isEndToEndEncryptionMandatory() == true
Log.i(
"$TAG Default account mode is [${if (showTrust) "end-to-end encryption mandatory" else "interoperable"}], update all contact models showTrust value"
)
knownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
unknownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
conferenceAvatarMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
}
@WorkerThread @WorkerThread
private fun getAvatarModelFromCache(key: String): ContactAvatarModel? { private fun getAvatarModelFromCache(key: String): ContactAvatarModel? {
return knownContactsAvatarsMap[key] ?: unknownContactsAvatarsMap[key] return knownContactsAvatarsMap[key] ?: unknownContactsAvatarsMap[key]

View file

@ -64,6 +64,7 @@ class ProfileModeFragment : Fragment() {
} }
binding.setContinueClickListener { binding.setContinueClickListener {
viewModel.applySelectedMode()
requireActivity().finish() requireActivity().finish()
} }

View file

@ -35,6 +35,8 @@ import org.linphone.core.Factory
import org.linphone.core.Reason import org.linphone.core.Reason
import org.linphone.core.RegistrationState import org.linphone.core.RegistrationState
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.ui.main.model.setEndToEndEncryptionMandatory
import org.linphone.ui.main.model.setInteroperabilityMode
import org.linphone.utils.AppUtils import org.linphone.utils.AppUtils
import org.linphone.utils.Event import org.linphone.utils.Event
@ -221,6 +223,27 @@ open class AccountLoginViewModel @UiThread constructor() : ViewModel() {
isCurrentlySelectedModeSecure.value = false 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 @UiThread
private fun isLoginButtonEnabled(): Boolean { private fun isLoginButtonEnabled(): Boolean {
return sipIdentity.value.orEmpty().trim().isNotEmpty() && password.value.orEmpty().isNotEmpty() return sipIdentity.value.orEmpty().trim().isNotEmpty() && password.value.orEmpty().isNotEmpty()

View file

@ -39,10 +39,7 @@ import org.linphone.utils.LinphoneUtils
import org.linphone.utils.ShortcutUtils import org.linphone.utils.ShortcutUtils
import org.linphone.utils.TimestampUtils import org.linphone.utils.TimestampUtils
class ConversationModel @WorkerThread constructor( class ConversationModel @WorkerThread constructor(val chatRoom: ChatRoom) {
val chatRoom: ChatRoom,
val isDisabledBecauseNotSecured: Boolean = false
) {
companion object { companion object {
private const val TAG = "[Conversation Model]" private const val TAG = "[Conversation Model]"
} }
@ -57,6 +54,8 @@ class ConversationModel @WorkerThread constructor(
Capabilities.Conference.toInt() Capabilities.Conference.toInt()
) )
val isEncrypted = chatRoom.hasCapability(Capabilities.Encrypted.toInt())
val isReadOnly = chatRoom.isReadOnly val isReadOnly = chatRoom.isReadOnly
val subject = MutableLiveData<String>() val subject = MutableLiveData<String>()

View file

@ -27,12 +27,10 @@ import org.linphone.R
import org.linphone.contacts.ContactsManager import org.linphone.contacts.ContactsManager
import org.linphone.core.ChatMessage import org.linphone.core.ChatMessage
import org.linphone.core.ChatRoom import org.linphone.core.ChatRoom
import org.linphone.core.ChatRoom.Capabilities
import org.linphone.core.Core import org.linphone.core.Core
import org.linphone.core.CoreListenerStub import org.linphone.core.CoreListenerStub
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.ui.main.chat.model.ConversationModel import org.linphone.ui.main.chat.model.ConversationModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
import org.linphone.ui.main.viewmodel.AbstractMainViewModel import org.linphone.ui.main.viewmodel.AbstractMainViewModel
import org.linphone.utils.AppUtils import org.linphone.utils.AppUtils
import org.linphone.utils.Event import org.linphone.utils.Event
@ -147,11 +145,8 @@ class ConversationsListViewModel @UiThread constructor() : AbstractMainViewModel
val account = LinphoneUtils.getDefaultAccount() val account = LinphoneUtils.getDefaultAccount()
val chatRooms = account?.chatRooms ?: coreContext.core.chatRooms val chatRooms = account?.chatRooms ?: coreContext.core.chatRooms
for (chatRoom in chatRooms) { for (chatRoom in chatRooms) {
val disabledBecauseNotSecured = account?.isEndToEndEncryptionMandatory() == true && !chatRoom.hasCapability(
Capabilities.Encrypted.toInt()
)
if (filter.isEmpty()) { if (filter.isEmpty()) {
val model = ConversationModel(chatRoom, disabledBecauseNotSecured) val model = ConversationModel(chatRoom)
list.add(model) list.add(model)
count += 1 count += 1
} else { } else {
@ -173,7 +168,7 @@ class ConversationsListViewModel @UiThread constructor() : AbstractMainViewModel
chatRoom.peerAddress.asStringUriOnly().contains(filter, ignoreCase = true) || chatRoom.peerAddress.asStringUriOnly().contains(filter, ignoreCase = true) ||
chatRoom.subject.orEmpty().contains(filter, ignoreCase = true) chatRoom.subject.orEmpty().contains(filter, ignoreCase = true)
) { ) {
val model = ConversationModel(chatRoom, disabledBecauseNotSecured) val model = ConversationModel(chatRoom)
list.add(model) list.add(model)
count += 1 count += 1
} }

View file

@ -24,6 +24,7 @@ import androidx.annotation.UiThread
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R import org.linphone.R
import org.linphone.contacts.AbstractAvatarModel import org.linphone.contacts.AbstractAvatarModel
import org.linphone.core.Account import org.linphone.core.Account
@ -113,8 +114,6 @@ class AccountModel @WorkerThread constructor(
account.addListener(accountListener) account.addListener(accountListener)
coreContext.core.addListener(coreListener) coreContext.core.addListener(coreListener)
trust.postValue(SecurityLevel.EndToEndEncryptedAndVerified)
showTrust.postValue(account.isEndToEndEncryptionMandatory())
presenceStatus.postValue(ConsolidatedPresence.Offline) presenceStatus.postValue(ConsolidatedPresence.Offline)
update() update()
@ -166,6 +165,9 @@ class AccountModel @WorkerThread constructor(
"$TAG Refreshing info for account [${account.params.identityAddress?.asStringUriOnly()}]" "$TAG Refreshing info for account [${account.params.identityAddress?.asStringUriOnly()}]"
) )
trust.postValue(SecurityLevel.EndToEndEncryptedAndVerified)
showTrust.postValue(account.isEndToEndEncryptionMandatory())
val name = LinphoneUtils.getDisplayName(account.params.identityAddress) val name = LinphoneUtils.getDisplayName(account.params.identityAddress)
displayName.postValue(name) displayName.postValue(name)
@ -233,7 +235,47 @@ class AccountModel @WorkerThread constructor(
} }
} }
@WorkerThread
fun Account.isEndToEndEncryptionMandatory(): Boolean { fun Account.isEndToEndEncryptionMandatory(): Boolean {
// TODO FIXME: use real API when available val defaultDomain = params.identityAddress?.domain == corePreferences.defaultDomain
return params.identityAddress?.domain == "sip.linphone.org" // TODO FIXME: use API when available
// val encryption = params.mediaEncryption == MediaEncryption.ZRTP && params.mediaEncryptionMandatory && params.instantMessagingEncryptionMandatory
val encryption = corePreferences.config.getBool("test", "account_e2e_mode", false)
return defaultDomain && encryption
}
@WorkerThread
fun Account.setEndToEndEncryptionMandatory() {
/*
TODO FIXME: use API when available
val clone = params.clone()
clone.mediaEncryption = MediaEncryption.ZRTP
clone.mediaEncryptionMandatory = true
clone.instantMessagingEncryptionMandatory = true
params = clone
*/
corePreferences.config.setBool("test", "account_e2e_mode", true)
if (this == core.defaultAccount) {
coreContext.contactsManager.updateContactsModelDependingOnDefaultAccountMode()
}
Log.i("[Account] End-to-end encryption set mandatory on account")
}
@WorkerThread
fun Account.setInteroperabilityMode() {
/*
TODO FIXME: use API when available
val clone = params.clone()
clone.mediaEncryption = MediaEncryption.SRTP
clone.mediaEncryptionMandatory = false
clone.instantMessagingEncryptionMandatory = false
params = clone
*/
corePreferences.config.setBool("test", "account_e2e_mode", false)
if (this == core.defaultAccount) {
coreContext.contactsManager.updateContactsModelDependingOnDefaultAccountMode()
}
Log.i("[Account] Account configured in interoperable mode")
} }

View file

@ -30,6 +30,8 @@ import org.linphone.core.Factory
import org.linphone.core.tools.Log import org.linphone.core.tools.Log
import org.linphone.ui.main.model.AccountModel import org.linphone.ui.main.model.AccountModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory 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.ui.main.settings.model.AccountDeviceModel
import org.linphone.utils.Event import org.linphone.utils.Event
@ -299,6 +301,18 @@ class AccountProfileViewModel @UiThread constructor() : ViewModel() {
@UiThread @UiThread
fun applySelectedMode() { fun applySelectedMode() {
// TODO 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

@ -415,7 +415,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:text="@{viewModel.isCurrentlySelectedModeSecure ? @string/manage_account_secure_mode_default_title : @string/manage_account_secure_mode_interoperable_title, default=@string/manage_account_secure_mode_default_title}" android:text="@{viewModel.isCurrentlySelectedModeSecure ? @string/manage_account_e2e_encrypted_mode_default_title : @string/manage_account_e2e_encrypted_mode_interoperable_title, default=@string/manage_account_e2e_encrypted_mode_default_title}"
app:layout_constraintTop_toTopOf="@id/mode_background" app:layout_constraintTop_toTopOf="@id/mode_background"
app:layout_constraintStart_toStartOf="@id/mode_background" app:layout_constraintStart_toStartOf="@id/mode_background"
app:layout_constraintBottom_toBottomOf="@id/mode_background"/> app:layout_constraintBottom_toBottomOf="@id/mode_background"/>

View file

@ -85,7 +85,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
android:text="@string/manage_account_secure_mode_default_title" android:text="@string/manage_account_e2e_encrypted_mode_default_title"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/color_main2_900" android:textColor="?attr/color_main2_900"
android:checked="@{viewModel.isCurrentlySelectedModeSecure}" android:checked="@{viewModel.isCurrentlySelectedModeSecure}"
@ -119,7 +119,7 @@
android:paddingBottom="10dp" android:paddingBottom="10dp"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_default_summary" android:text="@string/manage_account_e2e_encrypted_mode_default_summary"
android:textSize="14sp" android:textSize="14sp"
android:gravity="start" android:gravity="start"
android:drawableEnd="@drawable/profile_secure_logo" android:drawableEnd="@drawable/profile_secure_logo"
@ -146,7 +146,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
android:layout_marginStart="20dp" android:layout_marginStart="20dp"
android:text="@string/manage_account_secure_mode_interoperable_title" android:text="@string/manage_account_e2e_encrypted_mode_interoperable_title"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/color_main2_900" android:textColor="?attr/color_main2_900"
android:checked="@{!viewModel.isCurrentlySelectedModeSecure}" android:checked="@{!viewModel.isCurrentlySelectedModeSecure}"
@ -180,7 +180,7 @@
android:paddingBottom="20dp" android:paddingBottom="20dp"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_interoperable_summary" android:text="@string/manage_account_e2e_encrypted_mode_interoperable_summary"
android:textSize="14sp" android:textSize="14sp"
android:gravity="start" android:gravity="start"
android:drawableEnd="@drawable/profile_interop_logo" android:drawableEnd="@drawable/profile_interop_logo"

View file

@ -92,7 +92,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:text="@string/manage_account_secure_mode_default_title" android:text="@string/manage_account_e2e_encrypted_mode_default_title"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/color_main2_900" android:textColor="?attr/color_main2_900"
android:checked="@{viewModel.isCurrentlySelectedModeSecure}" android:checked="@{viewModel.isCurrentlySelectedModeSecure}"
@ -127,7 +127,7 @@
android:paddingBottom="20dp" android:paddingBottom="20dp"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_default_summary" android:text="@string/manage_account_e2e_encrypted_mode_default_summary"
android:textSize="14sp" android:textSize="14sp"
android:gravity="start" android:gravity="start"
android:drawableEnd="@drawable/profile_secure_logo" android:drawableEnd="@drawable/profile_secure_logo"
@ -144,7 +144,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:text="@string/manage_account_secure_mode_interoperable_title" android:text="@string/manage_account_e2e_encrypted_mode_interoperable_title"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/color_main2_900" android:textColor="?attr/color_main2_900"
android:checked="@{!viewModel.isCurrentlySelectedModeSecure}" android:checked="@{!viewModel.isCurrentlySelectedModeSecure}"
@ -179,7 +179,7 @@
android:paddingBottom="20dp" android:paddingBottom="20dp"
android:paddingStart="16dp" android:paddingStart="16dp"
android:paddingEnd="16dp" android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_interoperable_summary" android:text="@string/manage_account_e2e_encrypted_mode_interoperable_summary"
android:textSize="14sp" android:textSize="14sp"
android:gravity="start" android:gravity="start"
android:drawableEnd="@drawable/profile_interop_logo" android:drawableEnd="@drawable/profile_interop_logo"

View file

@ -57,7 +57,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:barrierDirection="start" app:barrierDirection="start"
app:barrierMargin="-5dp" app:barrierMargin="-5dp"
app:constraint_referenced_ids="notifications_count, warning_disabled_not_secured, ephemeral, muted, date_time, last_sent_message_status" /> app:constraint_referenced_ids="notifications_count, warning_not_secured, ephemeral, muted, date_time, last_sent_message_status" />
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style" style="@style/default_text_style"
@ -161,13 +161,13 @@
app:tint="?attr/color_main2_400" /> app:tint="?attr/color_main2_400" />
<ImageView <ImageView
android:id="@+id/warning_disabled_not_secured" android:id="@+id/warning_not_secured"
android:layout_width="@dimen/small_icon_size" android:layout_width="@dimen/small_icon_size"
android:layout_height="@dimen/small_icon_size" android:layout_height="@dimen/small_icon_size"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:src="@drawable/lock_simple_open_bold" android:src="@drawable/lock_simple_open_bold"
android:visibility="@{model.isDisabledBecauseNotSecured ? View.VISIBLE : View.GONE}" android:visibility="@{model.isEncrypted ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toBottomOf="@id/date_time" app:layout_constraintTop_toBottomOf="@id/date_time"
app:layout_constraintBottom_toTopOf="@id/separator" app:layout_constraintBottom_toTopOf="@id/separator"
app:layout_constraintEnd_toStartOf="@id/ephemeral" app:layout_constraintEnd_toStartOf="@id/ephemeral"

View file

@ -39,7 +39,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
android:paddingTop="@dimen/dialog_top_bottom_margin" android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="@{defaultMode ? @string/manage_account_secure_mode_default_title : @string/manage_account_secure_mode_interoperable_title, default=@string/manage_account_secure_mode_default_title}" android:text="@{defaultMode ? @string/manage_account_e2e_encrypted_mode_default_title : @string/manage_account_e2e_encrypted_mode_interoperable_title, default=@string/manage_account_e2e_encrypted_mode_default_title}"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toTopOf="@id/message" app:layout_constraintBottom_toTopOf="@id/message"
app:layout_constraintStart_toStartOf="@id/dialog_background" app:layout_constraintStart_toStartOf="@id/dialog_background"
@ -54,7 +54,7 @@
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
android:layout_marginEnd="15dp" android:layout_marginEnd="15dp"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:text="@{defaultMode ? @string/manage_account_dialog_secure_mode_default_message : @string/manage_account_dialog_secure_mode_interoperable_message, default=@string/manage_account_dialog_secure_mode_default_message}" android:text="@{defaultMode ? @string/manage_account_dialog_e2e_encrypted_mode_default_message : @string/manage_account_dialog_e2e_encrypted_mode_interoperable_message, default=@string/manage_account_dialog_e2e_encrypted_mode_default_message}"
android:textSize="14sp" android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/confirm" app:layout_constraintBottom_toTopOf="@id/confirm"
app:layout_constraintStart_toStartOf="@id/dialog_background" app:layout_constraintStart_toStartOf="@id/dialog_background"

View file

@ -292,14 +292,14 @@
<string name="manage_account_delete">Supprimer le compte</string> <string name="manage_account_delete">Supprimer le compte</string>
<string name="manage_account_choose_mode_title">Choisir le mode</string> <string name="manage_account_choose_mode_title">Choisir le mode</string>
<string name="manage_account_choose_mode_apply_label">Appliquer</string> <string name="manage_account_choose_mode_apply_label">Appliquer</string>
<string name="manage_account_secure_mode_default_title">Chiffré de bout en bout</string> <string name="manage_account_e2e_encrypted_mode_default_title">Chiffré de bout en bout</string>
<string name="manage_account_secure_mode_interoperable_title">Intéropérable</string> <string name="manage_account_e2e_encrypted_mode_interoperable_title">Intéropérable</string>
<string name="manage_account_secure_mode_default_summary">Ce mode vous garantit la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges.</string> <string name="manage_account_e2e_encrypted_mode_default_summary">Ce mode vous garantit la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges.</string>
<string name="manage_account_secure_mode_interoperable_summary">Ce mode vous permet de profiter de toutes les fonctionnalités de &appName; tout en restant interopérable avec nimporte quelle autre service SIP.</string> <string name="manage_account_e2e_encrypted_mode_interoperable_summary">Ce mode vous permet de profiter de toutes les fonctionnalités de &appName; tout en restant interopérable avec nimporte quelle autre service SIP.</string>
<string name="manage_account_device_remove">Supprimer</string> <string name="manage_account_device_remove">Supprimer</string>
<string name="manage_account_device_last_connection">Dernière connexion :</string> <string name="manage_account_device_last_connection">Dernière connexion :</string>
<string name="manage_account_dialog_secure_mode_default_message">Blah</string> <!-- TODO --> <string name="manage_account_dialog_e2e_encrypted_mode_default_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_secure_mode_interoperable_message">Blah</string> <!-- TODO --> <string name="manage_account_dialog_e2e_encrypted_mode_interoperable_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_remove_account_title">Supprimer %s ?</string> <string name="manage_account_dialog_remove_account_title">Supprimer %s ?</string>
<string name="manage_account_dialog_remove_account_message">Vous pouvez vous reconnecter à tout moment en cliquant sur "Ajouter un compte".Cependant toutes les informations stockées sur ce périphérique seront supprimées.</string> <string name="manage_account_dialog_remove_account_message">Vous pouvez vous reconnecter à tout moment en cliquant sur "Ajouter un compte".Cependant toutes les informations stockées sur ce périphérique seront supprimées.</string>

View file

@ -327,14 +327,14 @@
<string name="manage_account_delete">Delete account</string> <string name="manage_account_delete">Delete account</string>
<string name="manage_account_choose_mode_title">Choose account mode</string> <string name="manage_account_choose_mode_title">Choose account mode</string>
<string name="manage_account_choose_mode_apply_label">Apply</string> <string name="manage_account_choose_mode_apply_label">Apply</string>
<string name="manage_account_secure_mode_default_title">Default mode</string> <string name="manage_account_e2e_encrypted_mode_default_title">End-to-end encrypted mode</string>
<string name="manage_account_secure_mode_interoperable_title">Interoperable mode</string> <string name="manage_account_e2e_encrypted_mode_interoperable_title">Interoperable mode</string>
<string name="manage_account_secure_mode_default_summary">This mode guarantee your data confidentiality. Our end-to-end encryption technology provide the highest level or security for your communications.</string> <string name="manage_account_e2e_encrypted_mode_default_summary">This mode guarantee your data confidentiality. Our end-to-end encryption technology provide the highest level or security for your communications.</string>
<string name="manage_account_secure_mode_interoperable_summary">This mode allows you to enjoy all &appName; features while staying interoperable with any SIP service through point-to-point encryption.</string> <string name="manage_account_e2e_encrypted_mode_interoperable_summary">This mode allows you to enjoy all &appName; features while staying interoperable with any SIP service through point-to-point encryption.</string>
<string name="manage_account_device_remove">Remove</string> <string name="manage_account_device_remove">Remove</string>
<string name="manage_account_device_last_connection">Last connection:</string> <string name="manage_account_device_last_connection">Last connection:</string>
<string name="manage_account_dialog_secure_mode_default_message">Blah</string> <!-- TODO --> <string name="manage_account_dialog_e2e_encrypted_mode_default_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_secure_mode_interoperable_message">Blah</string> <!-- TODO --> <string name="manage_account_dialog_e2e_encrypted_mode_interoperable_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_remove_account_title">Delete %s?</string> <string name="manage_account_dialog_remove_account_title">Delete %s?</string>
<string name="manage_account_dialog_remove_account_message">You can reconnect at any time by clicking “Add an account”. However, all data on this phone will be deleted.</string> <string name="manage_account_dialog_remove_account_message">You can reconnect at any time by clicking “Add an account”. However, all data on this phone will be deleted.</string>