mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 16:22:49 +00:00
Merge pull request #7360 from hayaksi1/fix/7253-skip-other-account-notifications
Do not notify about an event sent by another account on the same device
This commit is contained in:
+21
-1
@@ -56,6 +56,7 @@ import io.element.android.libraries.push.impl.db.PushRequest
|
||||
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent
|
||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.services.toolbox.api.strings.StringProvider
|
||||
import timber.log.Timber
|
||||
@@ -94,6 +95,7 @@ class DefaultNotifiableEventResolver(
|
||||
private val callNotificationEventResolver: CallNotificationEventResolver,
|
||||
private val fallbackNotificationFactory: FallbackNotificationFactory,
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
private val sessionStore: SessionStore,
|
||||
) : NotifiableEventResolver {
|
||||
override suspend fun resolveEvents(
|
||||
sessionId: SessionId,
|
||||
@@ -117,10 +119,15 @@ class DefaultNotifiableEventResolver(
|
||||
return Result.failure(exception ?: NotificationResolverException.UnknownError("Unknown error while fetching notifications"))
|
||||
}
|
||||
|
||||
val otherSessionUserIds = sessionStore.getAllSessions()
|
||||
.map { UserId(it.userId) }
|
||||
.minus(sessionId)
|
||||
.toSet()
|
||||
|
||||
// The null check is done above
|
||||
val notificationDataMap = notificationsResult.getOrNull()!!.mapValues { (_, notificationData) ->
|
||||
notificationData.flatMap { data ->
|
||||
data.asNotifiableEvent(client, sessionId)
|
||||
data.asNotifiableEvent(client, sessionId, otherSessionUserIds)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,10 +143,23 @@ class DefaultNotifiableEventResolver(
|
||||
)
|
||||
}
|
||||
|
||||
private fun NotificationContent.senderIdOrNull(): UserId? = when (this) {
|
||||
is NotificationContent.MessageLike.RoomMessage -> senderId
|
||||
is NotificationContent.MessageLike.Poll -> senderId
|
||||
is NotificationContent.MessageLike.CallInvite -> senderId
|
||||
is NotificationContent.MessageLike.RtcNotification -> senderId
|
||||
is NotificationContent.Invite -> senderId
|
||||
else -> null
|
||||
}
|
||||
|
||||
private suspend fun NotificationData.asNotifiableEvent(
|
||||
client: MatrixClient,
|
||||
userId: SessionId,
|
||||
otherSessionUserIds: Set<UserId>,
|
||||
): Result<ResolvedPushEvent> = runCatchingExceptions {
|
||||
if (content.senderIdOrNull() in otherSessionUserIds) {
|
||||
throw NotificationResolverException.EventFilteredOut
|
||||
}
|
||||
when (val content = this.content) {
|
||||
is NotificationContent.MessageLike.RoomMessage -> {
|
||||
val showMediaPreview = client.mediaPreviewService.getMediaPreviewValue().isPreviewEnabled(roomJoinRule)
|
||||
|
||||
+111
@@ -39,6 +39,7 @@ import io.element.android.libraries.matrix.test.A_REDACTION_REASON
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_NAME
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID_2
|
||||
import io.element.android.libraries.matrix.test.A_SPACE_NAME
|
||||
import io.element.android.libraries.matrix.test.A_TIMESTAMP
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_2
|
||||
@@ -56,6 +57,9 @@ import io.element.android.libraries.push.impl.notifications.model.FallbackNotifi
|
||||
import io.element.android.libraries.push.impl.notifications.model.InviteNotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent
|
||||
import io.element.android.libraries.push.impl.notifications.model.ResolvedPushEvent
|
||||
import io.element.android.libraries.sessionstorage.api.SessionStore
|
||||
import io.element.android.libraries.sessionstorage.test.InMemorySessionStore
|
||||
import io.element.android.libraries.sessionstorage.test.aSessionData
|
||||
import io.element.android.services.toolbox.impl.strings.AndroidStringProvider
|
||||
import io.element.android.services.toolbox.test.systemclock.A_FAKE_TIMESTAMP
|
||||
import io.element.android.services.toolbox.test.systemclock.FakeSystemClock
|
||||
@@ -836,6 +840,111 @@ class DefaultNotifiableEventResolverTest : RobolectricTest() {
|
||||
assertThat(result.getEvent(request)?.getOrNull()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `resolve RoomMessage sent by another session on the same device is filtered out`() = runTest {
|
||||
val sut = createDefaultNotifiableEventResolver(
|
||||
notificationResult = Result.success(
|
||||
mapOf(
|
||||
AN_EVENT_ID to Result.success(
|
||||
aNotificationData(
|
||||
content = NotificationContent.MessageLike.RoomMessage(
|
||||
senderId = A_SESSION_ID_2,
|
||||
messageType = TextMessageType("Hello world", null),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
sessionStore = InMemorySessionStore(
|
||||
listOf(
|
||||
aSessionData(sessionId = A_SESSION_ID.value),
|
||||
aSessionData(sessionId = A_SESSION_ID_2.value),
|
||||
)
|
||||
),
|
||||
)
|
||||
val request = aPushRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase")
|
||||
val result = sut.resolveEvents(A_SESSION_ID, listOf(request))
|
||||
assertThat(result.getEvent(request)?.exceptionOrNull()).isEqualTo(NotificationResolverException.EventFilteredOut)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `resolve RtcNotification sent by another session on the same device is filtered out`() = runTest {
|
||||
val sut = createDefaultNotifiableEventResolver(
|
||||
notificationResult = Result.success(
|
||||
mapOf(
|
||||
AN_EVENT_ID to Result.success(
|
||||
aNotificationData(
|
||||
content = NotificationContent.MessageLike.RtcNotification(
|
||||
senderId = A_SESSION_ID_2,
|
||||
type = RtcNotificationType.RING,
|
||||
callIntent = CallIntent.AUDIO,
|
||||
expirationTimestampMillis = 0,
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
sessionStore = InMemorySessionStore(
|
||||
listOf(
|
||||
aSessionData(sessionId = A_SESSION_ID.value),
|
||||
aSessionData(sessionId = A_SESSION_ID_2.value),
|
||||
)
|
||||
),
|
||||
)
|
||||
val request = aPushRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase")
|
||||
val result = sut.resolveEvents(A_SESSION_ID, listOf(request))
|
||||
assertThat(result.getEvent(request)?.exceptionOrNull()).isEqualTo(NotificationResolverException.EventFilteredOut)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `resolve RoomMessage sent by a user who is not logged in is not filtered out`() = runTest {
|
||||
val sut = createDefaultNotifiableEventResolver(
|
||||
notificationResult = Result.success(
|
||||
mapOf(
|
||||
AN_EVENT_ID to Result.success(
|
||||
aNotificationData(
|
||||
content = NotificationContent.MessageLike.RoomMessage(
|
||||
senderId = A_SESSION_ID_2,
|
||||
messageType = TextMessageType("Hello world", null),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
sessionStore = InMemorySessionStore(listOf(aSessionData(sessionId = A_SESSION_ID.value))),
|
||||
)
|
||||
val request = aPushRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase")
|
||||
val result = sut.resolveEvents(A_SESSION_ID, listOf(request))
|
||||
assertThat(result.getEvent(request)?.isSuccess).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `resolve RoomMessage sent by the receiving session itself is not filtered out`() = runTest {
|
||||
val sut = createDefaultNotifiableEventResolver(
|
||||
notificationResult = Result.success(
|
||||
mapOf(
|
||||
AN_EVENT_ID to Result.success(
|
||||
aNotificationData(
|
||||
content = NotificationContent.MessageLike.RoomMessage(
|
||||
senderId = A_SESSION_ID,
|
||||
messageType = TextMessageType("Hello world", null),
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
sessionStore = InMemorySessionStore(
|
||||
listOf(
|
||||
aSessionData(sessionId = A_SESSION_ID.value),
|
||||
aSessionData(sessionId = A_SESSION_ID_2.value),
|
||||
)
|
||||
),
|
||||
)
|
||||
val request = aPushRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase")
|
||||
val result = sut.resolveEvents(A_SESSION_ID, listOf(request))
|
||||
assertThat(result.getEvent(request)?.isSuccess).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `resolve null cases`() {
|
||||
testNoResults(NotificationContent.MessageLike.CallAnswer)
|
||||
@@ -893,6 +1002,7 @@ class DefaultNotifiableEventResolverTest : RobolectricTest() {
|
||||
notificationService: FakeNotificationService? = FakeNotificationService(),
|
||||
notificationResult: Result<Map<EventId, Result<NotificationData>>> = Result.success(emptyMap()),
|
||||
callNotificationEventResolver: FakeCallNotificationEventResolver = FakeCallNotificationEventResolver(),
|
||||
sessionStore: SessionStore = InMemorySessionStore(),
|
||||
): DefaultNotifiableEventResolver {
|
||||
val context = RuntimeEnvironment.getApplication() as Context
|
||||
notificationService?.givenGetNotificationsResult(notificationResult)
|
||||
@@ -917,6 +1027,7 @@ class DefaultNotifiableEventResolverTest : RobolectricTest() {
|
||||
clock = FakeSystemClock(),
|
||||
),
|
||||
featureFlagService = FakeFeatureFlagService(),
|
||||
sessionStore = sessionStore,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user