mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-21 20:49:36 +01:00
parent
cf8261fe4c
commit
0e8b0b8db0
@ -251,7 +251,7 @@ class MessageNotificationWorker(
|
||||
var notificationId = decryptedPushMessage.timestamp.toInt()
|
||||
|
||||
val notificationInfoBundle = Bundle()
|
||||
notificationInfoBundle.putLong(BundleKeys.KEY_INTERNAL_USER_ID, signatureVerification.userEntity!!.id!!)
|
||||
notificationInfoBundle.putLong(BundleKeys.KEY_INTERNAL_USER_ID, signatureVerification.userEntity!!.id)
|
||||
notificationInfoBundle.putString(BundleKeys.KEY_CONVERSATION_TOKEN, decryptedPushMessage.id)
|
||||
notificationInfoBundle.putLong(BundleKeys.KEY_NOTIFICATION_ID, decryptedPushMessage.notificationId!!)
|
||||
notificationBuilder.extras = notificationInfoBundle
|
||||
|
@ -83,8 +83,8 @@ class ConversationsRepositoryImpl(val conversationsDao: ConversationsDao) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getConversationForUserWithToken(userId: Long, token: String): Conversation? {
|
||||
val conversationEntity = conversationsDao.getConversationForUserWithToken(userId, token)
|
||||
override suspend fun getConversationForUserWithToken(internalUserId: Long, token: String): Conversation? {
|
||||
val conversationEntity = conversationsDao.getConversationForUserWithToken(internalUserId, token)
|
||||
if (conversationEntity != null) {
|
||||
return conversationEntity.toConversation()
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ class NextcloudTalkRepositoryImpl(private val apiService: ApiService) : Nextclou
|
||||
return apiService.getNotification(user.getCredentials(), ApiUtils.getUrlForNotificationWithId(user.baseUrl, notificationId))
|
||||
}
|
||||
|
||||
override suspend fun getPeersForCall(user: UserNgEntity, conversationToken: String): ParticipantsOverall {
|
||||
override suspend fun getParticipantsForCall(user: UserNgEntity, conversationToken: String): ParticipantsOverall {
|
||||
return apiService.getPeersForCall(user.getCredentials(), ApiUtils.getUrlForCall(user.baseUrl, conversationToken))
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ val UseCasesModule = module {
|
||||
single { createCreateConversationUseCase(get(), get()) }
|
||||
single { createAddParticipantToConversationUseCase(get(), get()) }
|
||||
single { setConversationPasswordUseCase(get(), get()) }
|
||||
factory { getPeersForCallUseCase(get(), get()) }
|
||||
factory { getParticipantsForCallUseCase(get(), get()) }
|
||||
factory { getNotificationUseCase(get(), get()) }
|
||||
factory { createChatViewModelFactory(get(), get(), get(), get(), get(), get()) }
|
||||
}
|
||||
@ -61,9 +61,9 @@ fun getNotificationUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||
return GetNotificationUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||
}
|
||||
|
||||
fun getPeersForCallUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||
apiErrorHandler: ApiErrorHandler): GetPeersForCallUseCase {
|
||||
return GetPeersForCallUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||
fun getParticipantsForCallUseCase(nextcloudTalkRepository: NextcloudTalkRepository,
|
||||
apiErrorHandler: ApiErrorHandler): GetParticipantsForCallUseCase {
|
||||
return GetParticipantsForCallUseCase(nextcloudTalkRepository, apiErrorHandler)
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@ import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
interface ConversationsRepository {
|
||||
fun getConversationsForUser(userId: Long, filter: CharSequence?): LiveData<List<Conversation>>
|
||||
fun getShortcutTargetConversations(userId: Long): LiveData<List<Conversation>>
|
||||
suspend fun getConversationForUserWithToken(userId: Long, token: String): Conversation?
|
||||
suspend fun getConversationForUserWithToken(internalUserId: Long, token: String): Conversation?
|
||||
suspend fun clearConversationsForUser(userId: Long)
|
||||
suspend fun saveConversationsForUser(
|
||||
userId: Long,
|
||||
|
@ -37,7 +37,7 @@ import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||
|
||||
interface NextcloudTalkRepository {
|
||||
suspend fun getNotificationForUser(user: UserNgEntity, notificationId: String): NotificationOverall
|
||||
suspend fun getPeersForCall(user: UserNgEntity, conversationToken: String): ParticipantsOverall
|
||||
suspend fun getParticipantsForCall(user: UserNgEntity, conversationToken: String): ParticipantsOverall
|
||||
suspend fun setPasswordForConversation(user: UserNgEntity, conversationToken: String, password: String): GenericOverall
|
||||
suspend fun addParticipantToConversation(user: UserNgEntity, conversationToken: String, participantId: String, source: String): AddParticipantOverall
|
||||
suspend fun createConversationForUser(user: UserNgEntity, conversationType: Int, invite: String?, source: String?, conversationName: String?): ConversationOverall
|
||||
|
@ -28,12 +28,12 @@ import com.nextcloud.talk.newarch.domain.repository.online.NextcloudTalkReposito
|
||||
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
|
||||
import org.koin.core.parameter.DefinitionParameters
|
||||
|
||||
class GetPeersForCallUseCase constructor(
|
||||
class GetParticipantsForCallUseCase constructor(
|
||||
private val nextcloudTalkRepository: NextcloudTalkRepository,
|
||||
apiErrorHandler: ApiErrorHandler?
|
||||
) : UseCase<ParticipantsOverall, Any?>(apiErrorHandler) {
|
||||
override suspend fun run(params: Any?): ParticipantsOverall {
|
||||
val definitionParameters = params as DefinitionParameters
|
||||
return nextcloudTalkRepository.getPeersForCall(definitionParameters[0], definitionParameters[1])
|
||||
return nextcloudTalkRepository.getParticipantsForCall(definitionParameters[0], definitionParameters[1])
|
||||
}
|
||||
}
|
@ -80,8 +80,8 @@ abstract class ConversationsDao {
|
||||
timestamp: Long
|
||||
)
|
||||
|
||||
@Query("SELECT * FROM conversations where id = :userId AND token = :token")
|
||||
abstract suspend fun getConversationForUserWithToken(userId: Long, token: String): ConversationEntity?
|
||||
@Query("SELECT * FROM conversations where id = :internalUserId AND token = :token")
|
||||
abstract suspend fun getConversationForUserWithToken(internalUserId: Long, token: String): ConversationEntity?
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateConversationsForUser(
|
||||
|
@ -10,6 +10,7 @@ import android.media.AudioAttributes
|
||||
import android.media.AudioManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
@ -30,12 +31,16 @@ import com.nextcloud.talk.jobs.MessageNotificationWorker
|
||||
import com.nextcloud.talk.models.SignatureVerification
|
||||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.models.json.conversations.ConversationOverall
|
||||
import com.nextcloud.talk.models.json.participants.Participant
|
||||
import com.nextcloud.talk.models.json.participants.ParticipantsOverall
|
||||
import com.nextcloud.talk.models.json.push.DecryptedPushMessage
|
||||
import com.nextcloud.talk.newarch.data.model.ErrorModel
|
||||
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.GetParticipantsForCallUseCase
|
||||
import com.nextcloud.talk.newarch.domain.usecases.base.UseCase
|
||||
import com.nextcloud.talk.newarch.domain.usecases.base.UseCaseResponse
|
||||
import com.nextcloud.talk.newarch.local.models.UserNgEntity
|
||||
import com.nextcloud.talk.newarch.utils.ComponentsWithEmptyCookieJar
|
||||
@ -57,8 +62,10 @@ import retrofit2.Retrofit
|
||||
import java.security.InvalidKeyException
|
||||
import java.security.NoSuchAlgorithmException
|
||||
import java.security.PrivateKey
|
||||
import java.util.*
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.NoSuchPaddingException
|
||||
import kotlin.concurrent.timerTask
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class CallService : Service(), KoinComponent, CoroutineScope {
|
||||
@ -83,12 +90,7 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
||||
decryptMessage(it.getStringExtra(BundleKeys.KEY_ENCRYPTED_SUBJECT), it.getStringExtra(BundleKeys.KEY_ENCRYPTED_SIGNATURE))
|
||||
} else if (it.action == BundleKeys.KEY_REJECT_INCOMING_CALL || it.action == BundleKeys.DISMISS_CALL_NOTIFICATION) {
|
||||
if (it.getStringExtra(BundleKeys.KEY_ACTIVE_NOTIFICATION) == activeNotification) {
|
||||
stopForeground(true)
|
||||
if (it.action != BundleKeys.DISMISS_CALL_NOTIFICATION) {
|
||||
eventBus.post(CallEvent())
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
endIncomingConversation(it.action != BundleKeys.DISMISS_CALL_NOTIFICATION)
|
||||
} else {
|
||||
// do nothing? :D
|
||||
}
|
||||
@ -184,7 +186,6 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
||||
.setAutoCancel(true)
|
||||
.setOngoing(true)
|
||||
.addAction(R.drawable.ic_call_end_white_24px, resources.getString(R.string.reject_call), rejectCallPendingIntent)
|
||||
//.setTimeoutAfter(45000L)
|
||||
.setContentIntent(fullScreenPendingIntent)
|
||||
.setFullScreenIntent(fullScreenPendingIntent, true)
|
||||
.setSound(NotificationUtils.getCallSoundUri(applicationContext, appPreferences), AudioManager.STREAM_RING)
|
||||
@ -193,20 +194,18 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
||||
notificationBuilder.setVibrate(vibrationEffect)
|
||||
}
|
||||
|
||||
//checkIfCallIsActive(signatureVerification, decryptedPushMessage)
|
||||
|
||||
if (conversation.type == Conversation.ConversationType.ONE_TO_ONE_CONVERSATION) {
|
||||
val target = object : Target {
|
||||
override fun onSuccess(result: Drawable) {
|
||||
super.onSuccess(result)
|
||||
largeIcon = result.toBitmap()
|
||||
notificationBuilder.setLargeIcon(largeIcon)
|
||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, conversation.token!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||
}
|
||||
|
||||
override fun onError(error: Drawable?) {
|
||||
super.onError(error)
|
||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, conversation.token!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +218,7 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
||||
|
||||
imageLoader.load(request)
|
||||
} else {
|
||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||
showNotification(notificationBuilder, signatureVerification.userEntity!!, conversation.token!!, decryptedPushMessage.notificationId!!, generatedActiveNotificationId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -253,6 +252,41 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIsConversationActive(user: UserNgEntity, conversationToken: String, activeNotificationArgument: String) {
|
||||
if (activeNotificationArgument == activeNotification) {
|
||||
val getParticipantsForCallUseCase = GetParticipantsForCallUseCase(componentsWithEmptyCookieJar.getRepository(), apiErrorHandler)
|
||||
getParticipantsForCallUseCase.invoke(this, parametersOf(user, conversationToken), object : UseCaseResponse<ParticipantsOverall> {
|
||||
override suspend fun onSuccess(result: ParticipantsOverall) {
|
||||
val participants = result.ocs.data
|
||||
if (participants.size > 0 && activeNotificationArgument == activeNotification) {
|
||||
val activeParticipants = participants.filter { it.participantFlags != Participant.ParticipantFlags.NOT_IN_CALL }
|
||||
val activeOnAnotherDevice = activeParticipants.filter { it.userId == user.userId }
|
||||
if (activeParticipants.isNotEmpty() && activeOnAnotherDevice.isEmpty()) {
|
||||
delay(5000)
|
||||
checkIsConversationActive(user, conversationToken, activeNotificationArgument)
|
||||
} else {
|
||||
endIncomingConversation(true)
|
||||
}
|
||||
} else if (activeNotificationArgument == activeNotification) {
|
||||
endIncomingConversation(true)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun onError(errorModel: ErrorModel?) {
|
||||
endIncomingConversation(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun endIncomingConversation(triggerEventBus : Boolean) {
|
||||
activeNotification = ""
|
||||
stopForeground(true)
|
||||
if (triggerEventBus) {
|
||||
eventBus.post(CallEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getConversationForTokenAndUser(user: UserNgEntity, conversationToken: String): Conversation? {
|
||||
var conversation = conversationsRepository.getConversationForUserWithToken(user.id, conversationToken)
|
||||
if (conversation == null) {
|
||||
@ -275,13 +309,15 @@ class CallService : Service(), KoinComponent, CoroutineScope {
|
||||
return conversation
|
||||
}
|
||||
|
||||
private fun showNotification(builder: NotificationCompat.Builder, user: UserNgEntity, internalNotificationId: Long, generatedNotificationId: String) {
|
||||
private fun showNotification(builder: NotificationCompat.Builder, user: UserNgEntity, conversationToken: String, internalNotificationId: Long, generatedNotificationId: String) {
|
||||
endIncomingConversation(true)
|
||||
activeNotification = generatedNotificationId
|
||||
val notification = builder.build()
|
||||
notification.extras.putLong(BundleKeys.KEY_INTERNAL_USER_ID, user.id)
|
||||
notification.extras.putLong(BundleKeys.KEY_NOTIFICATION_ID, internalNotificationId)
|
||||
notification.flags = notification.flags or Notification.FLAG_INSISTENT
|
||||
startForeground(generatedNotificationId.hashCode(), notification)
|
||||
checkIsConversationActive(user, conversationToken, generatedNotificationId)
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
|
Loading…
Reference in New Issue
Block a user