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

Commit 0fbfb69b authored by Jeff DeCew's avatar Jeff DeCew
Browse files

NotifCollection.dismissNotifications now takes EntryWithDismissStats instead of Pair

The change from Pair is unflagged, but the creation of copyForEntry is flagged.

Bug: 355967751
Flag: EXEMPT unflaggable readability type change
Flag: com.android.systemui.notifications_dismiss_pruned_summaries
Test: atest NotifCollectionTest
Change-Id: If4da4caec7a02782ea23bade5ab452fd58cae633
parent 0248b5c8
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.notification.collection

import com.android.internal.statusbar.NotificationVisibility
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats

/**
 * A holder class for a [NotificationEntry] and an associated [DismissedByUserStats], used by
 * [NotifCollection] for handling dismissal.
 */
data class EntryWithDismissStats(val entry: NotificationEntry, val stats: DismissedByUserStats) {
    /**
     * Creates deep a copy of this object, but with the entry, key and rank updated to correspond to
     * the given entry.
     */
    fun copyForEntry(newEntry: NotificationEntry) =
        EntryWithDismissStats(
            entry = newEntry,
            stats =
                DismissedByUserStats(
                    stats.dismissalSurface,
                    stats.dismissalSentiment,
                    NotificationVisibility.obtain(
                        newEntry.key,
                        newEntry.ranking.rank,
                        stats.notificationVisibility.count,
                        /* visible= */ false,
                    ),
                ),
        )
}
+12 −25
Original line number Diff line number Diff line
@@ -63,14 +63,12 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
@@ -276,7 +274,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
     * Dismisses multiple notifications on behalf of the user.
     */
    public void dismissNotifications(
            List<Pair<NotificationEntry, DismissedByUserStats>> entriesToDismiss) {
            List<EntryWithDismissStats> entriesToDismiss) {
        Assert.isMainThread();
        checkForReentrantCall();

@@ -287,8 +285,8 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
        final int entryCount = entriesToDismiss.size();
        final List<NotificationEntry> entriesToLocallyDismiss = new ArrayList<>();
        for (int i = 0; i < entriesToDismiss.size(); i++) {
            NotificationEntry entry = entriesToDismiss.get(i).first;
            DismissedByUserStats stats = entriesToDismiss.get(i).second;
            NotificationEntry entry = entriesToDismiss.get(i).getEntry();
            DismissedByUserStats stats = entriesToDismiss.get(i).getStats();

            requireNonNull(stats);
            NotificationEntry storedEntry = mNotificationSet.get(entry.getKey());
@@ -343,31 +341,20 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
        dispatchEventsAndRebuildList("dismissNotifications");
    }

    private List<Pair<NotificationEntry, DismissedByUserStats>> includeSummariesToDismiss(
            List<Pair<NotificationEntry, DismissedByUserStats>> entriesToDismiss) {
    private List<EntryWithDismissStats> includeSummariesToDismiss(
            List<EntryWithDismissStats> entriesToDismiss) {
        final HashSet<NotificationEntry> entriesSet = new HashSet<>(entriesToDismiss.size());
        for (Pair<NotificationEntry, DismissedByUserStats> entryToStats : entriesToDismiss) {
            entriesSet.add(entryToStats.first);
        for (EntryWithDismissStats entryToStats : entriesToDismiss) {
            entriesSet.add(entryToStats.getEntry());
        }

        final List<Pair<NotificationEntry, DismissedByUserStats>> entriesPlusSummaries =
        final List<EntryWithDismissStats> entriesPlusSummaries =
                new ArrayList<>(entriesToDismiss.size() + 1);
        for (Pair<NotificationEntry, DismissedByUserStats> entryToStats : entriesToDismiss) {
        for (EntryWithDismissStats entryToStats : entriesToDismiss) {
            entriesPlusSummaries.add(entryToStats);
            NotificationEntry summary = fetchSummaryToDismiss(entryToStats.first);
            NotificationEntry summary = fetchSummaryToDismiss(entryToStats.getEntry());
            if (summary != null && !entriesSet.contains(summary)) {
                DismissedByUserStats currentStats = entryToStats.second;
                NotificationVisibility summaryVisibility = NotificationVisibility.obtain(
                        summary.getKey(),
                        summary.getRanking().getRank(),
                        currentStats.notificationVisibility.count,
                        /* visible= */ false);
                DismissedByUserStats summaryStats = new DismissedByUserStats(
                        currentStats.dismissalSurface,
                        currentStats.dismissalSentiment,
                        summaryVisibility
                );
                entriesPlusSummaries.add(new Pair<>(summary, summaryStats));
                entriesPlusSummaries.add(entryToStats.copyForEntry(summary));
            }
        }
        return entriesPlusSummaries;
@@ -379,7 +366,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
    public void dismissNotification(
            NotificationEntry entry,
            @NonNull DismissedByUserStats stats) {
        dismissNotifications(List.of(new Pair<>(entry, stats)));
        dismissNotifications(List.of(new EntryWithDismissStats(entry, stats)));
    }

    /**
+3 −3
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.util.Pair;
import android.util.Property;
import android.view.Display;
import android.view.MotionEvent;
@@ -105,6 +104,7 @@ import com.android.systemui.statusbar.notification.HeadsUpTouchHelper.HeadsUpNot
import com.android.systemui.statusbar.notification.LaunchAnimationParameters;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.EntryWithDismissStats;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -1777,12 +1777,12 @@ public class NotificationStackScrollLayoutController implements Dumpable {
            mNotifCollection.dismissAllNotifications(
                    mLockscreenUserManager.getCurrentUserId());
        } else {
            final List<Pair<NotificationEntry, DismissedByUserStats>>
            final List<EntryWithDismissStats>
                    entriesWithRowsDismissedFromShade = new ArrayList<>();
            for (ExpandableNotificationRow row : viewsToRemove) {
                final NotificationEntry entry = row.getEntry();
                entriesWithRowsDismissedFromShade.add(
                        new Pair<>(entry, getDismissedByUserStats(entry)));
                        new EntryWithDismissStats(entry, getDismissedByUserStats(entry)));
            }
            mNotifCollection.dismissNotifications(entriesWithRowsDismissedFromShade);
        }
+14 −11
Original line number Diff line number Diff line
@@ -72,7 +72,6 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;

import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
@@ -1292,8 +1291,8 @@ public class NotifCollectionTest extends SysuiTestCase {

        // WHEN both notifications are manually dismissed together
        mCollection.dismissNotifications(
                List.of(new Pair<>(entry1, defaultStats(entry1)),
                        new Pair<>(entry2, defaultStats(entry2))));
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));

        // THEN build list is only called one time
        verifyBuiltList(List.of(entry1, entry2));
@@ -1311,8 +1310,8 @@ public class NotifCollectionTest extends SysuiTestCase {
        DismissedByUserStats stats1 = defaultStats(entry1);
        DismissedByUserStats stats2 = defaultStats(entry2);
        mCollection.dismissNotifications(
                List.of(new Pair<>(entry1, defaultStats(entry1)),
                        new Pair<>(entry2, defaultStats(entry2))));
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));

        // THEN we send the dismissals to system server
        FakeExecutor.exhaustExecutors(mBgExecutor);
@@ -1343,8 +1342,8 @@ public class NotifCollectionTest extends SysuiTestCase {

        // WHEN both notifications are manually dismissed together
        mCollection.dismissNotifications(
                List.of(new Pair<>(entry1, defaultStats(entry1)),
                        new Pair<>(entry2, defaultStats(entry2))));
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));

        // THEN the entries are marked as dismissed
        assertEquals(DISMISSED, entry1.getDismissState());
@@ -1368,8 +1367,8 @@ public class NotifCollectionTest extends SysuiTestCase {

        // WHEN both notifications are manually dismissed together
        mCollection.dismissNotifications(
                List.of(new Pair<>(entry1, defaultStats(entry1)),
                        new Pair<>(entry2, defaultStats(entry2))));
                List.of(entryWithDefaultStats(entry1),
                        entryWithDefaultStats(entry2)));

        // THEN all interceptors get checked
        verify(mInterceptor1).shouldInterceptDismissal(entry1);
@@ -1409,8 +1408,8 @@ public class NotifCollectionTest extends SysuiTestCase {

        // WHEN one child from each group are manually dismissed together
        mCollection.dismissNotifications(
                List.of(new Pair<>(entry1child, defaultStats(entry1child)),
                        new Pair<>(entry2child1, defaultStats(entry2child1))));
                List.of(entryWithDefaultStats(entry1child),
                        entryWithDefaultStats(entry2child1)));

        // THEN the summary for the singleton child is dismissed, but not the other summary
        verify(mInterceptor1).shouldInterceptDismissal(entry1summary);
@@ -1806,6 +1805,10 @@ public class NotifCollectionTest extends SysuiTestCase {
                NotificationVisibility.obtain(entry.getKey(), 7, 2, true));
    }

    private static EntryWithDismissStats entryWithDefaultStats(NotificationEntry entry) {
        return new EntryWithDismissStats(entry, defaultStats(entry));
    }

    private CollectionEvent postNotif(NotificationEntryBuilder builder) {
        clearInvocations(mCollectionListener);
        NotifEvent rawEvent = mNoMan.postNotif(builder);