Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt +72 −0 Original line number Diff line number Diff line Loading @@ -22,19 +22,25 @@ import android.app.Notification.BubbleMetadata import android.app.Notification.CATEGORY_EVENT import android.app.Notification.CATEGORY_REMINDER import android.app.Notification.VISIBILITY_PRIVATE import android.app.NotificationManager import android.app.NotificationManager.IMPORTANCE_DEFAULT import android.app.NotificationManager.IMPORTANCE_HIGH import android.app.PendingIntent import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.pm.PackageManager.PERMISSION_GRANTED import android.database.ContentObserver import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler import android.os.PowerManager import android.os.SystemProperties import android.provider.Settings import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED import android.provider.Settings.Global.HEADS_UP_OFF import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger import com.android.internal.messages.nano.SystemMessageProto.SystemMessage import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.settings.UserTracker Loading @@ -47,6 +53,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.util.NotificationChannels import com.android.systemui.util.settings.GlobalSettings import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock Loading Loading @@ -244,12 +251,22 @@ class AlertKeyguardVisibilitySuppressor( keyguardNotificationVisibilityProvider.shouldHideNotification(entry) } /** * Set with: * adb shell setprop persist.force_show_avalanche_edu_once 1 && adb shell stop; adb shell start */ private const val FORCE_SHOW_AVALANCHE_EDU_ONCE = "persist.force_show_avalanche_edu_once" private const val PREF_HAS_SEEN_AVALANCHE_EDU = "has_seen_avalanche_edu" class AvalancheSuppressor( private val avalancheProvider: AvalancheProvider, private val systemClock: SystemClock, private val systemSettings: SystemSettings, private val packageManager: PackageManager, private val uiEventLogger: UiEventLogger, private val context: Context, private val notificationManager: NotificationManager ) : VisualInterruptionFilter( types = setOf(PEEK, PULSE), Loading @@ -257,6 +274,24 @@ class AvalancheSuppressor( ) { val TAG = "AvalancheSuppressor" private val prefs = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE) // SharedPreferences are persisted across reboots var hasSeenEdu: Boolean get() = prefs.getBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, false) set(value) = prefs.edit().putBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, value).apply() // Reset on reboot. // The pipeline runs these suppressors many times very fast, so we must use a separate bool // to force show for debug so that phone does not get stuck sending out infinite number of // education HUNs. private var hasShownOnceForDebug = false private fun shouldShowEdu() : Boolean { val forceShowOnce = SystemProperties.get(FORCE_SHOW_AVALANCHE_EDU_ONCE, "").equals("1") return !hasSeenEdu || (forceShowOnce && !hasShownOnceForDebug) } enum class State { ALLOW_CONVERSATION_AFTER_AVALANCHE, ALLOW_HIGH_PRIORITY_CONVERSATION_ANY_TIME, Loading Loading @@ -309,9 +344,46 @@ class AvalancheSuppressor( if (state != State.SUPPRESS) { return false } if (shouldShowEdu()) { showEdu() } return true } /** * Show avalanche education HUN from SystemUI. */ private fun showEdu() { val res = context.resources val titleStr = res.getString( com.android.systemui.res.R.string.adaptive_notification_edu_hun_title) val textStr = res.getString( com.android.systemui.res.R.string.adaptive_notification_edu_hun_text) val actionStr = res.getString( com.android.systemui.res.R.string.go_to_adaptive_notification_settings) val intent = Intent(Settings.ACTION_MANAGE_ADAPTIVE_NOTIFICATIONS) val pendingIntent = PendingIntent.getActivity( context, 0, intent, PendingIntent.FLAG_IMMUTABLE ) val builder = Notification.Builder(context, NotificationChannels.ALERTS) .setTicker(titleStr) .setContentTitle(titleStr) .setContentText(textStr) .setSmallIcon(com.android.systemui.res.R.drawable.ic_settings) .setCategory(Notification.CATEGORY_SYSTEM) .setAutoCancel(true) .addAction(android.R.drawable.button_onoff_indicator_off, actionStr, pendingIntent) .setContentIntent(pendingIntent) notificationManager.notify(SystemMessage.NOTE_ADAPTIVE_NOTIFICATIONS, builder.build()) hasSeenEdu = true hasShownOnceForDebug = true; } private fun calculateState(entry: NotificationEntry): State { if ( entry.ranking.isConversation && Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt +6 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.systemui.statusbar.notification.interruption import android.app.NotificationManager import android.content.Context import android.content.pm.PackageManager import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler Loading Loading @@ -68,7 +70,9 @@ constructor( private val avalancheProvider: AvalancheProvider, private val systemSettings: SystemSettings, private val packageManager: PackageManager, private val bubbles: Optional<Bubbles> private val bubbles: Optional<Bubbles>, private val context: Context, private val notificationManager: NotificationManager ) : VisualInterruptionDecisionProvider { init { Loading Loading @@ -179,7 +183,7 @@ constructor( if (NotificationAvalancheSuppression.isEnabled) { addFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) avalancheProvider.register() } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt +76 −16 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.Manifest.permission import android.app.Notification.CATEGORY_EVENT import android.app.Notification.CATEGORY_REMINDER import android.app.NotificationManager import android.content.pm.PackageManager.PERMISSION_DENIED import android.content.pm.PackageManager.PERMISSION_GRANTED import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 Loading @@ -28,11 +29,16 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE import java.util.Optional import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito.anyString import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.kotlin.whenever import java.util.Optional @SmallTest @RunWith(AndroidJUnit4::class) Loading @@ -58,7 +64,9 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro avalancheProvider, systemSettings, packageManager, Optional.of(bubbles) Optional.of(bubbles), context, notificationManager ) } Loading Loading @@ -86,13 +94,61 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro // instead of VisualInterruptionDecisionProviderTestBase // because avalanche code is based on the suppression refactor. @Test fun testAvalancheFilter_suppress_hasNotSeenEdu_showEduHun() { setAllowedEmergencyPkg(false) whenever(avalancheProvider.timeoutMs).thenReturn(20) whenever(avalancheProvider.startTime).thenReturn(whenAgo(10)) val avalancheSuppressor = AvalancheSuppressor( avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger, context, notificationManager ) avalancheSuppressor.hasSeenEdu = false withFilter(avalancheSuppressor) { ensurePeekState() assertShouldNotHeadsUp( buildEntry { importance = NotificationManager.IMPORTANCE_HIGH whenMs = whenAgo(5) } ) } verify(notificationManager, times(1)).notify(anyInt(), any()) } @Test fun testAvalancheFilter_suppress_hasSeenEduHun_doNotShowEduHun() { setAllowedEmergencyPkg(false) whenever(avalancheProvider.timeoutMs).thenReturn(20) whenever(avalancheProvider.startTime).thenReturn(whenAgo(10)) val avalancheSuppressor = AvalancheSuppressor( avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger, context, notificationManager ) avalancheSuppressor.hasSeenEdu = true withFilter(avalancheSuppressor) { ensurePeekState() assertShouldNotHeadsUp( buildEntry { importance = NotificationManager.IMPORTANCE_HIGH whenMs = whenAgo(5) } ) } verify(notificationManager, times(0)).notify(anyInt(), any()) } @Test fun testAvalancheFilter_duringAvalanche_allowConversationFromAfterEvent() { avalancheProvider.startTime = whenAgo(10) withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -112,7 +168,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldNotHeadsUp( Loading @@ -132,7 +188,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -150,7 +206,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -168,7 +224,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -186,7 +242,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -204,7 +260,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { assertFsiNotSuppressed() } Loading @@ -216,7 +272,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -228,20 +284,24 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro } } @Test fun testAvalancheFilter_duringAvalanche_allowEmergency() { avalancheProvider.startTime = whenAgo(10) private fun setAllowedEmergencyPkg(allow: Boolean) { `when`( packageManager.checkPermission( org.mockito.Mockito.eq(permission.RECEIVE_EMERGENCY_BROADCAST), anyString() ) ).thenReturn(PERMISSION_GRANTED) ).thenReturn(if (allow) PERMISSION_GRANTED else PERMISSION_DENIED) } @Test fun testAvalancheFilter_duringAvalanche_allowEmergency() { avalancheProvider.startTime = whenAgo(10) setAllowedEmergencyPkg(true) withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt +2 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.app.Notification.GROUP_ALERT_CHILDREN import android.app.Notification.GROUP_ALERT_SUMMARY import android.app.Notification.VISIBILITY_PRIVATE import android.app.NotificationChannel import android.app.NotificationManager import android.app.NotificationManager.IMPORTANCE_DEFAULT import android.app.NotificationManager.IMPORTANCE_HIGH import android.app.NotificationManager.IMPORTANCE_LOW Loading Loading @@ -133,7 +134,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() { protected val bubbles: Bubbles = mock() lateinit var systemSettings: SystemSettings protected val packageManager: PackageManager = mock() protected val notificationManager: NotificationManager = mock() protected abstract val provider: VisualInterruptionDecisionProvider private val neverSuppresses = object : NotificationInterruptSuppressor {} Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt +7 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.systemui.statusbar.notification.interruption import android.app.NotificationManager import android.content.Context import android.content.pm.PackageManager import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler Loading Loading @@ -58,6 +60,8 @@ object VisualInterruptionDecisionProviderTestUtil { systemSettings: SystemSettings, packageManager: PackageManager, bubbles: Optional<Bubbles>, context: Context, notificationManager: NotificationManager ): VisualInterruptionDecisionProvider { return if (VisualInterruptionRefactor.isEnabled) { VisualInterruptionDecisionProviderImpl( Loading @@ -79,7 +83,9 @@ object VisualInterruptionDecisionProviderTestUtil { avalancheProvider, systemSettings, packageManager, bubbles bubbles, context, notificationManager ) } else { NotificationInterruptStateProviderWrapper( Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt +72 −0 Original line number Diff line number Diff line Loading @@ -22,19 +22,25 @@ import android.app.Notification.BubbleMetadata import android.app.Notification.CATEGORY_EVENT import android.app.Notification.CATEGORY_REMINDER import android.app.Notification.VISIBILITY_PRIVATE import android.app.NotificationManager import android.app.NotificationManager.IMPORTANCE_DEFAULT import android.app.NotificationManager.IMPORTANCE_HIGH import android.app.PendingIntent import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.pm.PackageManager.PERMISSION_GRANTED import android.database.ContentObserver import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler import android.os.PowerManager import android.os.SystemProperties import android.provider.Settings import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED import android.provider.Settings.Global.HEADS_UP_OFF import com.android.internal.logging.UiEvent import com.android.internal.logging.UiEventLogger import com.android.internal.messages.nano.SystemMessageProto.SystemMessage import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.settings.UserTracker Loading @@ -47,6 +53,7 @@ import com.android.systemui.statusbar.notification.interruption.VisualInterrupti import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE import com.android.systemui.statusbar.policy.BatteryController import com.android.systemui.statusbar.policy.HeadsUpManager import com.android.systemui.util.NotificationChannels import com.android.systemui.util.settings.GlobalSettings import com.android.systemui.util.settings.SystemSettings import com.android.systemui.util.time.SystemClock Loading Loading @@ -244,12 +251,22 @@ class AlertKeyguardVisibilitySuppressor( keyguardNotificationVisibilityProvider.shouldHideNotification(entry) } /** * Set with: * adb shell setprop persist.force_show_avalanche_edu_once 1 && adb shell stop; adb shell start */ private const val FORCE_SHOW_AVALANCHE_EDU_ONCE = "persist.force_show_avalanche_edu_once" private const val PREF_HAS_SEEN_AVALANCHE_EDU = "has_seen_avalanche_edu" class AvalancheSuppressor( private val avalancheProvider: AvalancheProvider, private val systemClock: SystemClock, private val systemSettings: SystemSettings, private val packageManager: PackageManager, private val uiEventLogger: UiEventLogger, private val context: Context, private val notificationManager: NotificationManager ) : VisualInterruptionFilter( types = setOf(PEEK, PULSE), Loading @@ -257,6 +274,24 @@ class AvalancheSuppressor( ) { val TAG = "AvalancheSuppressor" private val prefs = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE) // SharedPreferences are persisted across reboots var hasSeenEdu: Boolean get() = prefs.getBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, false) set(value) = prefs.edit().putBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, value).apply() // Reset on reboot. // The pipeline runs these suppressors many times very fast, so we must use a separate bool // to force show for debug so that phone does not get stuck sending out infinite number of // education HUNs. private var hasShownOnceForDebug = false private fun shouldShowEdu() : Boolean { val forceShowOnce = SystemProperties.get(FORCE_SHOW_AVALANCHE_EDU_ONCE, "").equals("1") return !hasSeenEdu || (forceShowOnce && !hasShownOnceForDebug) } enum class State { ALLOW_CONVERSATION_AFTER_AVALANCHE, ALLOW_HIGH_PRIORITY_CONVERSATION_ANY_TIME, Loading Loading @@ -309,9 +344,46 @@ class AvalancheSuppressor( if (state != State.SUPPRESS) { return false } if (shouldShowEdu()) { showEdu() } return true } /** * Show avalanche education HUN from SystemUI. */ private fun showEdu() { val res = context.resources val titleStr = res.getString( com.android.systemui.res.R.string.adaptive_notification_edu_hun_title) val textStr = res.getString( com.android.systemui.res.R.string.adaptive_notification_edu_hun_text) val actionStr = res.getString( com.android.systemui.res.R.string.go_to_adaptive_notification_settings) val intent = Intent(Settings.ACTION_MANAGE_ADAPTIVE_NOTIFICATIONS) val pendingIntent = PendingIntent.getActivity( context, 0, intent, PendingIntent.FLAG_IMMUTABLE ) val builder = Notification.Builder(context, NotificationChannels.ALERTS) .setTicker(titleStr) .setContentTitle(titleStr) .setContentText(textStr) .setSmallIcon(com.android.systemui.res.R.drawable.ic_settings) .setCategory(Notification.CATEGORY_SYSTEM) .setAutoCancel(true) .addAction(android.R.drawable.button_onoff_indicator_off, actionStr, pendingIntent) .setContentIntent(pendingIntent) notificationManager.notify(SystemMessage.NOTE_ADAPTIVE_NOTIFICATIONS, builder.build()) hasSeenEdu = true hasShownOnceForDebug = true; } private fun calculateState(entry: NotificationEntry): State { if ( entry.ranking.isConversation && Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt +6 −2 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.systemui.statusbar.notification.interruption import android.app.NotificationManager import android.content.Context import android.content.pm.PackageManager import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler Loading Loading @@ -68,7 +70,9 @@ constructor( private val avalancheProvider: AvalancheProvider, private val systemSettings: SystemSettings, private val packageManager: PackageManager, private val bubbles: Optional<Bubbles> private val bubbles: Optional<Bubbles>, private val context: Context, private val notificationManager: NotificationManager ) : VisualInterruptionDecisionProvider { init { Loading Loading @@ -179,7 +183,7 @@ constructor( if (NotificationAvalancheSuppression.isEnabled) { addFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) avalancheProvider.register() } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt +76 −16 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.Manifest.permission import android.app.Notification.CATEGORY_EVENT import android.app.Notification.CATEGORY_REMINDER import android.app.NotificationManager import android.content.pm.PackageManager.PERMISSION_DENIED import android.content.pm.PackageManager.PERMISSION_GRANTED import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 Loading @@ -28,11 +29,16 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE import java.util.Optional import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.any import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito.anyString import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.kotlin.whenever import java.util.Optional @SmallTest @RunWith(AndroidJUnit4::class) Loading @@ -58,7 +64,9 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro avalancheProvider, systemSettings, packageManager, Optional.of(bubbles) Optional.of(bubbles), context, notificationManager ) } Loading Loading @@ -86,13 +94,61 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro // instead of VisualInterruptionDecisionProviderTestBase // because avalanche code is based on the suppression refactor. @Test fun testAvalancheFilter_suppress_hasNotSeenEdu_showEduHun() { setAllowedEmergencyPkg(false) whenever(avalancheProvider.timeoutMs).thenReturn(20) whenever(avalancheProvider.startTime).thenReturn(whenAgo(10)) val avalancheSuppressor = AvalancheSuppressor( avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger, context, notificationManager ) avalancheSuppressor.hasSeenEdu = false withFilter(avalancheSuppressor) { ensurePeekState() assertShouldNotHeadsUp( buildEntry { importance = NotificationManager.IMPORTANCE_HIGH whenMs = whenAgo(5) } ) } verify(notificationManager, times(1)).notify(anyInt(), any()) } @Test fun testAvalancheFilter_suppress_hasSeenEduHun_doNotShowEduHun() { setAllowedEmergencyPkg(false) whenever(avalancheProvider.timeoutMs).thenReturn(20) whenever(avalancheProvider.startTime).thenReturn(whenAgo(10)) val avalancheSuppressor = AvalancheSuppressor( avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger, context, notificationManager ) avalancheSuppressor.hasSeenEdu = true withFilter(avalancheSuppressor) { ensurePeekState() assertShouldNotHeadsUp( buildEntry { importance = NotificationManager.IMPORTANCE_HIGH whenMs = whenAgo(5) } ) } verify(notificationManager, times(0)).notify(anyInt(), any()) } @Test fun testAvalancheFilter_duringAvalanche_allowConversationFromAfterEvent() { avalancheProvider.startTime = whenAgo(10) withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -112,7 +168,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldNotHeadsUp( Loading @@ -132,7 +188,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -150,7 +206,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -168,7 +224,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -186,7 +242,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -204,7 +260,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { assertFsiNotSuppressed() } Loading @@ -216,7 +272,7 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading @@ -228,20 +284,24 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro } } @Test fun testAvalancheFilter_duringAvalanche_allowEmergency() { avalancheProvider.startTime = whenAgo(10) private fun setAllowedEmergencyPkg(allow: Boolean) { `when`( packageManager.checkPermission( org.mockito.Mockito.eq(permission.RECEIVE_EMERGENCY_BROADCAST), anyString() ) ).thenReturn(PERMISSION_GRANTED) ).thenReturn(if (allow) PERMISSION_GRANTED else PERMISSION_DENIED) } @Test fun testAvalancheFilter_duringAvalanche_allowEmergency() { avalancheProvider.startTime = whenAgo(10) setAllowedEmergencyPkg(true) withFilter( AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager, uiEventLogger) uiEventLogger, context, notificationManager) ) { ensurePeekState() assertShouldHeadsUp( Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt +2 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.app.Notification.GROUP_ALERT_CHILDREN import android.app.Notification.GROUP_ALERT_SUMMARY import android.app.Notification.VISIBILITY_PRIVATE import android.app.NotificationChannel import android.app.NotificationManager import android.app.NotificationManager.IMPORTANCE_DEFAULT import android.app.NotificationManager.IMPORTANCE_HIGH import android.app.NotificationManager.IMPORTANCE_LOW Loading Loading @@ -133,7 +134,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() { protected val bubbles: Bubbles = mock() lateinit var systemSettings: SystemSettings protected val packageManager: PackageManager = mock() protected val notificationManager: NotificationManager = mock() protected abstract val provider: VisualInterruptionDecisionProvider private val neverSuppresses = object : NotificationInterruptSuppressor {} Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt +7 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.systemui.statusbar.notification.interruption import android.app.NotificationManager import android.content.Context import android.content.pm.PackageManager import android.hardware.display.AmbientDisplayConfiguration import android.os.Handler Loading Loading @@ -58,6 +60,8 @@ object VisualInterruptionDecisionProviderTestUtil { systemSettings: SystemSettings, packageManager: PackageManager, bubbles: Optional<Bubbles>, context: Context, notificationManager: NotificationManager ): VisualInterruptionDecisionProvider { return if (VisualInterruptionRefactor.isEnabled) { VisualInterruptionDecisionProviderImpl( Loading @@ -79,7 +83,9 @@ object VisualInterruptionDecisionProviderTestUtil { avalancheProvider, systemSettings, packageManager, bubbles bubbles, context, notificationManager ) } else { NotificationInterruptStateProviderWrapper( Loading