keeping an inmemory cache of the seen ids, fixes delayed sync responses causing already dismissed notifications from being shown again

- uses a simple circular buffer to limit the memory usage
This commit is contained in:
Adam Brown 2021-10-13 15:36:37 +01:00
parent 4f51dbdcf9
commit f2da047720
2 changed files with 52 additions and 3 deletions

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.notifications
/**
* A FIFO circular buffer of strings
*/
class CircularStringCache(cacheSize: Int) {
private val cache = Array(cacheSize) { "" }
private var writeIndex = 0
fun contains(key: String): Boolean = cache.contains(key)
fun put(key: String) {
if (writeIndex == cache.size - 1) {
writeIndex = 0
}
cache[writeIndex] = key
writeIndex++
}
}

View File

@ -84,6 +84,13 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
private var useCompleteNotificationFormat = vectorPreferences.useCompleteNotificationFormat()
/**
* An in memory FIFO cache of the seen events.
* Acts as a notification debouncer to stop already dismissed push notifications from
* displaying again when the /sync response is delayed.
*/
private val seenEventIds = CircularStringCache(cacheSize = 25)
/**
Should be called as soon as a new event is ready to be displayed.
The notification corresponding to this event will not be displayed until
@ -139,13 +146,19 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
} else {
// Ignore an edit of a not displayed event in the notification drawer
}
} else {
if (seenEventIds.contains(notifiableEvent.eventId)) {
// we've already seen the event, lets' skip
Timber.d("onNotifiableEventReceived(): skipping event, already seen}")
} else {
// Not an edit
seenEventIds.put(notifiableEvent.eventId)
eventList.add(notifiableEvent)
}
}
}
}
}
fun onEventRedacted(eventId: String) {
synchronized(eventList) {