From 40446c7a310a2c451356d29bd6fe20376bdf3819 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 9 Dec 2020 11:48:44 +0100 Subject: [PATCH] VoIP: introduce priority for in-app notification --- .../vector/app/core/services/CallService.kt | 4 -- .../app/features/popup/IncomingCallAlert.kt | 1 + .../app/features/popup/PopupAlertManager.kt | 44 ++++++++++++------- .../vector/app/features/popup/VectorAlert.kt | 4 ++ 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/services/CallService.kt b/vector/src/main/java/im/vector/app/core/services/CallService.kt index a0adcca496..1b8345491b 100644 --- a/vector/src/main/java/im/vector/app/core/services/CallService.kt +++ b/vector/src/main/java/im/vector/app/core/services/CallService.kt @@ -158,10 +158,6 @@ class CallService : VectorService(), WiredHeadsetStateReceiver.HeadsetEventListe /** * Display a permanent notification when there is an incoming call. * - * @param session the session - * @param isVideo true if this is a video call, false for voice call - * @param room the room - * @param callId the callId */ private fun displayIncomingCallNotification(intent: Intent) { Timber.v("## VOIP displayIncomingCallNotification $intent") diff --git a/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt b/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt index add7e9c083..73f9f32ca4 100644 --- a/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt +++ b/vector/src/main/java/im/vector/app/features/popup/IncomingCallAlert.kt @@ -29,6 +29,7 @@ class IncomingCallAlert(uid: String, override val shouldBeDisplayedIn: ((Activity) -> Boolean) = { true } ) : DefaultVectorAlert(uid, "", "", 0, shouldBeDisplayedIn) { + override val priority = PopupAlertManager.INCOMING_CALL_PRIORITY override val layoutRes = R.layout.alerter_incoming_call_layout override var colorAttribute: Int? = R.attr.riotx_alerter_background diff --git a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt index 34cee15707..0b7bf2e2c8 100644 --- a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt +++ b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt @@ -35,19 +35,25 @@ import javax.inject.Singleton /** * Responsible of displaying important popup alerts on top of the screen. - * Alerts are stacked and will be displayed sequentially + * Alerts are stacked and will be displayed sequentially but sorted by priority. + * So if a new alert is posted with a higher priority than the current one it will show it instead and the current one + * will be back in the queue in first position. */ @Singleton class PopupAlertManager @Inject constructor() { + companion object { + const val INCOMING_CALL_PRIORITY = Int.MAX_VALUE + } + private var weakCurrentActivity: WeakReference? = null private var currentAlerter: VectorAlert? = null - private val alertFiFo = mutableListOf() + private val alertQueue = mutableListOf() fun postVectorAlert(alert: VectorAlert) { - synchronized(alertFiFo) { - alertFiFo.add(alert) + synchronized(alertQueue) { + alertQueue.add(alert) } weakCurrentActivity?.get()?.runOnUiThread { displayNextIfPossible() @@ -55,8 +61,8 @@ class PopupAlertManager @Inject constructor() { } fun cancelAlert(uid: String) { - synchronized(alertFiFo) { - alertFiFo.listIterator().apply { + synchronized(alertQueue) { + alertQueue.listIterator().apply { while (this.hasNext()) { val next = this.next() if (next.uid == uid) { @@ -79,8 +85,8 @@ class PopupAlertManager @Inject constructor() { * Cancel all alerts, after a sign out for instance */ fun cancelAll() { - synchronized(alertFiFo) { - alertFiFo.clear() + synchronized(alertQueue) { + alertQueue.clear() } // Cancel any displayed alert @@ -126,15 +132,21 @@ class PopupAlertManager @Inject constructor() { } private fun displayNextIfPossible() { - val currentActivity = weakCurrentActivity?.get() - if (Alerter.isShowing || currentActivity == null) { - // will retry later - return - } + val currentActivity = weakCurrentActivity?.get() ?: return val next: VectorAlert? - synchronized(alertFiFo) { - next = alertFiFo.firstOrNull() - if (next != null) alertFiFo.remove(next) + synchronized(alertQueue) { + next = alertQueue.maxByOrNull { it.priority } + // If next alert with highest priority is higher than the current one, we should display it + // and add the current one to queue again. + if (next != null && next.priority > currentAlerter?.priority ?: Int.MIN_VALUE) { + alertQueue.remove(next) + currentAlerter?.also { + alertQueue.add(0, it) + } + } else { + // otherwise, we don't do anything + return + } } currentAlerter = next next?.let { diff --git a/vector/src/main/java/im/vector/app/features/popup/VectorAlert.kt b/vector/src/main/java/im/vector/app/features/popup/VectorAlert.kt index eadc09aa7c..d21755091e 100644 --- a/vector/src/main/java/im/vector/app/features/popup/VectorAlert.kt +++ b/vector/src/main/java/im/vector/app/features/popup/VectorAlert.kt @@ -34,6 +34,7 @@ interface VectorAlert { val title: String val description: String val iconId: Int? + val priority: Int val shouldBeDisplayedIn: ((Activity) -> Boolean) data class Button(val title: String, val action: Runnable, val autoClose: Boolean) @@ -83,6 +84,7 @@ open class DefaultVectorAlert( override val shouldBeDisplayedIn: ((Activity) -> Boolean) = { true }, ) : VectorAlert { + // will be set by manager, and accessible by actions at runtime override var weakCurrentActivity: WeakReference? = null @@ -97,6 +99,8 @@ open class DefaultVectorAlert( @LayoutRes override val layoutRes = R.layout.alerter_alert_default_layout + override val priority: Int = 0 + @ColorRes override var colorRes: Int? = null