summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java211
2 files changed, 189 insertions, 56 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
index 04ff58b36c94..64b2f048ce2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
@@ -25,6 +25,7 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
+import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
@@ -69,7 +70,8 @@ public class NotificationData {
mHeadsUpManager = headsUpManager;
}
- private final Comparator<NotificationEntry> mRankingComparator =
+ @VisibleForTesting
+ protected final Comparator<NotificationEntry> mRankingComparator =
new Comparator<NotificationEntry>() {
private final Ranking mRankingA = new Ranking();
private final Ranking mRankingB = new Ranking();
@@ -120,6 +122,8 @@ public class NotificationData {
} else if (aSystemMax != bSystemMax) {
// Upsort PRIORITY_MAX system notifications
return aSystemMax ? -1 : 1;
+ } else if (a.isHighPriority() != b.isHighPriority()) {
+ return -1 * Boolean.compare(a.isHighPriority(), b.isHighPriority());
} else if (aRank != bRank) {
return aRank - bRank;
} else {
@@ -231,17 +235,14 @@ public class NotificationData {
/**
* Returns true if this notification should be displayed in the high-priority notifications
- * section (and on the lockscreen and status bar).
+ * section
*/
public boolean isHighPriority(StatusBarNotification statusBarNotification) {
if (mRankingMap != null) {
getRanking(statusBarNotification.getKey(), mTmpRanking);
if (mTmpRanking.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT
- || isImportantOngoing(statusBarNotification.getNotification())
- || statusBarNotification.getNotification().hasMediaSession()
- || hasPerson(statusBarNotification.getNotification())
- || hasStyle(statusBarNotification.getNotification(),
- Notification.MessagingStyle.class)) {
+ || hasHighPriorityCharacteristics(
+ mTmpRanking.getChannel(), statusBarNotification)) {
return true;
}
if (mGroupManager.isSummaryOfGroup(statusBarNotification)) {
@@ -257,6 +258,25 @@ public class NotificationData {
return false;
}
+ private boolean hasHighPriorityCharacteristics(NotificationChannel channel,
+ StatusBarNotification statusBarNotification) {
+
+ if (isImportantOngoing(statusBarNotification.getNotification())
+ || statusBarNotification.getNotification().hasMediaSession()
+ || hasPerson(statusBarNotification.getNotification())
+ || hasStyle(statusBarNotification.getNotification(),
+ Notification.MessagingStyle.class)) {
+ // Users who have long pressed and demoted to silent should not see the notification
+ // in the top section
+ if (channel != null && channel.hasUserSetImportance()) {
+ return false;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
private boolean isImportantOngoing(Notification notification) {
return notification.isForegroundService()
&& mTmpRanking.getImportance() >= NotificationManager.IMPORTANCE_LOW;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index 79a6ac4cb0c7..6e0ddbf0cc46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -28,6 +28,7 @@ import static android.app.NotificationManager.IMPORTANCE_MIN;
import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_CHANNEL;
import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_IMPORTANCE;
+import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_RANK;
import static com.android.systemui.statusbar.notification.collection.NotificationDataTest.TestableNotificationData.OVERRIDE_VIS_EFFECTS;
import static junit.framework.Assert.assertEquals;
@@ -61,16 +62,12 @@ import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArraySet;
-import androidx.test.filters.SmallTest;
-
import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationTestHelper;
-import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationData.KeyguardEnvironment;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -83,7 +80,11 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+
+import androidx.test.filters.SmallTest;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -137,7 +138,9 @@ public class NotificationDataTest extends SysuiTestCase {
@Test
public void testChannelSetWhenAdded() {
- mNotificationData.rankingOverrides.putParcelable(OVERRIDE_CHANNEL, NOTIFICATION_CHANNEL);
+ Bundle override = new Bundle();
+ override.putParcelable(OVERRIDE_CHANNEL, NOTIFICATION_CHANNEL);
+ mNotificationData.rankingOverrides.put(mRow.getEntry().key, override);
mNotificationData.add(mRow.getEntry());
assertEquals(NOTIFICATION_CHANNEL, mRow.getEntry().channel);
}
@@ -229,7 +232,9 @@ public class NotificationDataTest extends SysuiTestCase {
n.flags = Notification.FLAG_FOREGROUND_SERVICE;
NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
mNotificationData.add(entry);
- mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS, 255);
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_VIS_EFFECTS, 255);
+ mNotificationData.rankingOverrides.put(entry.key, override);
assertTrue(entry.isExemptFromDndVisualSuppression());
assertFalse(entry.shouldSuppressAmbient());
@@ -245,7 +250,9 @@ public class NotificationDataTest extends SysuiTestCase {
when(mMockStatusBarNotification.getNotification()).thenReturn(n);
NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
mNotificationData.add(entry);
- mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS, 255);
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_VIS_EFFECTS, 255);
+ mNotificationData.rankingOverrides.put(entry.key, override);
assertTrue(entry.isExemptFromDndVisualSuppression());
assertFalse(entry.shouldSuppressAmbient());
@@ -257,7 +264,9 @@ public class NotificationDataTest extends SysuiTestCase {
NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
entry.mIsSystemNotification = true;
mNotificationData.add(entry);
- mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS, 255);
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_VIS_EFFECTS, 255);
+ mNotificationData.rankingOverrides.put(entry.key, override);
assertTrue(entry.isExemptFromDndVisualSuppression());
assertFalse(entry.shouldSuppressAmbient());
@@ -268,8 +277,9 @@ public class NotificationDataTest extends SysuiTestCase {
initStatusBarNotification(false);
NotificationEntry entry = new NotificationEntry(mMockStatusBarNotification);
entry.mIsSystemNotification = true;
- mNotificationData.rankingOverrides.putInt(OVERRIDE_VIS_EFFECTS,
- NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT);
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_VIS_EFFECTS, NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT);
+ mNotificationData.rankingOverrides.put(entry.key, override);
mNotificationData.add(entry);
when(mMockStatusBarNotification.getNotification()).thenReturn(
@@ -395,11 +405,13 @@ public class NotificationDataTest extends SysuiTestCase {
Notification notification = mock(Notification.class);
when(notification.isForegroundService()).thenReturn(true);
- mNotificationData.rankingOverrides.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_MIN);
-
StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
notification, mContext.getUser(), "", 0);
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_MIN);
+ mNotificationData.rankingOverrides.put(sbn.getKey(), override);
+
assertFalse(mNotificationData.isHighPriority(sbn));
}
@@ -408,14 +420,114 @@ public class NotificationDataTest extends SysuiTestCase {
Notification notification = mock(Notification.class);
when(notification.isForegroundService()).thenReturn(true);
- mNotificationData.rankingOverrides.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW);
-
StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
notification, mContext.getUser(), "", 0);
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW);
+ mNotificationData.rankingOverrides.put(sbn.getKey(), override);
+
assertTrue(mNotificationData.isHighPriority(sbn));
}
+ @Test
+ public void userChangeTrumpsHighPriorityCharacteristics() {
+ Person person = new Person.Builder()
+ .setName("name")
+ .setKey("abc")
+ .setUri("uri")
+ .setBot(true)
+ .build();
+
+ Notification notification = new Notification.Builder(mContext, "test")
+ .addPerson(person)
+ .setStyle(new Notification.MessagingStyle(""))
+ .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+ .build();
+
+ StatusBarNotification sbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
+ notification, mContext.getUser(), "", 0);
+
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+ channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+
+ Bundle override = new Bundle();
+ override.putParcelable(OVERRIDE_CHANNEL, channel);
+ mNotificationData.rankingOverrides.put(sbn.getKey(), override);
+
+ assertFalse(mNotificationData.isHighPriority(sbn));
+ }
+
+ @Test
+ public void testSort_highPriorityTrumpsNMSRank() {
+ // NMS rank says A and then B. But A is not high priority and B is, so B should sort in
+ // front
+ Notification aN = new Notification.Builder(mContext, "test")
+ .setStyle(new Notification.MessagingStyle(""))
+ .build();
+ StatusBarNotification aSbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
+ aN, mContext.getUser(), "", 0);
+ NotificationEntry a = new NotificationEntry(aSbn);
+ a.setRow(mock(ExpandableNotificationRow.class));
+ a.setIsHighPriority(false);
+
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW);
+ override.putInt(OVERRIDE_RANK, 1);
+ mNotificationData.rankingOverrides.put(a.key, override);
+
+ Notification bN = new Notification.Builder(mContext, "test")
+ .setStyle(new Notification.MessagingStyle(""))
+ .build();
+ StatusBarNotification bSbn = new StatusBarNotification("pkg2", "pkg2", 0, "tag", 0, 0,
+ bN, mContext.getUser(), "", 0);
+ NotificationEntry b = new NotificationEntry(bSbn);
+ b.setIsHighPriority(true);
+ b.setRow(mock(ExpandableNotificationRow.class));
+
+ Bundle bOverride = new Bundle();
+ bOverride.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW);
+ bOverride.putInt(OVERRIDE_RANK, 2);
+ mNotificationData.rankingOverrides.put(b.key, bOverride);
+
+ assertEquals(1, mNotificationData.mRankingComparator.compare(a, b));
+ }
+
+ @Test
+ public void testSort_samePriorityUsesNMSRank() {
+ // NMS rank says A and then B. But A is not high priority and B is, so B should sort in
+ // front
+ Notification aN = new Notification.Builder(mContext, "test")
+ .setStyle(new Notification.MessagingStyle(""))
+ .build();
+ StatusBarNotification aSbn = new StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
+ aN, mContext.getUser(), "", 0);
+ NotificationEntry a = new NotificationEntry(aSbn);
+ a.setRow(mock(ExpandableNotificationRow.class));
+ a.setIsHighPriority(false);
+
+ Bundle override = new Bundle();
+ override.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW);
+ override.putInt(OVERRIDE_RANK, 1);
+ mNotificationData.rankingOverrides.put(a.key, override);
+
+ Notification bN = new Notification.Builder(mContext, "test")
+ .setStyle(new Notification.MessagingStyle(""))
+ .build();
+ StatusBarNotification bSbn = new StatusBarNotification("pkg2", "pkg2", 0, "tag", 0, 0,
+ bN, mContext.getUser(), "", 0);
+ NotificationEntry b = new NotificationEntry(bSbn);
+ b.setRow(mock(ExpandableNotificationRow.class));
+ b.setIsHighPriority(false);
+
+ Bundle bOverride = new Bundle();
+ bOverride.putInt(OVERRIDE_IMPORTANCE, IMPORTANCE_LOW);
+ bOverride.putInt(OVERRIDE_RANK, 2);
+ mNotificationData.rankingOverrides.put(b.key, bOverride);
+
+ assertEquals(-1, mNotificationData.mRankingComparator.compare(a, b));
+ }
+
private void initStatusBarNotification(boolean allowDuringSetup) {
Bundle bundle = new Bundle();
bundle.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, allowDuringSetup);
@@ -449,7 +561,7 @@ public class NotificationDataTest extends SysuiTestCase {
public static final String OVERRIDE_SMART_REPLIES = "sr";
public static final String OVERRIDE_BUBBLE = "cb";
- public Bundle rankingOverrides = new Bundle();
+ public Map<String, Bundle> rankingOverrides = new HashMap<>();
@Override
protected boolean getRanking(String key, Ranking outRanking) {
@@ -475,40 +587,41 @@ public class NotificationDataTest extends SysuiTestCase {
currentReplies.addAll(outRanking.getSmartReplies());
}
- outRanking.populate(key,
- rankingOverrides.getInt(OVERRIDE_RANK, outRanking.getRank()),
- rankingOverrides.getBoolean(OVERRIDE_DND,
- outRanking.matchesInterruptionFilter()),
- rankingOverrides.getInt(OVERRIDE_VIS_OVERRIDE,
- outRanking.getVisibilityOverride()),
- rankingOverrides.getInt(OVERRIDE_VIS_EFFECTS,
- outRanking.getSuppressedVisualEffects()),
- rankingOverrides.getInt(OVERRIDE_IMPORTANCE, outRanking.getImportance()),
- rankingOverrides.getCharSequence(OVERRIDE_IMP_EXP,
- outRanking.getImportanceExplanation()),
- rankingOverrides.getString(OVERRIDE_GROUP, outRanking.getOverrideGroupKey()),
- rankingOverrides.containsKey(OVERRIDE_CHANNEL)
- ? (NotificationChannel) rankingOverrides.getParcelable(OVERRIDE_CHANNEL)
- : outRanking.getChannel(),
- rankingOverrides.containsKey(OVERRIDE_PEOPLE)
- ? rankingOverrides.getStringArrayList(OVERRIDE_PEOPLE)
- : currentAdditionalPeople,
- rankingOverrides.containsKey(OVERRIDE_SNOOZE_CRITERIA)
- ? rankingOverrides.getParcelableArrayList(OVERRIDE_SNOOZE_CRITERIA)
- : currentSnooze,
- rankingOverrides.getBoolean(OVERRIDE_BADGE, outRanking.canShowBadge()),
- rankingOverrides.getInt(OVERRIDE_USER_SENTIMENT, outRanking.getUserSentiment()),
- rankingOverrides.getBoolean(OVERRIDE_HIDDEN, outRanking.isSuspended()),
- rankingOverrides.getLong(OVERRIDE_LAST_ALERTED,
- outRanking.getLastAudiblyAlertedMillis()),
- rankingOverrides.getBoolean(OVERRIDE_NOISY, outRanking.isNoisy()),
- rankingOverrides.containsKey(OVERRIDE_SMART_ACTIONS)
- ? rankingOverrides.getParcelableArrayList(OVERRIDE_SMART_ACTIONS)
- : currentActions,
- rankingOverrides.containsKey(OVERRIDE_SMART_REPLIES)
- ? rankingOverrides.getCharSequenceArrayList(OVERRIDE_SMART_REPLIES)
- : currentReplies,
- rankingOverrides.getBoolean(OVERRIDE_BUBBLE, outRanking.canBubble()));
+ if (rankingOverrides.get(key) != null) {
+ Bundle overrides = rankingOverrides.get(key);
+ outRanking.populate(key,
+ overrides.getInt(OVERRIDE_RANK, outRanking.getRank()),
+ overrides.getBoolean(OVERRIDE_DND, outRanking.matchesInterruptionFilter()),
+ overrides.getInt(OVERRIDE_VIS_OVERRIDE, outRanking.getVisibilityOverride()),
+ overrides.getInt(OVERRIDE_VIS_EFFECTS,
+ outRanking.getSuppressedVisualEffects()),
+ overrides.getInt(OVERRIDE_IMPORTANCE, outRanking.getImportance()),
+ overrides.getCharSequence(OVERRIDE_IMP_EXP,
+ outRanking.getImportanceExplanation()),
+ overrides.getString(OVERRIDE_GROUP, outRanking.getOverrideGroupKey()),
+ overrides.containsKey(OVERRIDE_CHANNEL)
+ ? (NotificationChannel) overrides.getParcelable(OVERRIDE_CHANNEL)
+ : outRanking.getChannel(),
+ overrides.containsKey(OVERRIDE_PEOPLE)
+ ? overrides.getStringArrayList(OVERRIDE_PEOPLE)
+ : currentAdditionalPeople,
+ overrides.containsKey(OVERRIDE_SNOOZE_CRITERIA)
+ ? overrides.getParcelableArrayList(OVERRIDE_SNOOZE_CRITERIA)
+ : currentSnooze,
+ overrides.getBoolean(OVERRIDE_BADGE, outRanking.canShowBadge()),
+ overrides.getInt(OVERRIDE_USER_SENTIMENT, outRanking.getUserSentiment()),
+ overrides.getBoolean(OVERRIDE_HIDDEN, outRanking.isSuspended()),
+ overrides.getLong(OVERRIDE_LAST_ALERTED,
+ outRanking.getLastAudiblyAlertedMillis()),
+ overrides.getBoolean(OVERRIDE_NOISY, outRanking.isNoisy()),
+ overrides.containsKey(OVERRIDE_SMART_ACTIONS)
+ ? overrides.getParcelableArrayList(OVERRIDE_SMART_ACTIONS)
+ : currentActions,
+ overrides.containsKey(OVERRIDE_SMART_REPLIES)
+ ? overrides.getCharSequenceArrayList(OVERRIDE_SMART_REPLIES)
+ : currentReplies,
+ overrides.getBoolean(OVERRIDE_BUBBLE, outRanking.canBubble()));
+ }
return true;
}
}