summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steve Elliott <steell@google.com> 2020-05-13 17:24:53 -0400
committer Steve Elliott <steell@google.com> 2020-05-15 16:13:29 -0400
commit33d3b54639af8d8776244934329b3bd2e8045b03 (patch)
treef6ac2aa3dff0c4b1752327efb9b33280a8b197b7
parent7c1333199152c5a687c5f75930040786eb783d9f (diff)
Rework Incoming section logic
We cannot assign notifications to the HUNing section during sort and filter in NotifRankMan, because we don't know if those Notifications can be placed there at that time. The VisStabMan can decide that they cannot be moved, and so NotifSecMan can get confused when it sees BUCKET_HEADS_UP in the middle of the shade. In an ideal world, VisStabMan would inform the sort performed by NotifRankMan, as opposed to "shooting it down" after the fact. The main issue here is that NotifRankMan and NotifSecMan are logically related (Notification ordering) but VisStabMan can throw a wrench in that relationship. Also I took the liberty of converting NotifSecMan to Kotlin. :-) Fixes: 153554168 Test: atest, manual Change-Id: I4d1d38eaf4eaac69542c7c115040e76ff95cc1c9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt108
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java314
4 files changed, 304 insertions, 167 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
index 5475c2e062d7..cbf680c5b782 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
@@ -30,7 +30,6 @@ import com.android.systemui.statusbar.notification.people.PeopleNotificationIden
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
-import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
import com.android.systemui.statusbar.notification.stack.PriorityBucket
@@ -138,23 +137,8 @@ open class NotificationRankingManager @Inject constructor(
.filterNot(notifFilter::shouldFilterOut)
.sortedWith(rankingComparator)
.toList()
- assignBuckets(filtered)
- return filtered
- }
-
- private fun assignBuckets(entries: List<NotificationEntry>) {
entries.forEach { it.bucket = getBucketForEntry(it) }
- if (!usePeopleFiltering) {
- // If we don't have a Conversation section, just assign buckets normally based on the
- // content.
- return
- }
- // If HUNs are not continuous with the top section, break out into a new Incoming section.
- entries.asReversed().asSequence().zipWithNext().forEach { (next, entry) ->
- if (entry.isRowHeadsUp && entry.bucket > next.bucket) {
- entry.bucket = BUCKET_HEADS_UP
- }
- }
+ return filtered
}
@PriorityBucket
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
index 92fdd6441539..17b414379f8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
@@ -52,14 +52,35 @@ class NotificationSectionsLogger @Inject constructor(
{ "$int1: other ($str1)" }
)
- fun logHeadsUp(position: Int) = logPosition(position, "Heads Up")
- fun logConversation(position: Int) = logPosition(position, "Conversation")
- fun logAlerting(position: Int) = logPosition(position, "Alerting")
- fun logSilent(position: Int) = logPosition(position, "Silent")
- fun logForegroundService(position: Int) = logPosition(position, "Foreground Service")
+ fun logHeadsUp(position: Int, isHeadsUp: Boolean) =
+ logPosition(position, "Heads Up", isHeadsUp)
+ fun logConversation(position: Int, isHeadsUp: Boolean) =
+ logPosition(position, "Conversation", isHeadsUp)
+ fun logAlerting(position: Int, isHeadsUp: Boolean) =
+ logPosition(position, "Alerting", isHeadsUp)
+ fun logSilent(position: Int, isHeadsUp: Boolean) =
+ logPosition(position, "Silent", isHeadsUp)
+ fun logForegroundService(position: Int, isHeadsUp: Boolean) =
+ logPosition(position, "Foreground Service", isHeadsUp)
fun logStr(str: String) = logBuffer.log(TAG, LogLevel.DEBUG, { str1 = str }, { "$str1" })
+ private fun logPosition(position: Int, label: String, isHeadsUp: Boolean) {
+ val headsUpTag = if (isHeadsUp) " (HUN)" else ""
+ logBuffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ int1 = position
+ str1 = label
+ str2 = headsUpTag
+ },
+ {
+ "$int1: $str1$str2"
+ }
+ )
+ }
+
private fun logPosition(position: Int, label: String) = logBuffer.log(
TAG,
LogLevel.DEBUG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index a2daec15d90b..65633a2e209f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -206,11 +206,14 @@ class NotificationSectionsManager @Inject internal constructor(
child === alertingHeaderView -> logger.logAlertingHeader(i)
child === silentHeaderView -> logger.logSilentHeader(i)
child !is ExpandableNotificationRow -> logger.logOther(i, child.javaClass)
- else -> when (child.entry.bucket) {
- BUCKET_HEADS_UP -> logger.logHeadsUp(i)
- BUCKET_PEOPLE -> logger.logConversation(i)
- BUCKET_ALERTING -> logger.logAlerting(i)
- BUCKET_SILENT -> logger.logSilent(i)
+ else -> {
+ val isHeadsUp = child.isHeadsUp
+ when (child.entry.bucket) {
+ BUCKET_HEADS_UP -> logger.logHeadsUp(i, isHeadsUp)
+ BUCKET_PEOPLE -> logger.logConversation(i, isHeadsUp)
+ BUCKET_ALERTING -> logger.logAlerting(i, isHeadsUp)
+ BUCKET_SILENT -> logger.logSilent(i, isHeadsUp)
+ }
}
}
}
@@ -242,7 +245,7 @@ class NotificationSectionsManager @Inject internal constructor(
var peopleNotifsPresent = false
var currentMediaControlsIdx = -1
- var mediaControlsTarget = if (usingMediaControls) 0 else -1
+ val mediaControlsTarget = if (usingMediaControls) 0 else -1
var currentIncomingHeaderIdx = -1
var incomingHeaderTarget = -1
var currentPeopleHeaderIdx = -1
@@ -253,10 +256,12 @@ class NotificationSectionsManager @Inject internal constructor(
var gentleHeaderTarget = -1
var lastNotifIndex = 0
+ var lastIncomingIndex = -1
+ var prev: ExpandableNotificationRow? = null
- parent.children.forEachIndexed { i, child ->
- // Track the existing positions of the headers
+ for ((i, child) in parent.children.withIndex()) {
when {
+ // Track the existing positions of the headers
child === incomingHeaderView -> {
logger.logIncomingHeader(i)
currentIncomingHeaderIdx = i
@@ -280,41 +285,40 @@ class NotificationSectionsManager @Inject internal constructor(
child !is ExpandableNotificationRow -> logger.logOther(i, child.javaClass)
else -> {
lastNotifIndex = i
- when (child.entry.bucket) {
- BUCKET_HEADS_UP -> {
- logger.logHeadsUp(i)
- if (showHeaders && incomingHeaderTarget == -1) {
- incomingHeaderTarget = i
- // Offset the target if there are other headers before this that
- // will be moved.
- if (currentIncomingHeaderIdx != -1) {
- incomingHeaderTarget--
- }
- if (currentMediaControlsIdx != -1) {
- incomingHeaderTarget--
- }
- if (currentPeopleHeaderIdx != -1) {
- incomingHeaderTarget--
- }
- if (currentAlertingHeaderIdx != -1) {
- incomingHeaderTarget--
- }
- if (currentGentleHeaderIdx != -1) {
- incomingHeaderTarget--
- }
+ // Is there a section discontinuity? This usually occurs due to HUNs
+ if (prev?.entry?.bucket?.let { it > child.entry.bucket } == true) {
+ // Remove existing headers, and move the Incoming header if necessary
+ if (alertingHeaderTarget != -1) {
+ if (showHeaders && incomingHeaderTarget != -1) {
+ incomingHeaderTarget = alertingHeaderTarget
}
- if (mediaControlsTarget != -1) {
- mediaControlsTarget++
+ alertingHeaderTarget = -1
+ }
+ if (peopleHeaderTarget != -1) {
+ if (showHeaders && incomingHeaderTarget != -1) {
+ incomingHeaderTarget = peopleHeaderTarget
}
+ peopleHeaderTarget = -1
+ }
+ if (showHeaders && incomingHeaderTarget == -1) {
+ incomingHeaderTarget = 0
}
- BUCKET_FOREGROUND_SERVICE -> {
- logger.logForegroundService(i)
- if (mediaControlsTarget != -1) {
- mediaControlsTarget++
+ // Walk backwards changing all previous notifications to the Incoming
+ // section
+ for (j in i - 1 downTo lastIncomingIndex + 1) {
+ val prevChild = parent.getChildAt(j)
+ if (prevChild is ExpandableNotificationRow) {
+ prevChild.entry.bucket = BUCKET_HEADS_UP
}
}
+ // Track the new bottom of the Incoming section
+ lastIncomingIndex = i - 1
+ }
+ val isHeadsUp = child.isHeadsUp
+ when (child.entry.bucket) {
+ BUCKET_FOREGROUND_SERVICE -> logger.logForegroundService(i, isHeadsUp)
BUCKET_PEOPLE -> {
- logger.logConversation(i)
+ logger.logConversation(i, isHeadsUp)
peopleNotifsPresent = true
if (showHeaders && peopleHeaderTarget == -1) {
peopleHeaderTarget = i
@@ -332,7 +336,7 @@ class NotificationSectionsManager @Inject internal constructor(
}
}
BUCKET_ALERTING -> {
- logger.logAlerting(i)
+ logger.logAlerting(i, isHeadsUp)
if (showHeaders && usingPeopleFiltering && alertingHeaderTarget == -1) {
alertingHeaderTarget = i
// Offset the target if there are other headers before this that
@@ -346,7 +350,7 @@ class NotificationSectionsManager @Inject internal constructor(
}
}
BUCKET_SILENT -> {
- logger.logSilent(i)
+ logger.logSilent(i, isHeadsUp)
if (showHeaders && gentleHeaderTarget == -1) {
gentleHeaderTarget = i
// Offset the target if there are other headers before this that
@@ -358,6 +362,8 @@ class NotificationSectionsManager @Inject internal constructor(
}
else -> throw IllegalStateException("Cannot find section bucket for view")
}
+
+ prev = child
}
}
}
@@ -393,12 +399,12 @@ class NotificationSectionsManager @Inject internal constructor(
peopleHeaderView?.let {
adjustHeaderVisibilityAndPosition(peopleHeaderTarget, it, currentPeopleHeaderIdx)
}
- mediaControlsView?.let {
- adjustViewPosition(mediaControlsTarget, it, currentMediaControlsIdx)
- }
incomingHeaderView?.let {
adjustHeaderVisibilityAndPosition(incomingHeaderTarget, it, currentIncomingHeaderIdx)
}
+ mediaControlsView?.let {
+ adjustViewPosition(mediaControlsTarget, it, currentMediaControlsIdx)
+ }
logger.logStr("Final order:")
logShadeContents()
@@ -575,14 +581,16 @@ class NotificationSectionsManager @Inject internal constructor(
@IntDef(
prefix = ["BUCKET_"],
value = [
- BUCKET_HEADS_UP, BUCKET_FOREGROUND_SERVICE, BUCKET_MEDIA_CONTROLS, BUCKET_PEOPLE,
- BUCKET_ALERTING, BUCKET_SILENT
+ BUCKET_UNKNOWN, BUCKET_MEDIA_CONTROLS, BUCKET_HEADS_UP, BUCKET_FOREGROUND_SERVICE,
+ BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT
]
)
annotation class PriorityBucket
-const val BUCKET_HEADS_UP = 0
-const val BUCKET_FOREGROUND_SERVICE = 1
-const val BUCKET_MEDIA_CONTROLS = 2
-const val BUCKET_PEOPLE = 3
-const val BUCKET_ALERTING = 4
-const val BUCKET_SILENT = 5
+
+const val BUCKET_UNKNOWN = 0
+const val BUCKET_MEDIA_CONTROLS = 1
+const val BUCKET_HEADS_UP = 2
+const val BUCKET_FOREGROUND_SERVICE = 3
+const val BUCKET_PEOPLE = 4
+const val BUCKET_ALERTING = 5
+const val BUCKET_SILENT = 6
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 02b6cbc0da9d..3dc941a0bd20 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -52,6 +52,7 @@ import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -135,7 +136,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Test
public void testInsertHeader() {
// GIVEN a stack with HI and LO rows but no section headers
- setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+ setStackState(
+ ALERTING,
+ ALERTING,
+ ALERTING,
+ GENTLE);
// WHEN we update the section headers
mSectionsManager.updateSectionBoundaries();
@@ -147,15 +152,18 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Test
public void testRemoveHeader() {
// GIVEN a stack that originally had a header between the HI and LO sections
- setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+ setStackState(
+ ALERTING,
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
// WHEN the last LO row is replaced with a HI row
setStackState(
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.GENTLE_HEADER,
- ChildType.ALERTING);
+ ALERTING,
+ ALERTING,
+ GENTLE_HEADER,
+ ALERTING);
clearInvocations(mNssl);
mSectionsManager.updateSectionBoundaries();
@@ -166,7 +174,10 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Test
public void testDoNothingIfHeaderAlreadyRemoved() {
// GIVEN a stack with only HI rows
- setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING);
+ setStackState(
+ ALERTING,
+ ALERTING,
+ ALERTING);
// WHEN we update the sections headers
mSectionsManager.updateSectionBoundaries();
@@ -179,19 +190,19 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
public void testMoveHeaderForward() {
// GIVEN a stack that originally had a header between the HI and LO sections
setStackState(
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.GENTLE);
+ ALERTING,
+ ALERTING,
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
// WHEN the LO section moves forward
setStackState(
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.GENTLE,
- ChildType.GENTLE_HEADER,
- ChildType.GENTLE);
+ ALERTING,
+ ALERTING,
+ GENTLE,
+ GENTLE_HEADER,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
// THEN the LO section header is also moved forward
@@ -202,19 +213,19 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
public void testMoveHeaderBackward() {
// GIVEN a stack that originally had a header between the HI and LO sections
setStackState(
- ChildType.ALERTING,
- ChildType.GENTLE,
- ChildType.GENTLE,
- ChildType.GENTLE);
+ ALERTING,
+ GENTLE,
+ GENTLE,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
// WHEN the LO section moves backward
setStackState(
- ChildType.ALERTING,
- ChildType.GENTLE_HEADER,
- ChildType.ALERTING,
- ChildType.ALERTING,
- ChildType.GENTLE);
+ ALERTING,
+ GENTLE_HEADER,
+ ALERTING,
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
// THEN the LO section header is also moved backward (with appropriate index shifting)
@@ -225,14 +236,8 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
public void testHeaderRemovedFromTransientParent() {
// GIVEN a stack where the header is animating away
setStackState(
- ChildType.ALERTING,
- ChildType.GENTLE,
- ChildType.GENTLE,
- ChildType.GENTLE);
- mSectionsManager.updateSectionBoundaries();
- setStackState(
- ChildType.ALERTING,
- ChildType.GENTLE_HEADER);
+ ALERTING,
+ GENTLE_HEADER);
mSectionsManager.updateSectionBoundaries();
clearInvocations(mNssl);
@@ -241,8 +246,8 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
// WHEN the LO section reappears
setStackState(
- ChildType.ALERTING,
- ChildType.GENTLE);
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
// THEN the header is first removed from the transient parent before being added to the
@@ -255,7 +260,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
public void testHeaderNotShownOnLockscreen() {
// GIVEN a stack of HI and LO notifs on the lockscreen
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+ setStackState(
+ ALERTING,
+ ALERTING,
+ ALERTING,
+ GENTLE);
// WHEN we update the section headers
mSectionsManager.updateSectionBoundaries();
@@ -268,7 +277,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
public void testHeaderShownWhenEnterLockscreen() {
// GIVEN a stack of HI and LO notifs on the lockscreen
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
- setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+ setStackState(
+ ALERTING,
+ ALERTING,
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
// WHEN we unlock
@@ -282,7 +295,10 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
@Test
public void testHeaderHiddenWhenEnterLockscreen() {
// GIVEN a stack of HI and LO notifs on the shade
- setStackState(ChildType.ALERTING, ChildType.GENTLE_HEADER, ChildType.GENTLE);
+ setStackState(
+ ALERTING,
+ GENTLE_HEADER,
+ GENTLE);
// WHEN we go back to the keyguard
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
@@ -297,10 +313,10 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
enablePeopleFiltering();
setStackState(
- ChildType.GENTLE_HEADER,
- ChildType.PERSON,
- ChildType.ALERTING,
- ChildType.GENTLE);
+ GENTLE_HEADER,
+ PERSON,
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 2);
@@ -313,9 +329,9 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
enablePeopleFiltering();
setStackState(
- ChildType.PERSON,
- ChildType.ALERTING,
- ChildType.GENTLE);
+ PERSON,
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 2);
@@ -328,12 +344,12 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
enablePeopleFiltering();
setStackState(
- ChildType.PEOPLE_HEADER,
- ChildType.ALERTING_HEADER,
- ChildType.GENTLE_HEADER,
- ChildType.PERSON,
- ChildType.ALERTING,
- ChildType.GENTLE);
+ PEOPLE_HEADER,
+ ALERTING_HEADER,
+ GENTLE_HEADER,
+ PERSON,
+ ALERTING,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 4);
@@ -347,12 +363,11 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
enablePeopleFiltering();
setStackState(
- ChildType.PEOPLE_HEADER,
- ChildType.ALERTING_HEADER,
- ChildType.ALERTING,
- ChildType.GENTLE_HEADER,
- ChildType.GENTLE
- );
+ PEOPLE_HEADER,
+ ALERTING_HEADER,
+ ALERTING,
+ GENTLE_HEADER,
+ GENTLE);
mSectionsManager.updateSectionBoundaries();
verify(mNssl, never()).removeView(mSectionsManager.getPeopleHeaderView());
@@ -360,41 +375,98 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
}
@Test
- public void testPeopleFiltering_HunWhilePeopleVisible() {
+ public void testPeopleFiltering_AlertingHunWhilePeopleVisible() {
enablePeopleFiltering();
setupMockStack(
- ChildType.PEOPLE_HEADER,
+ PEOPLE_HEADER,
+ ALERTING.headsUp(),
+ PERSON,
+ ALERTING_HEADER,
+ GENTLE_HEADER,
+ GENTLE
+ );
+ mSectionsManager.updateSectionBoundaries();
+
+ verifyMockStack(
+ ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
+ ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.ALERTING_HEADER,
ChildType.GENTLE_HEADER,
ChildType.GENTLE
);
+ }
+
+ @Test
+ public void testPeopleFiltering_PersonHunWhileAlertingHunVisible() {
+ enablePeopleFiltering();
+
+ setupMockStack(
+ PERSON.headsUp(),
+ INCOMING_HEADER,
+ ALERTING.headsUp(),
+ PEOPLE_HEADER,
+ PERSON
+ );
mSectionsManager.updateSectionBoundaries();
verifyMockStack(
ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
+ ChildType.HEADS_UP,
+ ChildType.PEOPLE_HEADER,
+ ChildType.PERSON
+ );
+ }
+
+ @Test
+ public void testPeopleFiltering_PersonHun() {
+ enablePeopleFiltering();
+
+ setupMockStack(
+ PERSON.headsUp(),
+ PEOPLE_HEADER,
+ PERSON
+ );
+ mSectionsManager.updateSectionBoundaries();
+
+ verifyMockStack(
ChildType.PEOPLE_HEADER,
ChildType.PERSON,
- ChildType.GENTLE_HEADER,
- ChildType.GENTLE
+ ChildType.PERSON
);
}
@Test
- public void testPeopleFiltering_Fsn() {
+ public void testPeopleFiltering_AlertingHunWhilePersonHunning() {
enablePeopleFiltering();
setupMockStack(
+ ALERTING.headsUp(),
+ PERSON.headsUp()
+ );
+ mSectionsManager.updateSectionBoundaries();
+ verifyMockStack(
ChildType.INCOMING_HEADER,
ChildType.HEADS_UP,
ChildType.PEOPLE_HEADER,
- ChildType.FSN,
- ChildType.PERSON,
- ChildType.ALERTING,
- ChildType.GENTLE
+ ChildType.PERSON
+ );
+ }
+
+ @Test
+ public void testPeopleFiltering_Fsn() {
+ enablePeopleFiltering();
+
+ setupMockStack(
+ INCOMING_HEADER,
+ ALERTING.headsUp(),
+ PEOPLE_HEADER,
+ FSN,
+ PERSON,
+ ALERTING,
+ GENTLE
);
mSectionsManager.updateSectionBoundaries();
@@ -416,7 +488,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
enableMediaControls();
// GIVEN a stack that doesn't include media controls
- setStackState(ChildType.ALERTING, ChildType.GENTLE_HEADER, ChildType.GENTLE);
+ setStackState(ALERTING, GENTLE_HEADER, GENTLE);
// WHEN we go back to the keyguard
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
@@ -431,14 +503,20 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
enableMediaControls();
// GIVEN a stack that doesn't include media controls but includes HEADS_UP
- setupMockStack(ChildType.HEADS_UP, ChildType.ALERTING, ChildType.GENTLE_HEADER,
- ChildType.GENTLE);
+ setupMockStack(
+ ALERTING.headsUp(),
+ ALERTING,
+ GENTLE_HEADER,
+ GENTLE);
// WHEN we go back to the keyguard
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
mSectionsManager.updateSectionBoundaries();
- verifyMockStack(ChildType.HEADS_UP, ChildType.MEDIA_CONTROLS, ChildType.ALERTING,
+ verifyMockStack(
+ ChildType.MEDIA_CONTROLS,
+ ChildType.ALERTING,
+ ChildType.ALERTING,
ChildType.GENTLE);
}
@@ -455,11 +533,12 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
FSN, PERSON, ALERTING, GENTLE, OTHER
}
- private void setStackState(ChildType... children) {
+ private void setStackState(StackEntry... children) {
when(mNssl.getChildCount()).thenReturn(children.length);
for (int i = 0; i < children.length; i++) {
View child;
- switch (children[i]) {
+ StackEntry entry = children[i];
+ switch (entry.mChildType) {
case INCOMING_HEADER:
child = mSectionsManager.getIncomingHeaderView();
break;
@@ -475,20 +554,17 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
case GENTLE_HEADER:
child = mSectionsManager.getSilentHeaderView();
break;
- case HEADS_UP:
- child = mockNotification(BUCKET_HEADS_UP);
- break;
case FSN:
- child = mockNotification(BUCKET_FOREGROUND_SERVICE);
+ child = mockNotification(BUCKET_FOREGROUND_SERVICE, entry.mIsHeadsUp);
break;
case PERSON:
- child = mockNotification(BUCKET_PEOPLE);
+ child = mockNotification(BUCKET_PEOPLE, entry.mIsHeadsUp);
break;
case ALERTING:
- child = mockNotification(BUCKET_ALERTING);
+ child = mockNotification(BUCKET_ALERTING, entry.mIsHeadsUp);
break;
case GENTLE:
- child = mockNotification(BUCKET_SILENT);
+ child = mockNotification(BUCKET_SILENT, entry.mIsHeadsUp);
break;
case OTHER:
child = mock(View.class);
@@ -503,12 +579,24 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
}
}
- private View mockNotification(int bucket) {
- ExpandableNotificationRow notifRow = mock(ExpandableNotificationRow.class,
- RETURNS_DEEP_STUBS);
+ private View mockNotification(int bucket, boolean headsUp) {
+ ExpandableNotificationRow notifRow =
+ mock(ExpandableNotificationRow.class, RETURNS_DEEP_STUBS);
when(notifRow.getVisibility()).thenReturn(View.VISIBLE);
- when(notifRow.getEntry().getBucket()).thenReturn(bucket);
when(notifRow.getParent()).thenReturn(mNssl);
+
+ NotificationEntry mockEntry = mock(NotificationEntry.class);
+ when(notifRow.getEntry()).thenReturn(mockEntry);
+
+ int[] bucketRef = new int[] { bucket };
+ when(mockEntry.getBucket()).thenAnswer(invocation -> bucketRef[0]);
+ doAnswer(invocation -> {
+ bucketRef[0] = invocation.getArgument(0);
+ return null;
+ }).when(mockEntry).setBucket(anyInt());
+
+ when(notifRow.isHeadsUp()).thenReturn(headsUp);
+ when(mockEntry.isRowHeadsUp()).thenReturn(headsUp);
return notifRow;
}
@@ -565,7 +653,7 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
assertThat(actual).containsExactly((Object[]) expected).inOrder();
}
- private void setupMockStack(ChildType... childTypes) {
+ private void setupMockStack(StackEntry... entries) {
final List<View> children = new ArrayList<>();
when(mNssl.getChildCount()).thenAnswer(invocation -> children.size());
when(mNssl.getChildAt(anyInt()))
@@ -590,9 +678,9 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
children.add(newIndex, child);
return null;
}).when(mNssl).changeViewPosition(any(), anyInt());
- for (ChildType childType : childTypes) {
+ for (StackEntry entry : entries) {
View child;
- switch (childType) {
+ switch (entry.mChildType) {
case INCOMING_HEADER:
child = mSectionsManager.getIncomingHeaderView();
break;
@@ -608,20 +696,17 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
case GENTLE_HEADER:
child = mSectionsManager.getSilentHeaderView();
break;
- case HEADS_UP:
- child = mockNotification(BUCKET_HEADS_UP);
- break;
case FSN:
- child = mockNotification(BUCKET_FOREGROUND_SERVICE);
+ child = mockNotification(BUCKET_FOREGROUND_SERVICE, entry.mIsHeadsUp);
break;
case PERSON:
- child = mockNotification(BUCKET_PEOPLE);
+ child = mockNotification(BUCKET_PEOPLE, entry.mIsHeadsUp);
break;
case ALERTING:
- child = mockNotification(BUCKET_ALERTING);
+ child = mockNotification(BUCKET_ALERTING, entry.mIsHeadsUp);
break;
case GENTLE:
- child = mockNotification(BUCKET_SILENT);
+ child = mockNotification(BUCKET_SILENT, entry.mIsHeadsUp);
break;
case OTHER:
child = mock(View.class);
@@ -629,9 +714,48 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
when(child.getParent()).thenReturn(mNssl);
break;
default:
- throw new RuntimeException("Unknown ChildType: " + childType);
+ throw new RuntimeException("Unknown ChildType: " + entry.mChildType);
}
children.add(child);
}
}
+
+ private static final StackEntry INCOMING_HEADER = new StackEntry(ChildType.INCOMING_HEADER);
+ private static final StackEntry MEDIA_CONTROLS = new StackEntry(ChildType.MEDIA_CONTROLS);
+ private static final StackEntry PEOPLE_HEADER = new StackEntry(ChildType.PEOPLE_HEADER);
+ private static final StackEntry ALERTING_HEADER = new StackEntry(ChildType.ALERTING_HEADER);
+ private static final StackEntry GENTLE_HEADER = new StackEntry(ChildType.GENTLE_HEADER);
+ private static final StackEntry FSN = new StackEntry(ChildType.FSN);
+ private static final StackEntry.Hunnable PERSON = new StackEntry.Hunnable(ChildType.PERSON);
+ private static final StackEntry.Hunnable ALERTING = new StackEntry.Hunnable(ChildType.ALERTING);
+ private static final StackEntry GENTLE = new StackEntry(ChildType.GENTLE);
+
+ private static class StackEntry {
+ final ChildType mChildType;
+ final boolean mIsHeadsUp;
+
+ StackEntry(ChildType childType) {
+ this(childType, false);
+ }
+
+ StackEntry(ChildType childType, boolean isHeadsUp) {
+ mChildType = childType;
+ mIsHeadsUp = isHeadsUp;
+ }
+
+ static class Hunnable extends StackEntry {
+
+ Hunnable(ChildType childType) {
+ super(childType, false);
+ }
+
+ Hunnable(ChildType childType, boolean isHeadsUp) {
+ super(childType, isHeadsUp);
+ }
+
+ public Hunnable headsUp() {
+ return new Hunnable(mChildType, true);
+ }
+ }
+ }
}