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
20674dd535
commit
031ed226bf
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