updating the push gateway property to reflect that it mean the event can be replaced

- makes the property immutable as only the creation of the event knows if it can be replace eg it came from a push or the /sync event stream
This commit is contained in:
Adam Brown 2021-10-07 12:19:35 +01:00
parent b44a382893
commit 86b500445f
8 changed files with 22 additions and 22 deletions

View file

@ -29,16 +29,13 @@ import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.network.WifiDetector
import im.vector.app.core.pushers.PushersManager
import im.vector.app.features.badge.BadgeProxy
import im.vector.app.features.notifications.NotifiableEventResolver
import im.vector.app.features.notifications.NotifiableMessageEvent
import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.notifications.SimpleNotifiableEvent
import im.vector.app.features.settings.VectorDataStore
import im.vector.app.features.settings.VectorPreferences
import im.vector.app.push.fcm.FcmHelper
@ -48,9 +45,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.pushrules.Action
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.Event
import timber.log.Timber
import javax.inject.Inject
@ -201,12 +196,11 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
Timber.tag(loggerTag.value).d("Fast lane: start request")
val event = tryOrNull { session.getEvent(roomId, eventId) } ?: return@launch
val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event)
val resolvedEvent = notifiableEventResolver.resolveInMemoryEvent(session, event, canBeReplaced = true)
resolvedEvent
?.also { Timber.tag(loggerTag.value).d("Fast lane: notify drawer") }
?.let {
it.isPushGatewayEvent = true
notificationDrawerManager.onNotifiableEventReceived(it)
notificationDrawerManager.refreshNotificationDrawer()
}

View file

@ -19,6 +19,7 @@ data class InviteNotifiableEvent(
val matrixID: String?,
override val eventId: String,
override val editedEventId: String?,
override val canBeReplaced: Boolean,
val roomId: String,
val noisy: Boolean,
val title: String,
@ -29,6 +30,5 @@ data class InviteNotifiableEvent(
override val isRedacted: Boolean = false
) : NotifiableEvent {
override var isPushGatewayEvent: Boolean = false
override var hasBeenDisplayed = false
}

View file

@ -25,6 +25,6 @@ sealed interface NotifiableEvent : Serializable {
val editedEventId: String?
var hasBeenDisplayed: Boolean
// Used to know if event should be replaced with the one coming from eventstream
var isPushGatewayEvent: Boolean
val canBeReplaced: Boolean
val isRedacted: Boolean
}

View file

@ -57,15 +57,15 @@ class NotifiableEventResolver @Inject constructor(
val roomID = event.roomId ?: return null
val eventId = event.eventId ?: return null
if (event.getClearType() == EventType.STATE_ROOM_MEMBER) {
return resolveStateRoomEvent(event, session, isNoisy)
return resolveStateRoomEvent(event, session, canBeReplaced = false, isNoisy = isNoisy)
}
val timelineEvent = session.getRoom(roomID)?.getTimeLineEvent(eventId) ?: return null
when (event.getClearType()) {
EventType.MESSAGE -> {
return resolveMessageEvent(timelineEvent, session, isNoisy)
return resolveMessageEvent(timelineEvent, session, canBeReplaced = false, isNoisy = isNoisy)
}
EventType.ENCRYPTED -> {
return resolveMessageEvent(timelineEvent, session, isNoisy)
return resolveMessageEvent(timelineEvent, session, canBeReplaced = false, isNoisy = isNoisy)
}
else -> {
// If the event can be displayed, display it as is
@ -82,12 +82,14 @@ class NotifiableEventResolver @Inject constructor(
description = bodyPreview,
title = stringProvider.getString(R.string.notification_unknown_new_event),
soundName = null,
type = event.type)
type = event.type,
canBeReplaced = false
)
}
}
}
fun resolveInMemoryEvent(session: Session, event: Event): NotifiableEvent? {
fun resolveInMemoryEvent(session: Session, event: Event, canBeReplaced: Boolean): NotifiableEvent? {
if (event.getClearType() != EventType.MESSAGE) return null
// Ignore message edition
@ -111,14 +113,14 @@ class NotifiableEventResolver @Inject constructor(
avatarUrl = user.avatarUrl
)
)
resolveMessageEvent(timelineEvent, session, isNoisy = !notificationAction.soundName.isNullOrBlank())
resolveMessageEvent(timelineEvent, session, canBeReplaced = canBeReplaced, isNoisy = !notificationAction.soundName.isNullOrBlank())
} else {
Timber.d("Matched push rule is set to not notify")
null
}
}
private fun resolveMessageEvent(event: TimelineEvent, session: Session, isNoisy: Boolean): NotifiableEvent {
private fun resolveMessageEvent(event: TimelineEvent, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent {
// The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...)
val room = session.getRoom(event.root.roomId!! /*roomID cannot be null*/)
@ -132,6 +134,7 @@ class NotifiableEventResolver @Inject constructor(
return NotifiableMessageEvent(
eventId = event.root.eventId!!,
editedEventId = event.getEditedEventId(),
canBeReplaced = canBeReplaced,
timestamp = event.root.originServerTs ?: 0,
noisy = isNoisy,
senderName = senderDisplayName,
@ -164,6 +167,7 @@ class NotifiableEventResolver @Inject constructor(
return NotifiableMessageEvent(
eventId = event.root.eventId!!,
editedEventId = event.getEditedEventId(),
canBeReplaced = canBeReplaced,
timestamp = event.root.originServerTs ?: 0,
noisy = isNoisy,
senderName = senderDisplayName,
@ -188,7 +192,7 @@ class NotifiableEventResolver @Inject constructor(
}
}
private fun resolveStateRoomEvent(event: Event, session: Session, isNoisy: Boolean): NotifiableEvent? {
private fun resolveStateRoomEvent(event: Event, session: Session, canBeReplaced: Boolean, isNoisy: Boolean): NotifiableEvent? {
val content = event.content?.toModel<RoomMemberContent>() ?: return null
val roomId = event.roomId ?: return null
val dName = event.senderId?.let { session.getRoomMember(it, roomId)?.displayName }
@ -199,6 +203,7 @@ class NotifiableEventResolver @Inject constructor(
session.myUserId,
eventId = event.eventId!!,
editedEventId = null,
canBeReplaced = canBeReplaced,
roomId = roomId,
timestamp = event.originServerTs ?: 0,
noisy = isNoisy,

View file

@ -20,6 +20,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType
data class NotifiableMessageEvent(
override val eventId: String,
override val editedEventId: String?,
override val canBeReplaced: Boolean,
val noisy: Boolean,
val timestamp: Long,
val senderName: String?,
@ -38,7 +39,6 @@ data class NotifiableMessageEvent(
override val isRedacted: Boolean = false
) : NotifiableEvent {
override var isPushGatewayEvent: Boolean = false
override var hasBeenDisplayed: Boolean = false
val type: String = EventType.MESSAGE

View file

@ -141,7 +141,8 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
roomId = room.roomId,
roomName = room.roomSummary()?.displayName ?: room.roomId,
roomIsDirect = room.roomSummary()?.isDirect == true,
outGoingMessage = true
outGoingMessage = true,
canBeReplaced = false
)
notificationDrawerManager.onNotifiableEventReceived(notifiableMessageEvent)

View file

@ -107,12 +107,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
if (BuildConfig.LOW_PRIVACY_LOG_ENABLE) {
Timber.d("onNotifiableEventReceived(): $notifiableEvent")
} else {
Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.isPushGatewayEvent}")
Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.canBeReplaced}")
}
synchronized(eventList) {
val existing = eventList.firstOrNull { it.eventId == notifiableEvent.eventId }
if (existing != null) {
if (existing.isPushGatewayEvent) {
if (existing.canBeReplaced) {
// Use the event coming from the event stream as it may contains more info than
// the fcm one (like type/content/clear text) (e.g when an encrypted message from
// FCM should be update with clear text after a sync)

View file

@ -25,10 +25,10 @@ data class SimpleNotifiableEvent(
val type: String?,
val timestamp: Long,
val soundName: String?,
override var canBeReplaced: Boolean,
override val isRedacted: Boolean = false
) : NotifiableEvent {
override var isPushGatewayEvent: Boolean = false
override var hasBeenDisplayed: Boolean = false
}