summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Caitlin Shkuratov <caitlinshk@google.com> 2025-01-13 16:57:15 +0000
committer Caitlin Shkuratov <caitlinshk@google.com> 2025-01-15 15:26:21 +0000
commit77fb9ee03d9374e7a7f0ca5b701520d8a2278319 (patch)
tree992bd563277687d2d726e281a5bbd5ce9242d44a
parentf3bc47b0d3e041b53f9c74200cf7f254aabafcb1 (diff)
[SB][Notif] Ensure promoted notifications are never sticky.
This is done by making sure `isSticky()` returns false if the notification is promoted. This means promoted notifications won't be sticky if you tap the status bar chip to show the HUN, or if an app posting a promoted notification makes it alert. Note: In practice, I think this case isn't possible because `mExpanded` should only be set to true when the expansion caret is tapped and RONs shouldn't show the expansion caret. But this adds protection just in case. Fixes: 385727186 Bug: 364653005 Flag: com.android.systemui.status_bar_notification_chips Test: Post two RONs, tap on one status bar chip to show HUN, then tap expansion caret on the HUN. Then, tap the other status bar chip -> verify HUN for the other chip shows Test: atest HeadsUpManagerImplTest Change-Id: Ibce9cb64125deeb00fff532033ea73c31c5a8654
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java39
5 files changed, 80 insertions, 5 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
index 739a9c956178..9dfc922eb7d0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImplTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification.headsup
import android.app.Notification
+import android.app.Notification.FLAG_PROMOTED_ONGOING
import android.app.PendingIntent
import android.app.Person
import android.os.Handler
@@ -677,10 +678,12 @@ class HeadsUpManagerImplTest(flags: FlagsParameterization) : SysuiTestCase() {
}
@Test
- fun testIsSticky_rowPinnedAndExpanded_true() {
- val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
- val row = testHelper.createRow()
- row.setPinnedStatus(PinnedStatus.PinnedBySystem)
+ @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+ fun testIsSticky_promotedAndExpanded_notifChipsFlagOff_true() {
+ val notif = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+ notif.flags = FLAG_PROMOTED_ONGOING
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, notif)
+ val row = testHelper.createRow().apply { setPinnedStatus(PinnedStatus.PinnedBySystem) }
notifEntry.row = row
underTest.showNotification(notifEntry)
@@ -692,6 +695,23 @@ class HeadsUpManagerImplTest(flags: FlagsParameterization) : SysuiTestCase() {
}
@Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ fun testIsSticky_promotedAndExpanded_notifChipsFlagOn_false() {
+ val notif = Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+ notif.flags = FLAG_PROMOTED_ONGOING
+ val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, notif)
+ val row = testHelper.createRow().apply { setPinnedStatus(PinnedStatus.PinnedBySystem) }
+ notifEntry.row = row
+
+ underTest.showNotification(notifEntry)
+
+ val headsUpEntry = underTest.getHeadsUpEntry(notifEntry.key)
+ headsUpEntry!!.setExpanded(true)
+
+ assertThat(underTest.isSticky(notifEntry.key)).isFalse()
+ }
+
+ @Test
fun testIsSticky_remoteInputActive_true() {
val notifEntry = HeadsUpManagerTestUtil.createEntry(/* id= */ 0, mContext)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index c38b84b710bc..417e57d2205f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -34,6 +34,8 @@ import static com.android.systemui.statusbar.notification.stack.NotificationPrio
import static java.util.Objects.requireNonNull;
+import android.annotation.FlaggedApi;
+import android.app.Flags;
import android.app.Notification;
import android.app.Notification.MessagingStyle.Message;
import android.app.NotificationChannel;
@@ -1091,6 +1093,14 @@ public final class NotificationEntry extends ListEntry {
}
/**
+ * Returns whether the NotificationEntry is promoted ongoing.
+ */
+ @FlaggedApi(Flags.FLAG_API_RICH_ONGOING)
+ public boolean isPromotedOngoing() {
+ return PromotedNotificationContentModel.isPromotedForStatusBarChip(mSbn.getNotification());
+ }
+
+ /**
* Sets the content needed to render this notification as a promoted notification on various
* surfaces (like status bar chips and AOD).
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
index d02e17cab534..0171fb72e158 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/headsup/HeadsUpManagerImpl.java
@@ -1425,7 +1425,12 @@ public class HeadsUpManagerImpl
}
}
- return (mEntry.isRowPinned() && mExpanded)
+ // Promoted notifications are always shown as expanded, and we don't want them to ever
+ // be sticky.
+ boolean isStickyDueToExpansion =
+ mEntry.isRowPinned() && mExpanded && !mEntry.isPromotedOngoing();
+
+ return isStickyDueToExpansion
|| mRemoteInputActive
|| hasFullScreenIntent(mEntry);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
index 258d80c60cd7..a175f90c384a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
@@ -147,6 +147,7 @@ data class PromotedNotificationContentModel(
* Returns true if the given notification should be considered promoted when deciding
* whether or not to show the status bar chip UI.
*/
+ @JvmStatic
fun isPromotedForStatusBarChip(notification: Notification): Boolean {
// Notification.isPromotedOngoing checks the ui_rich_ongoing flag, but we want the
// status bar chip to be ready before all the features behind the ui_rich_ongoing flag
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 72d1db3affe8..281ce16b539f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -22,6 +22,7 @@ import static android.app.Notification.CATEGORY_EVENT;
import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.Notification.CATEGORY_REMINDER;
import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
+import static android.app.Notification.FLAG_PROMOTED_ONGOING;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
@@ -43,6 +44,8 @@ import android.graphics.drawable.Icon;
import android.media.session.MediaSession;
import android.os.Bundle;
import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
@@ -54,6 +57,8 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.res.R;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.SbnBuilder;
+import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
+import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
@@ -280,6 +285,40 @@ public class NotificationEntryTest extends SysuiTestCase {
}
@Test
+ @EnableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
+ public void isPromotedOngoing_noFlagOnNotif_false() {
+ mEntry.getSbn().getNotification().flags &= ~FLAG_PROMOTED_ONGOING;
+
+ assertFalse(mEntry.isPromotedOngoing());
+ }
+
+ @Test
+ @DisableFlags({PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME})
+ public void isPromotedOngoing_statusBarNotifChipsFlagAndUiFlagOff_false() {
+ mEntry.getSbn().getNotification().flags |= FLAG_PROMOTED_ONGOING;
+
+ assertFalse(mEntry.isPromotedOngoing());
+ }
+
+ @Test
+ @EnableFlags(PromotedNotificationUi.FLAG_NAME)
+ @DisableFlags(StatusBarNotifChips.FLAG_NAME)
+ public void isPromotedOngoing_uiFlagOnAndNotifHasFlag_true() {
+ mEntry.getSbn().getNotification().flags |= FLAG_PROMOTED_ONGOING;
+
+ assertTrue(mEntry.isPromotedOngoing());
+ }
+
+ @Test
+ @EnableFlags(StatusBarNotifChips.FLAG_NAME)
+ @DisableFlags(PromotedNotificationUi.FLAG_NAME)
+ public void isPromotedOngoing_statusBarNotifChipsFlagOnAndNotifHasFlag_true() {
+ mEntry.getSbn().getNotification().flags |= FLAG_PROMOTED_ONGOING;
+
+ assertTrue(mEntry.isPromotedOngoing());
+ }
+
+ @Test
public void testIsNotificationVisibilityPrivate_true() {
assertTrue(mEntry.isNotificationVisibilityPrivate());
}