summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Julia Tuttle <juliatuttle@google.com> 2023-11-01 22:49:10 -0400
committer Julia Tuttle <juliatuttle@google.com> 2023-11-01 22:55:01 -0400
commit5f9a3dd31b57d83f1bdd7304155a1efd7d299ed7 (patch)
tree8dc944c98704b08ad394a701344863caebf39a33
parent84e94f27d4bffc93be07f6a98cf6d07e5d7a73fe (diff)
Add VisualInterruptionSuppressor logic tests
Bug: 261728888 Test: atest VisualInterruptionDecisionProviderImplTest Flag: ACONFIG com.android.systemui.visual_interruptions_refactor DEVELOPMENT Change-Id: I563a12bbba7b036c2c2da75b7260caab136abd49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt180
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt42
3 files changed, 212 insertions, 21 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
index f0fe56db9fdd..2730683a31c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
@@ -19,6 +19,7 @@ import android.hardware.display.AmbientDisplayConfiguration
import android.os.Handler
import android.os.PowerManager
import android.util.Log
+import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.settings.UserTracker
@@ -106,11 +107,21 @@ constructor(
condition.start()
}
+ @VisibleForTesting
+ fun removeCondition(condition: VisualInterruptionCondition) {
+ conditions.remove(condition)
+ }
+
fun addFilter(filter: VisualInterruptionFilter) {
filters.add(filter)
filter.start()
}
+ @VisibleForTesting
+ fun removeFilter(filter: VisualInterruptionFilter) {
+ filters.remove(filter)
+ }
+
override fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision {
check(started)
return makeHeadsUpDecision(entry)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
index eda65e671676..80d941a40cb5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
@@ -18,6 +18,11 @@ package com.android.systemui.statusbar.notification.interruption
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
+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 org.junit.Test
import org.junit.runner.RunWith
@SmallTest
@@ -38,4 +43,179 @@ class VisualInterruptionDecisionProviderImplTest : VisualInterruptionDecisionPro
userTracker,
)
}
+
+ @Test
+ fun testNothingCondition_suppressesNothing() {
+ withCondition(TestCondition(types = emptySet()) { true }) {
+ assertPeekNotSuppressed()
+ assertPulseNotSuppressed()
+ assertBubbleNotSuppressed()
+ }
+ }
+
+ @Test
+ fun testNothingFilter_suppressesNothing() {
+ withFilter(TestFilter(types = emptySet()) { true }) {
+ assertPeekNotSuppressed()
+ assertPulseNotSuppressed()
+ assertBubbleNotSuppressed()
+ }
+ }
+
+ @Test
+ fun testPeekCondition_suppressesOnlyPeek() {
+ withCondition(TestCondition(types = setOf(PEEK)) { true }) {
+ assertPeekSuppressed()
+ assertPulseNotSuppressed()
+ assertBubbleNotSuppressed()
+ }
+ }
+
+ @Test
+ fun testPeekFilter_suppressesOnlyPeek() {
+ withFilter(TestFilter(types = setOf(PEEK)) { true }) {
+ assertPeekSuppressed()
+ assertPulseNotSuppressed()
+ assertBubbleNotSuppressed()
+ }
+ }
+
+ @Test
+ fun testPulseCondition_suppressesOnlyPulse() {
+ withCondition(TestCondition(types = setOf(PULSE)) { true }) {
+ assertPeekNotSuppressed()
+ assertPulseSuppressed()
+ assertBubbleNotSuppressed()
+ }
+ }
+
+ @Test
+ fun testPulseFilter_suppressesOnlyPulse() {
+ withFilter(TestFilter(types = setOf(PULSE)) { true }) {
+ assertPeekNotSuppressed()
+ assertPulseSuppressed()
+ assertBubbleNotSuppressed()
+ }
+ }
+
+ @Test
+ fun testBubbleCondition_suppressesOnlyBubble() {
+ withCondition(TestCondition(types = setOf(BUBBLE)) { true }) {
+ assertPeekNotSuppressed()
+ assertPulseNotSuppressed()
+ assertBubbleSuppressed()
+ }
+ }
+
+ @Test
+ fun testBubbleFilter_suppressesOnlyBubble() {
+ withFilter(TestFilter(types = setOf(BUBBLE)) { true }) {
+ assertPeekNotSuppressed()
+ assertPulseNotSuppressed()
+ assertBubbleSuppressed()
+ }
+ }
+
+ @Test
+ fun testCondition_differentState() {
+ ensurePeekState()
+ val entry = buildPeekEntry()
+
+ var stateShouldSuppress = false
+ withCondition(TestCondition(types = setOf(PEEK)) { stateShouldSuppress }) {
+ assertShouldHeadsUp(entry)
+
+ stateShouldSuppress = true
+ assertShouldNotHeadsUp(entry)
+
+ stateShouldSuppress = false
+ assertShouldHeadsUp(entry)
+ }
+ }
+
+ @Test
+ fun testFilter_differentState() {
+ ensurePeekState()
+ val entry = buildPeekEntry()
+
+ var stateShouldSuppress = false
+ withFilter(TestFilter(types = setOf(PEEK)) { stateShouldSuppress }) {
+ assertShouldHeadsUp(entry)
+
+ stateShouldSuppress = true
+ assertShouldNotHeadsUp(entry)
+
+ stateShouldSuppress = false
+ assertShouldHeadsUp(entry)
+ }
+ }
+
+ @Test
+ fun testFilter_differentNotif() {
+ ensurePeekState()
+
+ val suppressedEntry = buildPeekEntry()
+ val unsuppressedEntry = buildPeekEntry()
+
+ withFilter(TestFilter(types = setOf(PEEK)) { it == suppressedEntry }) {
+ assertShouldNotHeadsUp(suppressedEntry)
+ assertShouldHeadsUp(unsuppressedEntry)
+ }
+ }
+
+ private fun assertPeekSuppressed() {
+ ensurePeekState()
+ assertShouldNotHeadsUp(buildPeekEntry())
+ }
+
+ private fun assertPeekNotSuppressed() {
+ ensurePeekState()
+ assertShouldHeadsUp(buildPeekEntry())
+ }
+
+ private fun assertPulseSuppressed() {
+ ensurePulseState()
+ assertShouldNotHeadsUp(buildPulseEntry())
+ }
+
+ private fun assertPulseNotSuppressed() {
+ ensurePulseState()
+ assertShouldHeadsUp(buildPulseEntry())
+ }
+
+ private fun assertBubbleSuppressed() {
+ ensureBubbleState()
+ assertShouldNotBubble(buildBubbleEntry())
+ }
+
+ private fun assertBubbleNotSuppressed() {
+ ensureBubbleState()
+ assertShouldBubble(buildBubbleEntry())
+ }
+
+ private fun withCondition(condition: VisualInterruptionCondition, block: () -> Unit) {
+ provider.addCondition(condition)
+ block()
+ provider.removeCondition(condition)
+ }
+
+ private fun withFilter(filter: VisualInterruptionFilter, block: () -> Unit) {
+ provider.addFilter(filter)
+ block()
+ provider.removeFilter(filter)
+ }
+
+ private class TestCondition(
+ types: Set<VisualInterruptionType>,
+ val onShouldSuppress: () -> Boolean
+ ) : VisualInterruptionCondition(types = types, reason = "") {
+ override fun shouldSuppress(): Boolean = onShouldSuppress()
+ }
+
+ private class TestFilter(
+ types: Set<VisualInterruptionType>,
+ val onShouldSuppress: (NotificationEntry) -> Boolean = { true }
+ ) : VisualInterruptionFilter(types = types, reason = "") {
+ override fun shouldSuppress(entry: NotificationEntry) = onShouldSuppress(entry)
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
index 35ce027e8c41..7f12b22f2b4e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
@@ -494,7 +494,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
assertShouldFsi(buildFsiEntry())
}
- private data class State(
+ protected data class State(
var hunSettingEnabled: Boolean? = null,
var hunSnoozed: Boolean? = null,
var isAodPowerSave: Boolean? = null,
@@ -507,7 +507,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
var statusBarState: Int? = null,
)
- private fun setState(state: State): Unit =
+ protected fun setState(state: State): Unit =
state.run {
hunSettingEnabled?.let {
val newSetting = if (it) HEADS_UP_ON else HEADS_UP_OFF
@@ -538,7 +538,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
statusBarState?.let { statusBarStateController.state = it }
}
- private fun ensureState(block: State.() -> Unit) =
+ protected fun ensureState(block: State.() -> Unit) =
State()
.apply {
keyguardShouldHideNotification = false
@@ -546,7 +546,7 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
}
.run(this::setState)
- private fun ensurePeekState(block: State.() -> Unit = {}) = ensureState {
+ protected fun ensurePeekState(block: State.() -> Unit = {}) = ensureState {
hunSettingEnabled = true
hunSnoozed = false
isDozing = false
@@ -555,67 +555,67 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
run(block)
}
- private fun ensurePulseState(block: State.() -> Unit = {}) = ensureState {
+ protected fun ensurePulseState(block: State.() -> Unit = {}) = ensureState {
isAodPowerSave = false
isDozing = true
pulseOnNotificationsEnabled = true
run(block)
}
- private fun ensureBubbleState(block: State.() -> Unit = {}) = ensureState(block)
+ protected fun ensureBubbleState(block: State.() -> Unit = {}) = ensureState(block)
- private fun ensureNotInteractiveFsiState(block: State.() -> Unit = {}) = ensureState {
+ protected fun ensureNotInteractiveFsiState(block: State.() -> Unit = {}) = ensureState {
isDreaming = false
isInteractive = false
statusBarState = SHADE
run(block)
}
- private fun ensureDreamingFsiState(block: State.() -> Unit = {}) = ensureState {
+ protected fun ensureDreamingFsiState(block: State.() -> Unit = {}) = ensureState {
isDreaming = true
isInteractive = true
statusBarState = SHADE
run(block)
}
- private fun ensureKeyguardFsiState(block: State.() -> Unit = {}) = ensureState {
+ protected fun ensureKeyguardFsiState(block: State.() -> Unit = {}) = ensureState {
isDreaming = false
isInteractive = true
statusBarState = KEYGUARD
run(block)
}
- private fun assertShouldHeadsUp(entry: NotificationEntry) =
+ protected fun assertShouldHeadsUp(entry: NotificationEntry) =
provider.makeUnloggedHeadsUpDecision(entry).let {
assertTrue("unexpected suppressed HUN: ${it.logReason}", it.shouldInterrupt)
}
- private fun assertShouldNotHeadsUp(entry: NotificationEntry) =
+ protected fun assertShouldNotHeadsUp(entry: NotificationEntry) =
provider.makeUnloggedHeadsUpDecision(entry).let {
assertFalse("unexpected unsuppressed HUN: ${it.logReason}", it.shouldInterrupt)
}
- private fun assertShouldBubble(entry: NotificationEntry) =
+ protected fun assertShouldBubble(entry: NotificationEntry) =
provider.makeAndLogBubbleDecision(entry).let {
assertTrue("unexpected suppressed bubble: ${it.logReason}", it.shouldInterrupt)
}
- private fun assertShouldNotBubble(entry: NotificationEntry) =
+ protected fun assertShouldNotBubble(entry: NotificationEntry) =
provider.makeAndLogBubbleDecision(entry).let {
assertFalse("unexpected unsuppressed bubble: ${it.logReason}", it.shouldInterrupt)
}
- private fun assertShouldFsi(entry: NotificationEntry) =
+ protected fun assertShouldFsi(entry: NotificationEntry) =
provider.makeUnloggedFullScreenIntentDecision(entry).let {
assertTrue("unexpected suppressed FSI: ${it.logReason}", it.shouldInterrupt)
}
- private fun assertShouldNotFsi(entry: NotificationEntry) =
+ protected fun assertShouldNotFsi(entry: NotificationEntry) =
provider.makeUnloggedFullScreenIntentDecision(entry).let {
assertFalse("unexpected unsuppressed FSI: ${it.logReason}", it.shouldInterrupt)
}
- private class EntryBuilder(val context: Context) {
+ protected class EntryBuilder(val context: Context) {
var importance = IMPORTANCE_DEFAULT
var suppressedVisualEffects: Int? = null
var whenMs: Long? = null
@@ -708,27 +708,27 @@ abstract class VisualInterruptionDecisionProviderTestBase : SysuiTestCase() {
}
}
- private fun buildEntry(block: EntryBuilder.() -> Unit) =
+ protected fun buildEntry(block: EntryBuilder.() -> Unit) =
EntryBuilder(context).also(block).build()
- private fun buildPeekEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ protected fun buildPeekEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
importance = IMPORTANCE_HIGH
run(block)
}
- private fun buildPulseEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ protected fun buildPulseEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
importance = IMPORTANCE_DEFAULT
visibilityOverride = VISIBILITY_NO_OVERRIDE
run(block)
}
- private fun buildBubbleEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ protected fun buildBubbleEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
canBubble = true
hasBubbleMetadata = true
run(block)
}
- private fun buildFsiEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
+ protected fun buildFsiEntry(block: EntryBuilder.() -> Unit = {}) = buildEntry {
importance = IMPORTANCE_HIGH
hasFsi = true
run(block)