mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-15 08:45:04 +01:00
Various bug fixes
Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
parent
8a661b355a
commit
371aa332c5
@ -21,9 +21,14 @@ package com.nextcloud.talk.services.firebase
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.work.Data
|
||||||
|
import androidx.work.OneTimeWorkRequest
|
||||||
|
import androidx.work.WorkManager
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService
|
import com.google.firebase.messaging.FirebaseMessagingService
|
||||||
import com.google.firebase.messaging.RemoteMessage
|
import com.google.firebase.messaging.RemoteMessage
|
||||||
|
import com.nextcloud.talk.jobs.NotificationWorker
|
||||||
import com.nextcloud.talk.newarch.services.CallService
|
import com.nextcloud.talk.newarch.services.CallService
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INCOMING_PUSH_MESSSAGE
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INCOMING_PUSH_MESSSAGE
|
||||||
@ -42,10 +47,12 @@ class MagicFirebaseMessagingService : FirebaseMessagingService(), KoinComponent
|
|||||||
|
|
||||||
@SuppressLint("LongLogTag")
|
@SuppressLint("LongLogTag")
|
||||||
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
||||||
val incomingCallIntent = Intent(applicationContext, CallService::class.java)
|
val messageData = Data.Builder()
|
||||||
incomingCallIntent.action = KEY_INCOMING_PUSH_MESSSAGE
|
.putString(BundleKeys.KEY_ENCRYPTED_SUBJECT, remoteMessage.data["subject"])
|
||||||
incomingCallIntent.putExtra(BundleKeys.KEY_ENCRYPTED_SUBJECT, remoteMessage.data["subject"])
|
.putString(BundleKeys.KEY_ENCRYPTED_SIGNATURE, remoteMessage.data["signature"])
|
||||||
incomingCallIntent.putExtra(BundleKeys.KEY_ENCRYPTED_SIGNATURE, remoteMessage.data["signature"])
|
.build()
|
||||||
ContextCompat.startForegroundService(applicationContext, incomingCallIntent)
|
|
||||||
|
val pushNotificationWork = OneTimeWorkRequest.Builder(NotificationWorker::class.java).setInputData(messageData).build()
|
||||||
|
WorkManager.getInstance().enqueue(pushNotificationWork)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1466,8 +1466,12 @@ class CallController(args: Bundle) : BaseController() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
timer.cancel()
|
timer.cancel()
|
||||||
recorder.stop()
|
try {
|
||||||
recorder.release()
|
recorder.stop()
|
||||||
|
recorder.release()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
hangupNetworkCalls(shutDownView)
|
hangupNetworkCalls(shutDownView)
|
||||||
}
|
}
|
||||||
@ -2267,7 +2271,7 @@ class CallController(args: Bundle) : BaseController() {
|
|||||||
}
|
}
|
||||||
CallController.CallStatus.IN_CONVERSATION -> handler!!.post {
|
CallController.CallStatus.IN_CONVERSATION -> handler!!.post {
|
||||||
stopCallingSound()
|
stopCallingSound()
|
||||||
startListening()
|
//startListening()
|
||||||
|
|
||||||
if (!isPTTActive) {
|
if (!isPTTActive) {
|
||||||
animateCallControls(false, 5000)
|
animateCallControls(false, 5000)
|
||||||
|
@ -21,6 +21,7 @@ package com.nextcloud.talk.jobs
|
|||||||
|
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.media.AudioAttributes
|
import android.media.AudioAttributes
|
||||||
@ -28,9 +29,12 @@ import android.media.AudioManager
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Base64
|
||||||
|
import android.util.Log
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.app.Person
|
import androidx.core.app.Person
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
import androidx.emoji.text.EmojiCompat
|
import androidx.emoji.text.EmojiCompat
|
||||||
@ -44,28 +48,42 @@ import com.nextcloud.talk.R
|
|||||||
import com.nextcloud.talk.models.SignatureVerification
|
import com.nextcloud.talk.models.SignatureVerification
|
||||||
import com.nextcloud.talk.models.json.chat.ChatUtils
|
import com.nextcloud.talk.models.json.chat.ChatUtils
|
||||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||||
|
import com.nextcloud.talk.models.json.conversations.ConversationOverall
|
||||||
import com.nextcloud.talk.models.json.notifications.NotificationOverall
|
import com.nextcloud.talk.models.json.notifications.NotificationOverall
|
||||||
import com.nextcloud.talk.models.json.push.DecryptedPushMessage
|
import com.nextcloud.talk.models.json.push.DecryptedPushMessage
|
||||||
import com.nextcloud.talk.models.json.push.NotificationUser
|
import com.nextcloud.talk.models.json.push.NotificationUser
|
||||||
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
||||||
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
import com.nextcloud.talk.newarch.data.source.remote.ApiErrorHandler
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.ConversationsRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
|
||||||
|
import com.nextcloud.talk.newarch.domain.usecases.GetConversationUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.GetNotificationUseCase
|
import com.nextcloud.talk.newarch.domain.usecases.GetNotificationUseCase
|
||||||
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
||||||
|
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||||
import com.nextcloud.talk.newarch.local.models.toUser
|
import com.nextcloud.talk.newarch.local.models.toUser
|
||||||
|
import com.nextcloud.talk.newarch.services.CallService
|
||||||
import com.nextcloud.talk.newarch.utils.Images
|
import com.nextcloud.talk.newarch.utils.Images
|
||||||
import com.nextcloud.talk.newarch.utils.MagicJson
|
import com.nextcloud.talk.newarch.utils.MagicJson
|
||||||
import com.nextcloud.talk.newarch.utils.NetworkComponents
|
import com.nextcloud.talk.newarch.utils.NetworkComponents
|
||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.NotificationUtils
|
import com.nextcloud.talk.utils.NotificationUtils
|
||||||
|
import com.nextcloud.talk.utils.PushUtils
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||||
|
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SHOW_INCOMING_CALL
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import org.koin.core.KoinComponent
|
import org.koin.core.KoinComponent
|
||||||
import org.koin.core.inject
|
import org.koin.core.inject
|
||||||
import org.koin.core.parameter.parametersOf
|
import org.koin.core.parameter.parametersOf
|
||||||
|
import java.security.InvalidKeyException
|
||||||
|
import java.security.NoSuchAlgorithmException
|
||||||
|
import java.security.PrivateKey
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
import javax.crypto.Cipher
|
||||||
|
import javax.crypto.NoSuchPaddingException
|
||||||
|
|
||||||
class NotificationWorker(
|
class NotificationWorker(
|
||||||
context: Context,
|
context: Context,
|
||||||
@ -74,34 +92,106 @@ class NotificationWorker(
|
|||||||
val appPreferences: AppPreferences by inject()
|
val appPreferences: AppPreferences by inject()
|
||||||
private val networkComponents: NetworkComponents by inject()
|
private val networkComponents: NetworkComponents by inject()
|
||||||
private val apiErrorHandler: ApiErrorHandler by inject()
|
private val apiErrorHandler: ApiErrorHandler by inject()
|
||||||
|
private val usersRepository: UsersRepository by inject()
|
||||||
|
private val conversationsRepository: ConversationsRepository by inject()
|
||||||
|
|
||||||
|
val tag: String = "NotificationWorker"
|
||||||
|
|
||||||
override suspend fun doWork(): Result = coroutineScope {
|
override suspend fun doWork(): Result = coroutineScope {
|
||||||
val data = inputData
|
val data = inputData
|
||||||
val decryptedPushMessageString: String = data.getString(BundleKeys.KEY_DECRYPTED_PUSH_MESSAGE)!!
|
decryptMessage(data.getString(BundleKeys.KEY_ENCRYPTED_SUBJECT)!!, data.getString(BundleKeys.KEY_ENCRYPTED_SIGNATURE)!!)
|
||||||
val signatureVerificationString: String = data.getString(BundleKeys.KEY_SIGNATURE_VERIFICATION)!!
|
|
||||||
val conversationString: String = data.getString(BundleKeys.KEY_CONVERSATION)!!
|
|
||||||
|
|
||||||
val json = Json(MagicJson.customJsonConfiguration)
|
Result.success()
|
||||||
val decryptedPushMessage = LoganSquare.parse(decryptedPushMessageString, DecryptedPushMessage::class.java)
|
}
|
||||||
val signatureVerification = json.parse(SignatureVerification.serializer(), signatureVerificationString)
|
|
||||||
val conversation = json.parse(Conversation.serializer(), conversationString)
|
|
||||||
|
|
||||||
when (decryptedPushMessage.type) {
|
private suspend fun decryptMessage(subject: String, signature: String) = coroutineScope {
|
||||||
"room" -> {
|
val signatureVerification: SignatureVerification
|
||||||
showNotificationWithObjectData(this, decryptedPushMessage, signatureVerification, conversation)
|
val decryptedPushMessage: DecryptedPushMessage
|
||||||
|
|
||||||
|
try {
|
||||||
|
val base64DecodedSubject = Base64.decode(subject, Base64.DEFAULT)
|
||||||
|
val base64DecodedSignature = Base64.decode(signature, Base64.DEFAULT)
|
||||||
|
val pushUtils = PushUtils(usersRepository)
|
||||||
|
val privateKey = pushUtils.readKeyFromFile(false) as PrivateKey
|
||||||
|
try {
|
||||||
|
signatureVerification = pushUtils.verifySignature(base64DecodedSignature, base64DecodedSubject)
|
||||||
|
if (signatureVerification.signatureValid) {
|
||||||
|
val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, privateKey)
|
||||||
|
val decryptedSubject = cipher.doFinal(base64DecodedSubject)
|
||||||
|
decryptedPushMessage = LoganSquare.parse(String(decryptedSubject), DecryptedPushMessage::class.java)
|
||||||
|
var conversation: Conversation? = null
|
||||||
|
decryptedPushMessage.id?.let {
|
||||||
|
conversation = getConversationForTokenAndUser(signatureVerification.userEntity!!, it)
|
||||||
|
}
|
||||||
|
|
||||||
|
decryptedPushMessage.apply {
|
||||||
|
when {
|
||||||
|
delete -> {
|
||||||
|
NotificationUtils.cancelExistingNotificationWithId(applicationContext, signatureVerification.userEntity!!, notificationId!!)
|
||||||
|
}
|
||||||
|
deleteAll -> {
|
||||||
|
NotificationUtils.cancelAllNotificationsForAccount(applicationContext, signatureVerification.userEntity!!)
|
||||||
|
}
|
||||||
|
type == "call" && (conversation?.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION || conversation?.objectType.equals("share:password")) -> {
|
||||||
|
conversation?.let {
|
||||||
|
// start service
|
||||||
|
val json = Json(MagicJson.customJsonConfiguration)
|
||||||
|
val incomingCallIntent = Intent(applicationContext, CallService::class.java)
|
||||||
|
incomingCallIntent.action = KEY_SHOW_INCOMING_CALL
|
||||||
|
incomingCallIntent.putExtra(BundleKeys.KEY_DECRYPTED_PUSH_MESSAGE, LoganSquare.serialize(decryptedPushMessage))
|
||||||
|
incomingCallIntent.putExtra(BundleKeys.KEY_SIGNATURE_VERIFICATION, json.stringify(SignatureVerification.serializer(), signatureVerification))
|
||||||
|
incomingCallIntent.putExtra(BundleKeys.KEY_CONVERSATION, json.stringify(Conversation.serializer(), it))
|
||||||
|
ContextCompat.startForegroundService(applicationContext, incomingCallIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
type == "call" -> {
|
||||||
|
conversation?.let { showNotification(decryptedPushMessage, signatureVerification, it) }
|
||||||
|
}
|
||||||
|
type == "room" -> {
|
||||||
|
conversation?.let { showNotificationWithObjectData(this@coroutineScope, decryptedPushMessage, signatureVerification, it) }
|
||||||
|
}
|
||||||
|
type == "chat" -> {
|
||||||
|
conversation?.let { showNotificationWithObjectData(this@coroutineScope, decryptedPushMessage, signatureVerification, it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
} catch (e1: NoSuchAlgorithmException) {
|
||||||
|
Log.d(tag, "No proper algorithm to decrypt the message " + e1.localizedMessage)
|
||||||
|
} catch (e1: NoSuchPaddingException) {
|
||||||
|
Log.d(tag, "No proper padding to decrypt the message " + e1.localizedMessage)
|
||||||
|
} catch (e1: InvalidKeyException) {
|
||||||
|
Log.d(tag, "Invalid private key " + e1.localizedMessage)
|
||||||
}
|
}
|
||||||
"chat" -> {
|
} catch (exception: Exception) {
|
||||||
showNotificationWithObjectData(this, decryptedPushMessage, signatureVerification, conversation)
|
Log.d(tag, "Something went very wrong " + exception.localizedMessage)
|
||||||
}
|
}
|
||||||
"call" -> {
|
}
|
||||||
showNotification(decryptedPushMessage, signatureVerification, conversation)
|
|
||||||
}
|
private suspend fun getConversationForTokenAndUser(user: UserNgEntity, conversationToken: String): Conversation? {
|
||||||
else -> {
|
var conversation = conversationsRepository.getConversationForUserWithToken(user.id, conversationToken)
|
||||||
// do nothing
|
if (conversation == null) {
|
||||||
|
val getConversationUseCase = GetConversationUseCase(networkComponents.getRepository(false, user.toUser()), apiErrorHandler)
|
||||||
|
runBlocking {
|
||||||
|
getConversationUseCase.invoke(this, parametersOf(user, conversationToken), object : UseCaseResponse<ConversationOverall> {
|
||||||
|
override suspend fun onSuccess(result: ConversationOverall) {
|
||||||
|
val internalConversation = result.ocs.data
|
||||||
|
conversationsRepository.saveConversationsForUser(user.id, listOf(internalConversation), false)
|
||||||
|
conversation = result.ocs.data
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onError(errorModel: ErrorModel?) {
|
||||||
|
conversation = null
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result.success()
|
return conversation
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showNotificationWithObjectData(coroutineScope: CoroutineScope, decryptedPushMessage: DecryptedPushMessage, signatureVerification: SignatureVerification, conversation: Conversation) {
|
private fun showNotificationWithObjectData(coroutineScope: CoroutineScope, decryptedPushMessage: DecryptedPushMessage, signatureVerification: SignatureVerification, conversation: Conversation) {
|
||||||
|
@ -156,7 +156,11 @@ fun createOkHttpClient(
|
|||||||
var response = chain.proceed(chain.request())
|
var response = chain.proceed(chain.request())
|
||||||
|
|
||||||
if (response.request().url().encodedPath().contains("/avatar/")) {
|
if (response.request().url().encodedPath().contains("/avatar/")) {
|
||||||
AvatarStatusCodeHolder.getInstance().statusCode = response.code()
|
if (response.header("x-nc-iscustomavatar", "0") == "1") {
|
||||||
|
AvatarStatusCodeHolder.getInstance().statusCode = response.code()
|
||||||
|
} else {
|
||||||
|
AvatarStatusCodeHolder.getInstance().statusCode = response.code()
|
||||||
|
}
|
||||||
|
|
||||||
if (response.code() == 201) {
|
if (response.code() == 201) {
|
||||||
response = response.newBuilder().code(200).message("OK").build()
|
response = response.newBuilder().code(200).message("OK").build()
|
||||||
|
@ -76,8 +76,17 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
|||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
intent?.let {
|
intent?.let {
|
||||||
if (it.action == BundleKeys.KEY_INCOMING_PUSH_MESSSAGE) {
|
if (it.action == BundleKeys.KEY_SHOW_INCOMING_CALL) {
|
||||||
decryptMessage(it.getStringExtra(BundleKeys.KEY_ENCRYPTED_SUBJECT), it.getStringExtra(BundleKeys.KEY_ENCRYPTED_SIGNATURE))
|
val decryptedPushMessageString: String = it.getStringExtra(BundleKeys.KEY_DECRYPTED_PUSH_MESSAGE)!!
|
||||||
|
val signatureVerificationString: String = it.getStringExtra(BundleKeys.KEY_SIGNATURE_VERIFICATION)!!
|
||||||
|
val conversationString: String = it.getStringExtra(BundleKeys.KEY_CONVERSATION)!!
|
||||||
|
|
||||||
|
val json = Json(MagicJson.customJsonConfiguration)
|
||||||
|
val decryptedPushMessage = LoganSquare.parse(decryptedPushMessageString, DecryptedPushMessage::class.java)
|
||||||
|
val signatureVerification = json.parse(SignatureVerification.serializer(), signatureVerificationString)
|
||||||
|
val conversation = json.parse(Conversation.serializer(), conversationString)
|
||||||
|
|
||||||
|
showIncomingCall(signatureVerification, decryptedPushMessage, conversation)
|
||||||
} else if (it.action == BundleKeys.KEY_REJECT_INCOMING_CALL || it.action == BundleKeys.DISMISS_CALL_NOTIFICATION) {
|
} else if (it.action == BundleKeys.KEY_REJECT_INCOMING_CALL || it.action == BundleKeys.DISMISS_CALL_NOTIFICATION) {
|
||||||
if (it.getStringExtra(BundleKeys.KEY_ACTIVE_NOTIFICATION) == activeNotification) {
|
if (it.getStringExtra(BundleKeys.KEY_ACTIVE_NOTIFICATION) == activeNotification) {
|
||||||
endIncomingConversation(it.action != BundleKeys.DISMISS_CALL_NOTIFICATION)
|
endIncomingConversation(it.action != BundleKeys.DISMISS_CALL_NOTIFICATION)
|
||||||
@ -92,133 +101,74 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun decryptMessage(subject: String, signature: String) = coroutineContext.run {
|
private fun showIncomingCall(signatureVerification: SignatureVerification, decryptedPushMessage: DecryptedPushMessage, conversation: Conversation) {
|
||||||
launch {
|
val generatedActiveNotificationId = signatureVerification.userEntity!!.id.toString() + "@" + decryptedPushMessage.notificationId!!.toString()
|
||||||
val signatureVerification: SignatureVerification
|
val fullScreenPendingIntent = NotificationUtils.getIncomingCallIPendingIntent(applicationContext, this@CallService, conversation, signatureVerification.userEntity!!, generatedActiveNotificationId)
|
||||||
val decryptedPushMessage: DecryptedPushMessage
|
|
||||||
|
|
||||||
try {
|
val soundUri = NotificationUtils.getCallSoundUri(applicationContext, appPreferences)
|
||||||
val base64DecodedSubject = Base64.decode(subject, Base64.DEFAULT)
|
val vibrationEffect = NotificationUtils.getVibrationEffect(appPreferences)
|
||||||
val base64DecodedSignature = Base64.decode(signature, Base64.DEFAULT)
|
|
||||||
val pushUtils = PushUtils(usersRepository)
|
|
||||||
val privateKey = pushUtils.readKeyFromFile(false) as PrivateKey
|
|
||||||
try {
|
|
||||||
signatureVerification = pushUtils.verifySignature(base64DecodedSignature, base64DecodedSubject)
|
|
||||||
if (signatureVerification.signatureValid) {
|
|
||||||
val cipher = Cipher.getInstance("RSA/None/PKCS1Padding")
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey)
|
|
||||||
val decryptedSubject = cipher.doFinal(base64DecodedSubject)
|
|
||||||
decryptedPushMessage = LoganSquare.parse(String(decryptedSubject), DecryptedPushMessage::class.java)
|
|
||||||
val conversation = getConversationForTokenAndUser(signatureVerification.userEntity!!, decryptedPushMessage.id!!)
|
|
||||||
|
|
||||||
decryptedPushMessage.apply {
|
val notificationChannelId = NotificationUtils.getNotificationChannelId(applicationContext, applicationContext.resources
|
||||||
when {
|
.getString(R.string.nc_notification_channel_calls), applicationContext.resources
|
||||||
delete -> {
|
.getString(R.string.nc_notification_channel_calls_description), true,
|
||||||
NotificationUtils.cancelExistingNotificationWithId(applicationContext, signatureVerification.userEntity!!, notificationId!!)
|
NotificationManagerCompat.IMPORTANCE_HIGH, soundUri!!,
|
||||||
}
|
NotificationUtils.getCallAudioAttributes(true), vibrationEffect, false, null)
|
||||||
deleteAll -> {
|
|
||||||
NotificationUtils.cancelAllNotificationsForAccount(applicationContext, signatureVerification.userEntity!!)
|
|
||||||
}
|
|
||||||
type == "call" && (conversation?.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION || conversation?.objectType.equals("share:password")) -> {
|
|
||||||
if (conversation != null) {
|
|
||||||
val generatedActiveNotificationId = signatureVerification.userEntity!!.id.toString() + "@" + decryptedPushMessage.notificationId!!.toString()
|
|
||||||
val fullScreenPendingIntent = NotificationUtils.getIncomingCallIPendingIntent(applicationContext, this@CallService, conversation, signatureVerification.userEntity!!, generatedActiveNotificationId)
|
|
||||||
|
|
||||||
val soundUri = NotificationUtils.getCallSoundUri(applicationContext, appPreferences)
|
val uri: Uri = Uri.parse(signatureVerification.userEntity?.baseUrl)
|
||||||
val vibrationEffect = NotificationUtils.getVibrationEffect(appPreferences)
|
var baseUrl = uri.host
|
||||||
|
|
||||||
val notificationChannelId = NotificationUtils.getNotificationChannelId(applicationContext, applicationContext.resources
|
if (baseUrl == null) {
|
||||||
.getString(R.string.nc_notification_channel_calls), applicationContext.resources
|
baseUrl = signatureVerification.userEntity?.baseUrl
|
||||||
.getString(R.string.nc_notification_channel_calls_description), true,
|
}
|
||||||
NotificationManagerCompat.IMPORTANCE_HIGH, soundUri!!,
|
|
||||||
NotificationUtils.getCallAudioAttributes(true), vibrationEffect, false, null)
|
|
||||||
|
|
||||||
val uri: Uri = Uri.parse(signatureVerification.userEntity?.baseUrl)
|
var largeIcon = BitmapFactory.decodeResource(applicationContext.resources, R.drawable.ic_baseline_person_black_24)
|
||||||
var baseUrl = uri.host
|
|
||||||
|
|
||||||
if (baseUrl == null) {
|
val rejectCallIntent = Intent(this@CallService, CallService::class.java)
|
||||||
baseUrl = signatureVerification.userEntity?.baseUrl
|
rejectCallIntent.action = BundleKeys.KEY_REJECT_INCOMING_CALL
|
||||||
}
|
rejectCallIntent.putExtra(BundleKeys.KEY_ACTIVE_NOTIFICATION, generatedActiveNotificationId)
|
||||||
|
val rejectCallPendingIntent = PendingIntent.getService(this@CallService, 0, rejectCallIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
|
val notificationBuilder = NotificationCompat.Builder(this@CallService, notificationChannelId)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_CALL)
|
||||||
|
.setSmallIcon(R.drawable.ic_call_black_24dp)
|
||||||
|
.setLargeIcon(largeIcon)
|
||||||
|
.setSubText(baseUrl)
|
||||||
|
.setShowWhen(true)
|
||||||
|
.setWhen(System.currentTimeMillis())
|
||||||
|
.setContentTitle(EmojiCompat.get().process(decryptedPushMessage.subject.toString()))
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setOngoing(true)
|
||||||
|
.addAction(R.drawable.ic_call_end_white_24px, resources.getString(R.string.nc_reject_call), rejectCallPendingIntent)
|
||||||
|
.setContentIntent(fullScreenPendingIntent)
|
||||||
|
.setFullScreenIntent(fullScreenPendingIntent, true)
|
||||||
|
.setSound(NotificationUtils.getCallSoundUri(applicationContext, appPreferences), AudioManager.STREAM_RING)
|
||||||
|
|
||||||
var largeIcon = BitmapFactory.decodeResource(applicationContext.resources, R.drawable.ic_baseline_person_black_24)
|
if (vibrationEffect != null) {
|
||||||
|
notificationBuilder.setVibrate(vibrationEffect)
|
||||||
|
}
|
||||||
|
|
||||||
val rejectCallIntent = Intent(this@CallService, CallService::class.java)
|
val target = object : Target {
|
||||||
rejectCallIntent.action = BundleKeys.KEY_REJECT_INCOMING_CALL
|
override fun onSuccess(result: Drawable) {
|
||||||
rejectCallIntent.putExtra(BundleKeys.KEY_ACTIVE_NOTIFICATION, generatedActiveNotificationId)
|
super.onSuccess(result)
|
||||||
val rejectCallPendingIntent = PendingIntent.getService(this@CallService, 0, rejectCallIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
largeIcon = result.toBitmap()
|
||||||
val notificationBuilder = NotificationCompat.Builder(this@CallService, notificationChannelId)
|
notificationBuilder.setLargeIcon(largeIcon)
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
showNotification(notificationBuilder, signatureVerification.userEntity!!, conversation!!.token!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||||
.setCategory(NotificationCompat.CATEGORY_CALL)
|
}
|
||||||
.setSmallIcon(R.drawable.ic_call_black_24dp)
|
|
||||||
.setLargeIcon(largeIcon)
|
|
||||||
.setSubText(baseUrl)
|
|
||||||
.setShowWhen(true)
|
|
||||||
.setWhen(System.currentTimeMillis())
|
|
||||||
.setContentTitle(EmojiCompat.get().process(decryptedPushMessage.subject.toString()))
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setOngoing(true)
|
|
||||||
.addAction(R.drawable.ic_call_end_white_24px, resources.getString(R.string.nc_reject_call), rejectCallPendingIntent)
|
|
||||||
.setContentIntent(fullScreenPendingIntent)
|
|
||||||
.setFullScreenIntent(fullScreenPendingIntent, true)
|
|
||||||
.setSound(NotificationUtils.getCallSoundUri(applicationContext, appPreferences), AudioManager.STREAM_RING)
|
|
||||||
|
|
||||||
if (vibrationEffect != null) {
|
override fun onError(error: Drawable?) {
|
||||||
notificationBuilder.setVibrate(vibrationEffect)
|
super.onError(error)
|
||||||
}
|
showNotification(notificationBuilder, signatureVerification.userEntity!!, conversation!!.token!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||||
|
|
||||||
val target = object : Target {
|
|
||||||
override fun onSuccess(result: Drawable) {
|
|
||||||
super.onSuccess(result)
|
|
||||||
largeIcon = result.toBitmap()
|
|
||||||
notificationBuilder.setLargeIcon(largeIcon)
|
|
||||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, conversation.token!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(error: Drawable?) {
|
|
||||||
super.onError(error)
|
|
||||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, conversation.token!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val avatarUrl = ApiUtils.getUrlForAvatarWithName(signatureVerification.userEntity!!.baseUrl, conversation.name, R.dimen.avatar_size)
|
|
||||||
val imageLoader = networkComponents.getImageLoader(signatureVerification.userEntity!!.toUser())
|
|
||||||
|
|
||||||
val request = Images().getRequestForUrl(
|
|
||||||
imageLoader, applicationContext, avatarUrl, signatureVerification.userEntity!!.toUser(),
|
|
||||||
target, null, CircleCropTransformation())
|
|
||||||
|
|
||||||
imageLoader.load(request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
if (conversation != null) {
|
|
||||||
val json = Json(MagicJson.customJsonConfiguration)
|
|
||||||
|
|
||||||
val messageData = Data.Builder()
|
|
||||||
.putString(BundleKeys.KEY_DECRYPTED_PUSH_MESSAGE, LoganSquare.serialize(decryptedPushMessage))
|
|
||||||
.putString(BundleKeys.KEY_SIGNATURE_VERIFICATION, json.stringify(SignatureVerification.serializer(), signatureVerification))
|
|
||||||
.putString(BundleKeys.KEY_CONVERSATION, json.stringify(Conversation.serializer(), conversation))
|
|
||||||
.build()
|
|
||||||
val pushNotificationWork = OneTimeWorkRequest.Builder(NotificationWorker::class.java).setInputData(messageData).build()
|
|
||||||
WorkManager.getInstance().enqueue(pushNotificationWork)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// do absolutely nothing
|
|
||||||
}
|
|
||||||
} catch (e1: NoSuchAlgorithmException) {
|
|
||||||
Log.d(tag, "No proper algorithm to decrypt the message " + e1.localizedMessage)
|
|
||||||
} catch (e1: NoSuchPaddingException) {
|
|
||||||
Log.d(tag, "No proper padding to decrypt the message " + e1.localizedMessage)
|
|
||||||
} catch (e1: InvalidKeyException) {
|
|
||||||
Log.d(tag, "Invalid private key " + e1.localizedMessage)
|
|
||||||
}
|
|
||||||
} catch (exception: Exception) {
|
|
||||||
Log.d(tag, "Something went very wrong " + exception.localizedMessage)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val avatarUrl = ApiUtils.getUrlForAvatarWithName(signatureVerification.userEntity!!.baseUrl, conversation!!.name, R.dimen.avatar_size)
|
||||||
|
val imageLoader = networkComponents.getImageLoader(signatureVerification.userEntity!!.toUser())
|
||||||
|
|
||||||
|
val request = Images().getRequestForUrl(
|
||||||
|
imageLoader, applicationContext, avatarUrl, signatureVerification.userEntity!!.toUser(),
|
||||||
|
target, null, CircleCropTransformation())
|
||||||
|
|
||||||
|
imageLoader.load(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIsConversationActive(user: UserNgEntity, conversationToken: String, activeNotificationArgument: String) {
|
private fun checkIsConversationActive(user: UserNgEntity, conversationToken: String, activeNotificationArgument: String) {
|
||||||
@ -256,28 +206,6 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getConversationForTokenAndUser(user: UserNgEntity, conversationToken: String): Conversation? {
|
|
||||||
var conversation = conversationsRepository.getConversationForUserWithToken(user.id, conversationToken)
|
|
||||||
if (conversation == null) {
|
|
||||||
val getConversationUseCase = GetConversationUseCase(networkComponents.getRepository(false, user.toUser()), apiErrorHandler)
|
|
||||||
runBlocking {
|
|
||||||
getConversationUseCase.invoke(this, parametersOf(user, conversationToken), object : UseCaseResponse<ConversationOverall> {
|
|
||||||
override suspend fun onSuccess(result: ConversationOverall) {
|
|
||||||
val internalConversation = result.ocs.data
|
|
||||||
conversationsRepository.saveConversationsForUser(user.id, listOf(internalConversation), false)
|
|
||||||
conversation = result.ocs.data
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun onError(errorModel: ErrorModel?) {
|
|
||||||
conversation = null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return conversation
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showNotification(builder: NotificationCompat.Builder, user: UserNgEntity, conversationToken: String, internalNotificationId: Long, generatedNotificationId: String) {
|
private fun showNotification(builder: NotificationCompat.Builder, user: UserNgEntity, conversationToken: String, internalNotificationId: Long, generatedNotificationId: String) {
|
||||||
endIncomingConversation(true)
|
endIncomingConversation(true)
|
||||||
activeNotification = generatedNotificationId
|
activeNotification = generatedNotificationId
|
||||||
|
Loading…
Reference in New Issue
Block a user