Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35d4c4df authored by Steve Elliott's avatar Steve Elliott
Browse files

dismissability for bundles

Bug: 394483200
Bug: 389839319
Test: atest SystemUITests
Flag: com.android.systemui.notification_bundle_ui
Change-Id: Ib57acf166989144bd2972faabe19ed3297b0f8b1
parent b89e6029
Loading
Loading
Loading
Loading
+23 −17
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No
import com.android.systemui.statusbar.notification.collection.notifcollection.UpdateSource;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;

@@ -1288,9 +1289,9 @@ public class NotifCollectionTest extends SysuiTestCase {
        clearInvocations(mBuildListener);

        // WHEN both notifications are manually dismissed together
        mCollection.dismissNotifications(
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));
        List<EntryWithDismissStats> entriesToDismiss = List.of(entryWithDefaultStats(entry1),
                entryWithDefaultStats(entry2));
        mCollection.dismissNotifications(entriesToDismiss, /* fromBundle= */ false);

        // THEN build list is only called one time
        verifyBuiltList(List.of(entry1, entry2));
@@ -1307,9 +1308,9 @@ public class NotifCollectionTest extends SysuiTestCase {
        // WHEN both notifications are manually dismissed together
        DismissedByUserStats stats1 = defaultStats(entry1);
        DismissedByUserStats stats2 = defaultStats(entry2);
        mCollection.dismissNotifications(
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));
        List<EntryWithDismissStats> entriesToDismiss = List.of(entryWithDefaultStats(entry1),
                entryWithDefaultStats(entry2));
        mCollection.dismissNotifications(entriesToDismiss, /* fromBundle= */ false);

        // THEN we send the dismissals to system server
        FakeExecutor.exhaustExecutors(mBgExecutor);
@@ -1339,9 +1340,9 @@ public class NotifCollectionTest extends SysuiTestCase {
        NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key);

        // WHEN both notifications are manually dismissed together
        mCollection.dismissNotifications(
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));
        List<EntryWithDismissStats> entriesToDismiss = List.of(entryWithDefaultStats(entry1),
                entryWithDefaultStats(entry2));
        mCollection.dismissNotifications(entriesToDismiss, /* fromBundle= */ false);

        // THEN the entries are marked as dismissed
        assertEquals(DISMISSED, entry1.getDismissState());
@@ -1364,9 +1365,9 @@ public class NotifCollectionTest extends SysuiTestCase {
        NotificationEntry entry2 = mCollectionListener.getEntry(notif2.key);

        // WHEN both notifications are manually dismissed together
        mCollection.dismissNotifications(
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));
        List<EntryWithDismissStats> entriesToDismiss = List.of(entryWithDefaultStats(entry1),
                entryWithDefaultStats(entry2));
        mCollection.dismissNotifications(entriesToDismiss, /* fromBundle= */ false);

        // THEN all interceptors get checked
        verify(mInterceptor1).shouldInterceptDismissal(entry1);
@@ -1404,9 +1405,9 @@ public class NotifCollectionTest extends SysuiTestCase {
        NotificationEntry entry2child2 = mCollectionListener.getEntry(notif2child2.key);

        // WHEN one child from each group are manually dismissed together
        mCollection.dismissNotifications(
                List.of(entryWithDefaultStats(entry1child),
                        entryWithDefaultStats(entry2child1)));
        List<EntryWithDismissStats> entriesToDismiss = List.of(entryWithDefaultStats(entry1child),
                entryWithDefaultStats(entry2child1));
        mCollection.dismissNotifications(entriesToDismiss, /* fromBundle= */ false);

        // THEN the summary for the singleton child is dismissed, but not the other summary
        verify(mInterceptor1).shouldInterceptDismissal(entry1summary);
@@ -1804,9 +1805,14 @@ public class NotifCollectionTest extends SysuiTestCase {
    }

    private static EntryWithDismissStats entryWithDefaultStats(NotificationEntry entry) {
        if (NotificationBundleUi.isEnabled()) {
            return new EntryWithDismissStats(
                    null, defaultStats(entry), entry.getKey(), entry.hashCode());
        } else {
            return new EntryWithDismissStats(
                    entry, defaultStats(entry), entry.getKey(), entry.hashCode());
        }
    }

    private CollectionEvent postNotif(NotificationEntryBuilder builder) {
        clearInvocations(mCollectionListener);
+23 −26
Original line number Diff line number Diff line
@@ -38,9 +38,9 @@ import com.android.systemui.statusbar.notification.collection.provider.mockHighP
import com.android.systemui.statusbar.notification.mockNotificationActivityStarter
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback
import com.android.systemui.statusbar.notification.row.entryAdapterFactory
import com.android.systemui.statusbar.notification.row.mockNotificationActionClickManager
import com.android.systemui.statusbar.notification.row.onUserInteractionCallback
import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
import com.android.systemui.testKosmos
@@ -50,10 +50,10 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mockito
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

@SmallTest
@@ -61,7 +61,7 @@ import org.mockito.kotlin.whenever
@RunWithLooper
@EnableFlags(NotificationBundleUi.FLAG_NAME)
class NotificationEntryAdapterTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val kosmos = testKosmos().apply { onUserInteractionCallback = mock() }

    private val factory: EntryAdapterFactory = kosmos.entryAdapterFactory
    private lateinit var underTest: NotificationEntryAdapter
@@ -506,7 +506,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
    }

    @Test
    fun getDismissState() {
    fun isParentDismissed() {
        val notification: Notification =
            Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()

@@ -515,7 +515,7 @@ class NotificationEntryAdapterTest : SysuiTestCase() {

        underTest = factory.create(entry) as NotificationEntryAdapter

        assertThat(underTest.dismissState).isEqualTo(entry.dismissState)
        assertThat(underTest.isParentDismissed).isTrue()
    }

    @Test
@@ -542,15 +542,13 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
                .addAction(mock())
                .build()
        val entry = NotificationEntryBuilder().setNotification(notification).build()
        val callback: OnUserInteractionCallback = mock()
        whenever(callback.registerFutureDismissal(any(), any())).thenReturn(mock())
        val callback = kosmos.onUserInteractionCallback
        whenever(callback.registerFutureDismissal(any<NotificationEntry>(), any()))
            .thenReturn(mock())

        underTest = factory.create(entry) as NotificationEntryAdapter

        underTest.registerFutureDismissal(
            callback,
            REASON_CANCEL,
        )
        underTest.registerFutureDismissal()
        verify(callback).registerFutureDismissal(entry, REASON_CANCEL)
    }

@@ -569,11 +567,10 @@ class NotificationEntryAdapterTest : SysuiTestCase() {
    @Test
    fun isBundled() {
        val notification: Notification =
            Notification.Builder(mContext, "")
                .setSmallIcon(R.drawable.ic_person)
                .build()
            Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()

        val entry = NotificationEntryBuilder()
        val entry =
            NotificationEntryBuilder()
                .setNotification(notification)
                .setChannel(NotificationChannel(NEWS_ID, NEWS_ID, 2))
                .build()
+2 −1
Original line number Diff line number Diff line
@@ -131,7 +131,8 @@ public class PromotedNotificationInfoTest extends SysuiTestCase {
                mock(VisualStabilityCoordinator.class),
                mock(NotificationActionClickManager.class),
                mock(HighPriorityProvider.class),
                mock(HeadsUpManager.class)
                mock(HeadsUpManager.class),
                mOnUserInteractionCallback
        ).create(mEntry);
        mRanking = mEntry.getRanking();
        when(mAssistantFeedbackController.isFeedbackEnabled()).thenReturn(false);
+5 −10
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import kotlinx.coroutines.flow.StateFlow

class BundleEntryAdapter(
    private val highPriorityProvider: HighPriorityProvider,
    private val onUserInteractionCallback: OnUserInteractionCallback,
    val entry: BundleEntry,
) : EntryAdapter {

@@ -189,10 +190,8 @@ class BundleEntryAdapter(
        Log.wtf(TAG, "onNotificationActionClicked() called")
    }

    override fun getDismissState(): NotificationEntry.DismissState {
        // TODO(b/394483200): setDismissState is only called in NotifCollection so it does not
        //  work on bundles yet
        return NotificationEntry.DismissState.NOT_DISMISSED
    override fun isParentDismissed(): Boolean {
        return false
    }

    override fun onEntryClicked(row: ExpandableNotificationRow) {
@@ -227,12 +226,8 @@ class BundleEntryAdapter(
        Log.wtf(TAG, "onEntryAnimatingAwayEnded() called")
    }

    override fun registerFutureDismissal(
        callback: OnUserInteractionCallback,
        reason: Int,
    ): Runnable? {
        // TODO(b/389839319): what should the pipeline do when a bundle is dismissed?
        return null
    override fun registerFutureDismissal(): Runnable {
        return onUserInteractionCallback.registerFutureDismissal(entry)
    }

    override fun markForReinflation(stage: RowContentBindStage) {
+4 −4
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import com.android.systemui.statusbar.notification.icon.IconPack;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotifBindPipeline;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.notification.row.RowContentBindStage;

import kotlinx.coroutines.flow.StateFlow;
@@ -200,8 +199,6 @@ public interface EntryAdapter {
     */
    void onNotificationActionClicked();

    NotificationEntry.DismissState getDismissState();

    void onEntryClicked(ExpandableNotificationRow row);

    @Nullable RemoteInputEntryAdapter getRemoteInputEntryAdapter();
@@ -220,7 +217,8 @@ public interface EntryAdapter {

    void onEntryAnimatingAwayEnded();

    Runnable registerFutureDismissal(@NonNull OnUserInteractionCallback callback, int reason);
    @NonNull
    Runnable registerFutureDismissal();

    void markForReinflation(@NonNull RowContentBindStage stage);

@@ -234,6 +232,8 @@ public interface EntryAdapter {
     */
    boolean isBundled();

    boolean isParentDismissed();

    /**
     * Returns whether this entry *is* a bundle.
     */
Loading