Various bug fixes

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2020-05-09 14:49:22 +02:00
parent 8a661b355a
commit 371aa332c5
No known key found for this signature in database
GPG Key ID: CDE0BBD2738C4CC0
5 changed files with 201 additions and 168 deletions

View File

@ -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)
} }
} }

View File

@ -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)

View File

@ -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) {

View File

@ -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()

View File

@ -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