Ensure that the SDK is syncing during an incoming call so that the application can detect if the call has been answered on another session.
This is dealing with the case the application is not in foreground.
This commit is contained in:
parent
126181a8b2
commit
6fc572d48e
6 changed files with 61 additions and 10 deletions
|
|
@ -93,13 +93,16 @@ class DefaultPushHandler @Inject constructor(
|
|||
when (resolvedPushEvent) {
|
||||
null -> Timber.tag(loggerTag.value).w("Unable to get a notification data")
|
||||
is ResolvedPushEvent.Event -> {
|
||||
when (resolvedPushEvent.notifiableEvent) {
|
||||
is NotifiableRingingCallEvent -> handleRingingCallEvent(resolvedPushEvent.notifiableEvent)
|
||||
when (val notifiableEvent = resolvedPushEvent.notifiableEvent) {
|
||||
is NotifiableRingingCallEvent -> {
|
||||
onNotifiableEventReceived.onNotifiableEventReceived(notifiableEvent)
|
||||
handleRingingCallEvent(notifiableEvent)
|
||||
}
|
||||
else -> {
|
||||
val userPushStore = userPushStoreFactory.getOrCreate(userId)
|
||||
val areNotificationsEnabled = userPushStore.getNotificationEnabledForDevice().first()
|
||||
if (areNotificationsEnabled) {
|
||||
onNotifiableEventReceived.onNotifiableEventReceived(resolvedPushEvent.notifiableEvent)
|
||||
onNotifiableEventReceived.onNotifiableEventReceived(notifiableEvent)
|
||||
} else {
|
||||
Timber.tag(loggerTag.value).i("Notification are disabled for this device, ignore push.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import com.squareup.anvil.annotations.ContributesBinding
|
|||
import io.element.android.libraries.di.AppScope
|
||||
import io.element.android.libraries.push.impl.notifications.DefaultNotificationDrawerManager
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
|
@ -28,7 +29,9 @@ class DefaultOnNotifiableEventReceived @Inject constructor(
|
|||
override fun onNotifiableEventReceived(notifiableEvent: NotifiableEvent) {
|
||||
coroutineScope.launch {
|
||||
launch { syncOnNotifiableEvent(notifiableEvent) }
|
||||
defaultNotificationDrawerManager.onNotifiableEventReceived(notifiableEvent)
|
||||
if (notifiableEvent !is NotifiableRingingCallEvent) {
|
||||
defaultNotificationDrawerManager.onNotifiableEventReceived(notifiableEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
|
|||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableRingingCallEvent
|
||||
import io.element.android.services.appnavstate.api.AppForegroundStateService
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.withContext
|
||||
|
|
@ -34,7 +35,8 @@ class SyncOnNotifiableEvent @Inject constructor(
|
|||
private var syncCounter = AtomicInteger(0)
|
||||
|
||||
suspend operator fun invoke(notifiableEvent: NotifiableEvent) = withContext(dispatchers.io) {
|
||||
if (!featureFlagService.isFeatureEnabled(FeatureFlags.SyncOnPush)) {
|
||||
val isRingingCallEvent = notifiableEvent is NotifiableRingingCallEvent
|
||||
if (!featureFlagService.isFeatureEnabled(FeatureFlags.SyncOnPush) && !isRingingCallEvent) {
|
||||
return@withContext
|
||||
}
|
||||
val client = matrixClientProvider.getOrRestore(notifiableEvent.sessionId).getOrNull() ?: return@withContext
|
||||
|
|
@ -45,12 +47,28 @@ class SyncOnNotifiableEvent @Inject constructor(
|
|||
if (!appForegroundStateService.isInForeground.value) {
|
||||
val syncService = client.syncService()
|
||||
syncService.startSyncIfNeeded()
|
||||
room.waitsUntilEventIsKnown(eventId = notifiableEvent.eventId, timeout = 10.seconds)
|
||||
if (isRingingCallEvent) {
|
||||
room.waitsUntilUserIsInTheCall(timeout = 60.seconds)
|
||||
} else {
|
||||
room.waitsUntilEventIsKnown(eventId = notifiableEvent.eventId, timeout = 10.seconds)
|
||||
}
|
||||
syncService.stopSyncIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User can be in the call if they answer using another session.
|
||||
* If the user does not join the call, the timeout will be reached.
|
||||
*/
|
||||
private suspend fun MatrixRoom.waitsUntilUserIsInTheCall(timeout: Duration) {
|
||||
withTimeoutOrNull(timeout) {
|
||||
roomInfoFlow.first {
|
||||
sessionId in it.activeRoomCallParticipants
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MatrixRoom.waitsUntilEventIsKnown(eventId: EventId, timeout: Duration) {
|
||||
withTimeoutOrNull(timeout) {
|
||||
liveTimeline.timelineItems.first { timelineItems ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue