diff options
| author | 2025-01-13 16:57:15 +0000 | |
|---|---|---|
| committer | 2025-01-15 15:26:21 +0000 | |
| commit | 77fb9ee03d9374e7a7f0ca5b701520d8a2278319 (patch) | |
| tree | 992bd563277687d2d726e281a5bbd5ce9242d44a | |
| parent | f3bc47b0d3e041b53f9c74200cf7f254aabafcb1 (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
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()); } |