Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2020-02-13 12:36:51 +01:00
parent d75e84c1fa
commit 550eba9de4
No known key found for this signature in database
GPG Key ID: CDE0BBD2738C4CC0
2 changed files with 0 additions and 782 deletions

View File

@ -1,70 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs
import android.content.Context
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.models.RetrofitBucket
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SELECTED_GROUPS
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SELECTED_USERS
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_TOKEN
import io.reactivex.schedulers.Schedulers
import org.greenrobot.eventbus.EventBus
import org.koin.core.KoinComponent
import org.koin.core.inject
class AddParticipantsToConversation(context: Context,
workerParams: WorkerParameters) : CoroutineWorker(context, workerParams), KoinComponent {
val ncApi: NcApi by inject()
val eventBus: EventBus by inject()
val usersRepository: UsersRepository by inject()
override suspend fun doWork(): Result {
val data = inputData
val selectedUserIds = data.getStringArray(KEY_SELECTED_USERS)
val selectedGroupIds = data.getStringArray(KEY_SELECTED_GROUPS)
val user = usersRepository.getUserWithId(data.getLong(KEY_INTERNAL_USER_ID, -1))
val conversationToken = data.getString(KEY_TOKEN)
val credentials = ApiUtils.getCredentials(user.username, user.token)
var retrofitBucket: RetrofitBucket
for (userId in selectedUserIds!!) {
retrofitBucket = ApiUtils.getRetrofitBucketForAddParticipant(user.baseUrl, conversationToken,
userId)
ncApi.addParticipant(credentials, retrofitBucket.url, retrofitBucket.queryMap)
.subscribeOn(Schedulers.io())
.blockingSubscribe()
}
for (groupId in selectedGroupIds!!) {
retrofitBucket = ApiUtils.getRetrofitBucketForAddGroupParticipant(user.baseUrl, conversationToken,
groupId)
ncApi.addParticipant(credentials, retrofitBucket.url, retrofitBucket.queryMap)
.subscribeOn(Schedulers.io())
.blockingSubscribe()
}
eventBus.post(EventStatus(user.id!!, EventStatus.EventType.PARTICIPANTS_UPDATE, true))
return Result.success()
}
}

View File

@ -1,712 +0,0 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.jobs
import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.Drawable
import android.media.AudioAttributes
import android.media.MediaPlayer
import android.net.Uri
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.Bundle
import android.os.VibrationEffect
import android.os.Vibrator
import android.text.TextUtils
import android.util.Base64
import android.util.Log
import androidx.core.app.NotificationCompat.Builder
import androidx.core.app.NotificationCompat.MessagingStyle
import androidx.core.app.NotificationCompat.MessagingStyle.Message
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.Person
import androidx.core.graphics.drawable.IconCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.emoji.text.EmojiCompat
import androidx.work.Worker
import androidx.work.WorkerParameters
import coil.Coil
import coil.target.Target
import coil.transform.CircleCropTransformation
import com.bluelinelabs.logansquare.LoganSquare
import com.nextcloud.talk.R.*
import com.nextcloud.talk.activities.MagicCallActivity
import com.nextcloud.talk.activities.MainActivity
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.models.RingtoneSettings
import com.nextcloud.talk.models.SignatureVerification
import com.nextcloud.talk.models.database.ArbitraryStorageEntity
import com.nextcloud.talk.models.json.chat.ChatUtils
import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.GROUP_CONVERSATION
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.ONE_TO_ONE_CONVERSATION
import com.nextcloud.talk.models.json.conversations.ConversationOverall
import com.nextcloud.talk.models.json.notifications.NotificationOverall
import com.nextcloud.talk.models.json.push.DecryptedPushMessage
import com.nextcloud.talk.models.json.push.NotificationUser
import com.nextcloud.talk.newarch.domain.repository.offline.UsersRepository
import com.nextcloud.talk.newarch.local.models.UserNgEntity
import com.nextcloud.talk.newarch.local.models.getCredentials
import com.nextcloud.talk.newarch.utils.Images
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DoNotDisturbUtils.isDnDActive
import com.nextcloud.talk.utils.DoNotDisturbUtils.isInDoNotDisturbWithPriority
import com.nextcloud.talk.utils.DoNotDisturbUtils.shouldPlaySound
import com.nextcloud.talk.utils.DoNotDisturbUtils.shouldVibrate
import com.nextcloud.talk.utils.NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V3
import com.nextcloud.talk.utils.NotificationUtils.NOTIFICATION_CHANNEL_MESSAGES_V3
import com.nextcloud.talk.utils.NotificationUtils.cancelAllNotificationsForAccount
import com.nextcloud.talk.utils.NotificationUtils.cancelExistingNotificationWithId
import com.nextcloud.talk.utils.NotificationUtils.createNotificationChannel
import com.nextcloud.talk.utils.NotificationUtils.findNotificationForRoom
import com.nextcloud.talk.utils.PushUtils
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_SIGNATURE
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_SUBJECT
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageUtils
import com.nextcloud.talk.utils.preferences.AppPreferences
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import okhttp3.JavaNetCookieJar
import okhttp3.OkHttpClient
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.parceler.Parcels
import retrofit2.Retrofit
import java.io.IOException
import java.net.CookieManager
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException
import java.security.PrivateKey
import java.util.*
import java.util.function.Consumer
import java.util.zip.CRC32
import javax.crypto.Cipher
import javax.crypto.NoSuchPaddingException
class NotificationWorker(
context: Context,
workerParams: WorkerParameters
) : Worker(context, workerParams), KoinComponent {
val appPreferences: AppPreferences by inject()
val retrofit: Retrofit by inject()
val okHttpClient: OkHttpClient by inject()
val usersRepository: UsersRepository by inject()
val arbitraryStorageUtils: ArbitraryStorageUtils by inject()
private var ncApi: NcApi? = null
private var decryptedPushMessage: DecryptedPushMessage? = null
private var context: Context? = null
private var signatureVerification: SignatureVerification? = null
private var conversationType: String? = "one2one"
private var credentials: String? = null
private var muteCall = false
private var importantConversation = false
private fun showNotificationForCallWithNoPing(intent: Intent) {
val userEntity: UserNgEntity =
signatureVerification!!.userEntity
var arbitraryStorageEntity: ArbitraryStorageEntity?
arbitraryStorageEntity = arbitraryStorageUtils.getStorageSetting(
userEntity.id!!,
"mute_calls",
intent.extras!!.getString(KEY_CONVERSATION_TOKEN)
)
if (arbitraryStorageEntity != null) {
muteCall = arbitraryStorageEntity.value!!.toBoolean()
}
arbitraryStorageEntity = arbitraryStorageUtils.getStorageSetting(
userEntity.id!!,
"important_conversation",
intent.extras!!.getString(KEY_CONVERSATION_TOKEN)
)
if (arbitraryStorageEntity != null) {
importantConversation = arbitraryStorageEntity.value!!.toBoolean()
}
if (isDnDActive()) {
if (!isInDoNotDisturbWithPriority()
|| !importantConversation
|| muteCall
) {
return
}
}
ncApi!!.getRoom(
credentials, ApiUtils.getRoom(
userEntity.baseUrl,
intent.extras!!.getString(KEY_CONVERSATION_TOKEN)
)
)
.blockingSubscribe(object : Observer<ConversationOverall?> {
override fun onSubscribe(d: Disposable) {}
override fun onNext(conversationOverall: ConversationOverall) {
val conversation: Conversation =
conversationOverall.ocs.data
intent.putExtra(
KEY_ROOM,
Parcels.wrap(
conversation
)
)
if ((conversation.type
== ONE_TO_ONE_CONVERSATION) ||
!TextUtils.isEmpty(
conversation.objectType
) && "share:password" == conversation.objectType
) {
context!!.startActivity(intent)
} else {
conversationType = if (conversation.type == GROUP_CONVERSATION) {
"group"
} else {
"public"
}
if (decryptedPushMessage!!.notificationId != Long.MIN_VALUE) {
showNotificationWithObjectData(intent)
} else {
showNotification(intent)
}
}
}
override fun onError(e: Throwable) {}
override fun onComplete() {}
})
}
private fun showNotificationWithObjectData(intent: Intent) {
val userEntity: UserNgEntity =
signatureVerification!!.userEntity
ncApi!!.getNotification(
credentials, ApiUtils.getUrlForNotificationWithId(
userEntity.baseUrl,
decryptedPushMessage!!.notificationId.toString()
)
)
.blockingSubscribe(object : Observer<NotificationOverall?> {
override fun onSubscribe(d: Disposable) {}
override fun onNext(notificationOverall: NotificationOverall) {
val notification: com.nextcloud.talk.models.json.notifications.Notification =
notificationOverall.ocs
.notification
if (notification.messageRichParameters != null &&
notification.messageRichParameters.size > 0
) {
decryptedPushMessage!!.text = ChatUtils.getParsedMessage(
notification.messageRich,
notification.messageRichParameters
)
} else {
decryptedPushMessage!!.text = notification.message
}
val subjectRichParameters: HashMap<String, HashMap<String, String>>? =
notification
.subjectRichParameters
decryptedPushMessage!!.timestamp = notification.datetime.millis
if (subjectRichParameters != null && subjectRichParameters.size > 0) {
val callHashMap =
subjectRichParameters["call"]
val userHashMap =
subjectRichParameters["user"]
val guestHashMap =
subjectRichParameters["guest"]
if (callHashMap != null && callHashMap.size > 0 && callHashMap.containsKey(
"name"
)
) {
if (notification.objectType == "chat") {
decryptedPushMessage!!.subject = callHashMap["name"]
} else {
decryptedPushMessage!!.subject = notification.subject
}
if (callHashMap.containsKey("call-type")) {
conversationType = callHashMap["call-type"]
}
}
val notificationUser =
NotificationUser()
if (userHashMap != null && !userHashMap.isEmpty()) {
notificationUser.id = userHashMap["id"]
notificationUser.type = userHashMap["type"]
notificationUser.name = userHashMap["name"]
decryptedPushMessage!!.notificationUser = notificationUser
} else if (guestHashMap != null && !guestHashMap.isEmpty()) {
notificationUser.id = guestHashMap["id"]
notificationUser.type = guestHashMap["type"]
notificationUser.name = guestHashMap["name"]
decryptedPushMessage!!.notificationUser = notificationUser
}
}
showNotification(intent)
}
override fun onError(e: Throwable) {}
override fun onComplete() {}
})
}
private fun showNotification(intent: Intent) {
val smallIcon: Int
val largeIcon: Bitmap?
val category: String
val priority = Notification.PRIORITY_HIGH
smallIcon = drawable.ic_logo
category = if (decryptedPushMessage!!.type == "chat" || (decryptedPushMessage!!.type
== "room")
) {
Notification.CATEGORY_MESSAGE
} else {
Notification.CATEGORY_CALL
}
largeIcon = when (conversationType) {
"group" -> BitmapFactory.decodeResource(
context!!.resources,
drawable.ic_people_group_black_24px
)
"public" -> BitmapFactory.decodeResource(
context!!.resources, drawable.ic_link_black_24px
)
else -> // assuming one2one
if (decryptedPushMessage!!.type == "chat" || (decryptedPushMessage!!.type
== "room")
) {
BitmapFactory.decodeResource(
context!!.resources, drawable.ic_chat_black_24dp
)
} else {
BitmapFactory.decodeResource(
context!!.resources, drawable.ic_call_black_24dp
)
}
}
intent.action = System.currentTimeMillis()
.toString()
val pendingIntent: PendingIntent? = PendingIntent.getActivity(
context,
0, intent, 0
)
val uri: Uri =
Uri.parse(signatureVerification!!.userEntity.baseUrl)
val baseUrl = uri.host
val notificationBuilder: Builder =
Builder(context!!, "1")
.setLargeIcon(largeIcon)
.setSmallIcon(smallIcon)
.setCategory(category)
.setPriority(priority)
.setSubText(baseUrl)
.setWhen(decryptedPushMessage!!.timestamp)
.setShowWhen(true)
.setContentTitle(
EmojiCompat.get().process(decryptedPushMessage!!.subject)
)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
if (!TextUtils.isEmpty(decryptedPushMessage!!.text)) {
notificationBuilder.setContentText(
EmojiCompat.get().process(decryptedPushMessage!!.text)
)
}
if (VERSION.SDK_INT >= 23) {
// This method should exist since API 21, but some phones don't have it
// So as a safeguard, we don't use it until 23
notificationBuilder.color = context!!.resources.getColor(color.colorPrimary)
}
val notificationInfo = Bundle()
notificationInfo.putLong(
KEY_INTERNAL_USER_ID,
signatureVerification!!.userEntity.id!!
)
// could be an ID or a TOKEN
notificationInfo.putString(
KEY_CONVERSATION_TOKEN,
decryptedPushMessage!!.id
)
notificationInfo.putLong(
KEY_NOTIFICATION_ID,
decryptedPushMessage!!.notificationId
)
notificationBuilder.extras = notificationInfo
if (VERSION.SDK_INT >= VERSION_CODES.O) {
/*NotificationUtils.createNotificationChannelGroup(context,
Long.toString(crc32.getValue()),
groupName);*/
if (decryptedPushMessage!!.type == "chat" || (decryptedPushMessage!!.type
== "room")
) {
createNotificationChannel(
context!!,
NOTIFICATION_CHANNEL_MESSAGES_V3,
context!!.resources
.getString(string.nc_notification_channel_messages),
context!!.resources
.getString(string.nc_notification_channel_messages), true,
NotificationManager.IMPORTANCE_HIGH
)
notificationBuilder.setChannelId(
NOTIFICATION_CHANNEL_MESSAGES_V3
)
} else {
createNotificationChannel(
context!!,
NOTIFICATION_CHANNEL_CALLS_V3,
context!!.resources
.getString(string.nc_notification_channel_calls),
context!!.resources
.getString(string.nc_notification_channel_calls_description),
true,
NotificationManager.IMPORTANCE_HIGH
)
notificationBuilder.setChannelId(
NOTIFICATION_CHANNEL_CALLS_V3
)
}
} else {
// red color for the lights
notificationBuilder.setLights(-0x10000, 200, 200)
}
notificationBuilder.setContentIntent(pendingIntent)
var crc32 = CRC32()
val groupName =
signatureVerification!!.userEntity.id.toString() + "@" + decryptedPushMessage!!.id
crc32.update(groupName.toByteArray())
notificationBuilder.setGroup(crc32.value.toString())
// notificationId
crc32 = CRC32()
val stringForCrc = System.currentTimeMillis()
.toString()
crc32.update(stringForCrc.toByteArray())
val activeStatusBarNotification =
findNotificationForRoom(
context,
signatureVerification!!.userEntity, decryptedPushMessage!!.id
)
val notificationId: Int
notificationId = activeStatusBarNotification?.id ?: crc32.value.toInt()
if (VERSION.SDK_INT >= VERSION_CODES.N && decryptedPushMessage!!.notificationUser != null && decryptedPushMessage!!.type == "chat") {
var style: MessagingStyle? = null
if (activeStatusBarNotification != null) {
val activeNotification: Notification? =
activeStatusBarNotification.notification
style =
MessagingStyle.extractMessagingStyleFromNotification(
activeNotification
)
}
val person = Person.Builder()
.setKey(
signatureVerification!!.userEntity.id.toString() +
"@" + decryptedPushMessage!!.notificationUser.id
)
.setName(
EmojiCompat.get().process(
decryptedPushMessage!!.notificationUser.name
)
)
.setBot(decryptedPushMessage!!.notificationUser.type == "bot")
notificationBuilder.setOnlyAlertOnce(true)
if (decryptedPushMessage!!.notificationUser.type == "user" || decryptedPushMessage!!.notificationUser.type == "guest") {
var avatarUrl: String? = ApiUtils.getUrlForAvatarWithName(
signatureVerification!!.userEntity.baseUrl,
decryptedPushMessage!!.notificationUser.id,
dimen.avatar_size
)
if (decryptedPushMessage!!.notificationUser.type == "guest") {
avatarUrl = ApiUtils.getUrlForAvatarWithNameForGuests(
signatureVerification!!.userEntity.baseUrl,
decryptedPushMessage!!.notificationUser.name,
dimen.avatar_size
)
}
val target = object : Target {
override fun onSuccess(result: Drawable) {
super.onSuccess(result)
person.setIcon(IconCompat.createWithBitmap(result.toBitmap()))
notificationBuilder.setStyle(
getStyle(
person.build(),
style
)
)
sendNotificationWithId(notificationId, notificationBuilder.build())
}
override fun onError(error: Drawable?) {
super.onError(error)
notificationBuilder.setStyle(getStyle(person.build(), style))
sendNotificationWithId(notificationId, notificationBuilder.build())
}
}
val request = Images().getRequestForUrl(
Coil.loader(), context!!, avatarUrl!!, signatureVerification!!.userEntity,
target, null, CircleCropTransformation()
)
Coil.loader()
.load(request)
} else {
notificationBuilder.setStyle(getStyle(person.build(), style))
sendNotificationWithId(notificationId, notificationBuilder.build())
}
} else {
sendNotificationWithId(notificationId, notificationBuilder.build())
}
}
private fun sendNotificationWithId(
notificationId: Int,
notification: Notification
) {
val notificationManager =
NotificationManagerCompat.from(context!!)
notificationManager.notify(notificationId, notification)
if (notification.category != Notification.CATEGORY_CALL) {
val ringtonePreferencesString: String?
val soundUri: Uri?
ringtonePreferencesString = appPreferences.messageRingtoneUri
soundUri = if (TextUtils.isEmpty(ringtonePreferencesString)) {
Uri.parse(
"android.resource://" + context!!.packageName +
"/raw/librem_by_feandesign_message"
)
} else {
try {
val ringtoneSettings: RingtoneSettings =
LoganSquare.parse(
ringtonePreferencesString, RingtoneSettings::class.java
)
ringtoneSettings.ringtoneUri
} catch (exception: IOException) {
Uri.parse(
"android.resource://" + context!!.packageName +
"/raw/librem_by_feandesign_message"
)
}
}
if (soundUri != null && (shouldPlaySound(importantConversation))
) {
val audioAttributesBuilder: AudioAttributes.Builder =
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
if (decryptedPushMessage!!.type == "chat" || (decryptedPushMessage!!.type
== "room")
) {
audioAttributesBuilder.setUsage(
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT
)
} else {
audioAttributesBuilder.setUsage(
AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST
)
}
val mediaPlayer = MediaPlayer()
try {
mediaPlayer.setDataSource(context!!, soundUri)
mediaPlayer.setAudioAttributes(audioAttributesBuilder.build())
mediaPlayer.setOnPreparedListener { mp: MediaPlayer? -> mediaPlayer.start() }
mediaPlayer.setOnCompletionListener { obj: MediaPlayer -> obj.release() }
mediaPlayer.prepareAsync()
} catch (e: IOException) {
Log.e(TAG, "Failed to set data source")
}
}
if (shouldVibrate(appPreferences.shouldVibrateSetting)
) {
val vibrator =
context!!.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
if (VERSION.SDK_INT >= VERSION_CODES.O) {
vibrator.vibrate(
VibrationEffect.createOneShot(
500, VibrationEffect.DEFAULT_AMPLITUDE
)
)
} else {
vibrator.vibrate(500)
}
}
}
}
override fun doWork(): Result {
context = applicationContext
val data = inputData
val subject =
data.getString(KEY_NOTIFICATION_SUBJECT)
val signature =
data.getString(KEY_NOTIFICATION_SIGNATURE)
val base64DecodedSubject: ByteArray = Base64.decode(subject, Base64.DEFAULT)
val base64DecodedSignature: ByteArray = 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 = Cipher.getInstance("RSA/None/PKCS1Padding")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
val decryptedSubject: ByteArray? = cipher.doFinal(base64DecodedSubject)
decryptedPushMessage =
LoganSquare.parse(
decryptedSubject!!.toString(Charsets.UTF_8),
DecryptedPushMessage::class.java
)
decryptedPushMessage!!.timestamp = System.currentTimeMillis()
if (decryptedPushMessage!!.delete) {
cancelExistingNotificationWithId(
context,
signatureVerification!!.userEntity, decryptedPushMessage!!.notificationId
)
} else if (decryptedPushMessage!!.deleteAll) {
cancelAllNotificationsForAccount(
context,
signatureVerification!!.userEntity
)
} else {
credentials = signatureVerification!!.userEntity.getCredentials()
ncApi = retrofit.newBuilder()
.client(
okHttpClient.newBuilder().cookieJar(
JavaNetCookieJar(CookieManager())
).build()
)
.build()
.create(
NcApi::class.java
)
val hasChatSupport =
signatureVerification!!.userEntity.hasSpreedFeatureCapability("chat-v2")
val shouldShowNotification = decryptedPushMessage!!.app == "spreed"
if (shouldShowNotification) {
val intent: Intent
val bundle = Bundle()
val startACall =
decryptedPushMessage!!.type == "call" || !hasChatSupport
intent = if (startACall) {
Intent(
context, MagicCallActivity::class.java
)
} else {
Intent(
context, MainActivity::class.java
)
}
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
if (!signatureVerification!!.userEntity.hasSpreedFeatureCapability("no-ping")) {
bundle.putString(
KEY_ROOM_ID,
decryptedPushMessage!!.id
)
} else {
bundle.putString(
KEY_CONVERSATION_TOKEN,
decryptedPushMessage!!.id
)
}
bundle.putParcelable(
KEY_USER_ENTITY,
signatureVerification!!.userEntity
)
bundle.putBoolean(
KEY_FROM_NOTIFICATION_START_CALL,
startACall
)
intent.putExtras(bundle)
when (decryptedPushMessage!!.type) {
"call" -> if (!bundle.containsKey(
KEY_CONVERSATION_TOKEN
)
) {
context!!.startActivity(intent)
} else {
showNotificationForCallWithNoPing(intent)
}
"room" -> if (bundle.containsKey(
KEY_CONVERSATION_TOKEN
)
) {
showNotificationWithObjectData(intent)
}
"chat" -> if (decryptedPushMessage!!.notificationId != Long.MIN_VALUE) {
showNotificationWithObjectData(intent)
} else {
showNotification(intent)
}
else -> {
}
}
}
}
}
} 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
)
}
return Result.success()
}
companion object {
const val TAG = "NotificationWorker"
}
}