diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.kt b/app/src/main/java/org/linphone/contacts/ContactsManager.kt
index d27b1968d..b188f5bbb 100644
--- a/app/src/main/java/org/linphone/contacts/ContactsManager.kt
+++ b/app/src/main/java/org/linphone/contacts/ContactsManager.kt
@@ -138,17 +138,8 @@ class ContactsManager @UiThread constructor() {
@WorkerThread
override fun onDefaultAccountChanged(core: Core, account: Account?) {
- Log.i("$TAG Default account changed, update all contact models showTrust value")
- val showTrust = account?.isEndToEndEncryptionMandatory()
- knownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
- contactAvatarModel.showTrust.postValue(showTrust)
- }
- unknownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
- contactAvatarModel.showTrust.postValue(showTrust)
- }
- conferenceAvatarMap.forEach { (_, contactAvatarModel) ->
- contactAvatarModel.showTrust.postValue(showTrust)
- }
+ Log.i("$TAG Default account changed, update all contacts' model showTrust value")
+ updateContactsModelDependingOnDefaultAccountMode()
}
}
@@ -212,6 +203,7 @@ class ContactsManager @UiThread constructor() {
coreContext.contactsManager.notifyContactsListChanged()
}
+ @WorkerThread
fun contactRemoved(friend: Friend) {
for (sipAddress in friend.addresses) {
val sipUri = sipAddress.asStringUriOnly()
@@ -611,6 +603,24 @@ class ContactsManager @UiThread constructor() {
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
private fun getAvatarModelFromCache(key: String): ContactAvatarModel? {
return knownContactsAvatarsMap[key] ?: unknownContactsAvatarsMap[key]
diff --git a/app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt b/app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt
index b30489ef1..26513b642 100644
--- a/app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt
+++ b/app/src/main/java/org/linphone/ui/assistant/fragment/ProfileModeFragment.kt
@@ -64,6 +64,7 @@ class ProfileModeFragment : Fragment() {
}
binding.setContinueClickListener {
+ viewModel.applySelectedMode()
requireActivity().finish()
}
diff --git a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt
index adb3875ac..f0176ddaa 100644
--- a/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/assistant/viewmodel/AccountLoginViewModel.kt
@@ -35,6 +35,8 @@ import org.linphone.core.Factory
import org.linphone.core.Reason
import org.linphone.core.RegistrationState
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.Event
@@ -221,6 +223,27 @@ open class AccountLoginViewModel @UiThread constructor() : ViewModel() {
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()
diff --git a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt b/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt
index 10f8b5c2b..fb05106f1 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/model/ConversationModel.kt
@@ -39,10 +39,7 @@ import org.linphone.utils.LinphoneUtils
import org.linphone.utils.ShortcutUtils
import org.linphone.utils.TimestampUtils
-class ConversationModel @WorkerThread constructor(
- val chatRoom: ChatRoom,
- val isDisabledBecauseNotSecured: Boolean = false
-) {
+class ConversationModel @WorkerThread constructor(val chatRoom: ChatRoom) {
companion object {
private const val TAG = "[Conversation Model]"
}
@@ -57,6 +54,8 @@ class ConversationModel @WorkerThread constructor(
Capabilities.Conference.toInt()
)
+ val isEncrypted = chatRoom.hasCapability(Capabilities.Encrypted.toInt())
+
val isReadOnly = chatRoom.isReadOnly
val subject = MutableLiveData()
diff --git a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationsListViewModel.kt b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationsListViewModel.kt
index 0743ea3bf..4e95f6e12 100644
--- a/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationsListViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/chat/viewmodel/ConversationsListViewModel.kt
@@ -27,12 +27,10 @@ import org.linphone.R
import org.linphone.contacts.ContactsManager
import org.linphone.core.ChatMessage
import org.linphone.core.ChatRoom
-import org.linphone.core.ChatRoom.Capabilities
import org.linphone.core.Core
import org.linphone.core.CoreListenerStub
import org.linphone.core.tools.Log
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.utils.AppUtils
import org.linphone.utils.Event
@@ -147,11 +145,8 @@ class ConversationsListViewModel @UiThread constructor() : AbstractMainViewModel
val account = LinphoneUtils.getDefaultAccount()
val chatRooms = account?.chatRooms ?: coreContext.core.chatRooms
for (chatRoom in chatRooms) {
- val disabledBecauseNotSecured = account?.isEndToEndEncryptionMandatory() == true && !chatRoom.hasCapability(
- Capabilities.Encrypted.toInt()
- )
if (filter.isEmpty()) {
- val model = ConversationModel(chatRoom, disabledBecauseNotSecured)
+ val model = ConversationModel(chatRoom)
list.add(model)
count += 1
} else {
@@ -173,7 +168,7 @@ class ConversationsListViewModel @UiThread constructor() : AbstractMainViewModel
chatRoom.peerAddress.asStringUriOnly().contains(filter, ignoreCase = true) ||
chatRoom.subject.orEmpty().contains(filter, ignoreCase = true)
) {
- val model = ConversationModel(chatRoom, disabledBecauseNotSecured)
+ val model = ConversationModel(chatRoom)
list.add(model)
count += 1
}
diff --git a/app/src/main/java/org/linphone/ui/main/model/AccountModel.kt b/app/src/main/java/org/linphone/ui/main/model/AccountModel.kt
index 264512663..f71d95418 100644
--- a/app/src/main/java/org/linphone/ui/main/model/AccountModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/model/AccountModel.kt
@@ -24,6 +24,7 @@ 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
@@ -113,8 +114,6 @@ class AccountModel @WorkerThread constructor(
account.addListener(accountListener)
coreContext.core.addListener(coreListener)
- trust.postValue(SecurityLevel.EndToEndEncryptedAndVerified)
- showTrust.postValue(account.isEndToEndEncryptionMandatory())
presenceStatus.postValue(ConsolidatedPresence.Offline)
update()
@@ -166,6 +165,9 @@ class AccountModel @WorkerThread constructor(
"$TAG Refreshing info for account [${account.params.identityAddress?.asStringUriOnly()}]"
)
+ trust.postValue(SecurityLevel.EndToEndEncryptedAndVerified)
+ showTrust.postValue(account.isEndToEndEncryptionMandatory())
+
val name = LinphoneUtils.getDisplayName(account.params.identityAddress)
displayName.postValue(name)
@@ -233,7 +235,47 @@ class AccountModel @WorkerThread constructor(
}
}
+@WorkerThread
fun Account.isEndToEndEncryptionMandatory(): Boolean {
- // TODO FIXME: use real API when available
- return params.identityAddress?.domain == "sip.linphone.org"
+ val defaultDomain = params.identityAddress?.domain == corePreferences.defaultDomain
+ // 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")
}
diff --git a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt
index 736eceda4..6714b0639 100644
--- a/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt
+++ b/app/src/main/java/org/linphone/ui/main/settings/viewmodel/AccountProfileViewModel.kt
@@ -30,6 +30,8 @@ import org.linphone.core.Factory
import org.linphone.core.tools.Log
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
@@ -299,6 +301,18 @@ class AccountProfileViewModel @UiThread constructor() : ViewModel() {
@UiThread
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()
+ }
+ }
}
}
diff --git a/app/src/main/res/layout/account_profile_fragment.xml b/app/src/main/res/layout/account_profile_fragment.xml
index 813455e87..e00d1c463 100644
--- a/app/src/main/res/layout/account_profile_fragment.xml
+++ b/app/src/main/res/layout/account_profile_fragment.xml
@@ -415,7 +415,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="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_constraintStart_toStartOf="@id/mode_background"
app:layout_constraintBottom_toBottomOf="@id/mode_background"/>
diff --git a/app/src/main/res/layout/account_profile_secure_mode_fragment.xml b/app/src/main/res/layout/account_profile_secure_mode_fragment.xml
index 52e1a8295..bc6b39203 100644
--- a/app/src/main/res/layout/account_profile_secure_mode_fragment.xml
+++ b/app/src/main/res/layout/account_profile_secure_mode_fragment.xml
@@ -85,7 +85,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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:textColor="?attr/color_main2_900"
android:checked="@{viewModel.isCurrentlySelectedModeSecure}"
@@ -119,7 +119,7 @@
android:paddingBottom="10dp"
android:paddingStart="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:gravity="start"
android:drawableEnd="@drawable/profile_secure_logo"
@@ -146,7 +146,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
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:textColor="?attr/color_main2_900"
android:checked="@{!viewModel.isCurrentlySelectedModeSecure}"
@@ -180,7 +180,7 @@
android:paddingBottom="20dp"
android:paddingStart="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:gravity="start"
android:drawableEnd="@drawable/profile_interop_logo"
diff --git a/app/src/main/res/layout/assistant_secure_mode_fragment.xml b/app/src/main/res/layout/assistant_secure_mode_fragment.xml
index 664c45d85..4a50cdf08 100644
--- a/app/src/main/res/layout/assistant_secure_mode_fragment.xml
+++ b/app/src/main/res/layout/assistant_secure_mode_fragment.xml
@@ -92,7 +92,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
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:textColor="?attr/color_main2_900"
android:checked="@{viewModel.isCurrentlySelectedModeSecure}"
@@ -127,7 +127,7 @@
android:paddingBottom="20dp"
android:paddingStart="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:gravity="start"
android:drawableEnd="@drawable/profile_secure_logo"
@@ -144,7 +144,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
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:textColor="?attr/color_main2_900"
android:checked="@{!viewModel.isCurrentlySelectedModeSecure}"
@@ -179,7 +179,7 @@
android:paddingBottom="20dp"
android:paddingStart="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:gravity="start"
android:drawableEnd="@drawable/profile_interop_logo"
diff --git a/app/src/main/res/layout/chat_list_cell.xml b/app/src/main/res/layout/chat_list_cell.xml
index 0ba73f376..362430a9a 100644
--- a/app/src/main/res/layout/chat_list_cell.xml
+++ b/app/src/main/res/layout/chat_list_cell.xml
@@ -57,7 +57,7 @@
android:layout_height="wrap_content"
app:barrierDirection="start"
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" />
Supprimer le compte
Choisir le mode
Appliquer
- Chiffré de bout en bout
- Intéropérable
- 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.
- Ce mode vous permet de profiter de toutes les fonctionnalités de &appName; tout en restant interopérable avec n’importe qu’elle autre service SIP.
+ Chiffré de bout en bout
+ Intéropérable
+ 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.
+ Ce mode vous permet de profiter de toutes les fonctionnalités de &appName; tout en restant interopérable avec n’importe qu’elle autre service SIP.
Supprimer
Dernière connexion :
- Blah
- Blah
+ Blah
+ Blah
Supprimer %s ?
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.
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 995d3f32a..405e3e56e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -327,14 +327,14 @@
Delete account
Choose account mode
Apply
- Default mode
- Interoperable mode
- This mode guarantee your data confidentiality. Our end-to-end encryption technology provide the highest level or security for your communications.
- This mode allows you to enjoy all &appName; features while staying interoperable with any SIP service through point-to-point encryption.
+ End-to-end encrypted mode
+ Interoperable mode
+ This mode guarantee your data confidentiality. Our end-to-end encryption technology provide the highest level or security for your communications.
+ This mode allows you to enjoy all &appName; features while staying interoperable with any SIP service through point-to-point encryption.
Remove
Last connection:
- Blah
- Blah
+ Blah
+ Blah
Delete %s?
You can reconnect at any time by clicking “Add an account”. However, all data on this phone will be deleted.