diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt
index 00c6187549b..8988006e512 100644
--- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt
+++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt
@@ -455,6 +455,10 @@ class CallActivity : CallBaseActivity() {
processExtras(intent.extras!!)
conversationUser = currentUserProviderOld.currentUser.blockingGet()
+ if (warnAndFinishIfCallEndToEndEncryptionUnsupported()) {
+ return
+ }
+
credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token)
if (TextUtils.isEmpty(baseUrl)) {
baseUrl = conversationUser!!.baseUrl
@@ -477,6 +481,15 @@ class CallActivity : CallBaseActivity() {
checkInitialDevicePermissions()
}
+ private fun warnAndFinishIfCallEndToEndEncryptionUnsupported(): Boolean {
+ if (!CapabilitiesUtil.isCallEndToEndEncryptionEnabled(conversationUser?.capabilities?.spreedCapability)) {
+ return false
+ }
+ Toast.makeText(context, R.string.nc_call_e2ee_not_supported, Toast.LENGTH_LONG).show()
+ finish()
+ return true
+ }
+
private fun initCallRecordingViewModel(recordingState: Int) {
callRecordingViewModel = ViewModelProvider(this, viewModelFactory).get(
CallRecordingViewModel::class.java
diff --git a/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt b/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt
index aaad05b3aef..abcd3d9d022 100644
--- a/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt
+++ b/app/src/main/java/com/nextcloud/talk/callnotification/CallNotificationActivity.kt
@@ -15,6 +15,7 @@ import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.View
+import android.widget.Toast
import androidx.core.app.NotificationManagerCompat
import autodagger.AutoInjector
import com.nextcloud.talk.R
@@ -29,6 +30,7 @@ import com.nextcloud.talk.extensions.loadUserAvatar
import com.nextcloud.talk.models.json.participants.Participant
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
+import com.nextcloud.talk.utils.CapabilitiesUtil
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
import com.nextcloud.talk.utils.NotificationUtils
import com.nextcloud.talk.utils.SpreedFeatures
@@ -190,6 +192,11 @@ class CallNotificationActivity : CallBaseActivity() {
}
private fun proceedToCall() {
+ if (CapabilitiesUtil.isCallEndToEndEncryptionEnabled(userBeingCalled?.capabilities?.spreedCapability)) {
+ Toast.makeText(context, R.string.nc_call_e2ee_not_supported, Toast.LENGTH_LONG).show()
+ hangup()
+ return
+ }
val callIntent = Intent(this, CallActivity::class.java)
intent.putExtra(KEY_ROOM_ONE_TO_ONE, isOneToOneCall)
callIntent.putExtras(intent.extras!!)
diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
index 0b174c37857..71a21eaaa15 100644
--- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
+++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
@@ -3437,6 +3437,10 @@ class ChatActivity :
private fun startACall(isVoiceOnlyCall: Boolean, callWithoutNotification: Boolean) {
currentConversation?.let {
if (::conversationUser.isInitialized) {
+ if (CapabilitiesUtil.isCallEndToEndEncryptionEnabled(spreedCapabilities)) {
+ Snackbar.make(binding.root, R.string.nc_call_e2ee_not_supported, Snackbar.LENGTH_LONG).show()
+ return
+ }
val pp = ParticipantPermissions(spreedCapabilities, it)
if (!pp.canStartCall() && currentConversation?.hasCall == false) {
Snackbar.make(binding.root, R.string.startCallForbidden, Snackbar.LENGTH_LONG).show()
diff --git a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt
index 51dc3d0c75c..220b95633a1 100644
--- a/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt
+++ b/app/src/main/java/com/nextcloud/talk/chat/MessageInputFragment.kt
@@ -37,7 +37,6 @@ import android.widget.RelativeLayout
import android.widget.SeekBar
import androidx.appcompat.view.ContextThemeWrapper
import androidx.compose.material3.MaterialTheme
-import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged
diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt
index 059bba60338..006ebcf55e9 100644
--- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt
+++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt
@@ -1100,6 +1100,10 @@ class ConversationsListActivity : BaseActivity() {
chatIntent.putExtras(bundle)
if (currentUser != null) {
+ if (CapabilitiesUtil.isCallEndToEndEncryptionEnabled(currentUser?.capabilities?.spreedCapability)) {
+ showSnackbar(context.getString(R.string.nc_call_e2ee_not_supported))
+ return@let
+ }
val pp = ParticipantPermissions(currentUser?.capabilities?.spreedCapability, it)
if (!pp.canStartCall() && selectedConversation?.hasCall == false) {
Log.e(TAG, "Error starting call from conversations list: call is forbidden")
diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt
index 86cb13d8388..4358cf0d83d 100644
--- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt
+++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.kt
@@ -76,6 +76,7 @@ import com.nextcloud.talk.receivers.ShareRecordingToChatReceiver
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ActorAvatar
import com.nextcloud.talk.utils.ApiUtils
+import com.nextcloud.talk.utils.CapabilitiesUtil
import com.nextcloud.talk.utils.CharacterAvatarUtils
import com.nextcloud.talk.utils.ConversationUtils
import com.nextcloud.talk.utils.DisplayUtils
@@ -404,7 +405,14 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
override fun onNext(conversation: ConversationModel) {
if (userManager.setUserAsActive(userBeingCalled!!).blockingGet()) {
- prepareCallNotificationScreen(conversation)
+ if (CapabilitiesUtil.isCallEndToEndEncryptionEnabled(
+ userBeingCalled?.capabilities?.spreedCapability
+ )
+ ) {
+ showEndToEndEncryptionUnsupportedNotification(conversation)
+ } else {
+ prepareCallNotificationScreen(conversation)
+ }
}
}
@@ -1299,6 +1307,34 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
}
}
+ private fun showEndToEndEncryptionUnsupportedNotification(conversation: ConversationModel) {
+ val notificationBuilder = NotificationCompat.Builder(
+ context!!,
+ NotificationUtils.NotificationChannels
+ .NOTIFICATION_CHANNEL_MESSAGES_V4.name
+ )
+
+ val intent = createMainActivityIntent()
+
+ val notification: Notification = notificationBuilder
+ .setContentTitle(
+ String.format(
+ context!!.resources.getString(R.string.nc_call_e2ee_not_supported_title),
+ conversation.displayName
+ )
+ )
+ .setContentText(context!!.resources.getString(R.string.nc_call_e2ee_not_supported))
+ .setSmallIcon(R.drawable.ic_call_black_24dp)
+ .setOngoing(false)
+ .setAutoCancel(true)
+ .setPriority(NotificationCompat.PRIORITY_LOW)
+ .setContentIntent(createUniquePendingIntent(intent))
+ .build()
+
+ sendNotification(pushMessage.timestamp.toInt(), notification)
+ Log.d(TAG, "'end-to-end-encryption not supported' notification was created for ${conversation.token}")
+ }
+
private fun createMainActivityIntent(): Intent {
val intent = Intent(context, MainActivity::class.java)
intent.flags = getIntentFlags()
diff --git a/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt b/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt
index 5448fbed8dc..04ab84f0359 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt
+++ b/app/src/main/java/com/nextcloud/talk/utils/CapabilitiesUtil.kt
@@ -327,6 +327,17 @@ object CapabilitiesUtil {
fun isBanningAvailable(spreedCapabilities: SpreedCapability): Boolean =
hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.BAN_V1)
+ fun isCallEndToEndEncryptionEnabled(spreedCapabilities: SpreedCapability?): Boolean {
+ if (
+ spreedCapabilities?.config?.containsKey("call") == true &&
+ spreedCapabilities.config!!["call"] != null &&
+ spreedCapabilities.config!!["call"]!!.containsKey("end-to-end-encryption")
+ ) {
+ return spreedCapabilities.config!!["call"]!!["end-to-end-encryption"].toString().toBoolean()
+ }
+ return false
+ }
+
// endregion
//region SpreedCapabilities that can't be used with federation as the settings for them are global
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9daacee5f3e..85b4dadbfbc 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -641,6 +641,8 @@ How to translate with transifex:
Keep
Message deleted successfully, but it might have been leaked to other services
You are not allowed to start a call
+ Call from %s unavailable
+ Calling is currently not supported because end-to-end encryption is enabled on the server
You need to promote a new moderator before you can leave the conversation
Room is retained successfully