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

Commit 05023573 authored by Jeff DeCew's avatar Jeff DeCew Committed by Automerger Merge Worker
Browse files

Fix NotificationEntry mismatch crashes when tapping notification. am: 4a206a41

parents c85d40aa 4a206a41
Loading
Loading
Loading
Loading
+149 −8
Original line number Original line Diff line number Diff line
@@ -18,9 +18,12 @@ package com.android.systemui.statusbar.notification.collection;


import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_ASSISTANT_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_CHANNEL_BANNED;
import static android.service.notification.NotificationListenerService.REASON_CHANNEL_BANNED;
import static android.service.notification.NotificationListenerService.REASON_CHANNEL_REMOVED;
import static android.service.notification.NotificationListenerService.REASON_CLEAR_DATA;
import static android.service.notification.NotificationListenerService.REASON_CLICK;
import static android.service.notification.NotificationListenerService.REASON_CLICK;
import static android.service.notification.NotificationListenerService.REASON_ERROR;
import static android.service.notification.NotificationListenerService.REASON_ERROR;
import static android.service.notification.NotificationListenerService.REASON_GROUP_OPTIMIZATION;
import static android.service.notification.NotificationListenerService.REASON_GROUP_OPTIMIZATION;
@@ -36,9 +39,11 @@ import static android.service.notification.NotificationListenerService.REASON_TI
import static android.service.notification.NotificationListenerService.REASON_UNAUTOBUNDLED;
import static android.service.notification.NotificationListenerService.REASON_UNAUTOBUNDLED;
import static android.service.notification.NotificationListenerService.REASON_USER_STOPPED;
import static android.service.notification.NotificationListenerService.REASON_USER_STOPPED;


import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.DISMISSED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.DISMISSED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.NOT_DISMISSED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.NOT_DISMISSED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.PARENT_DISMISSED;
import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.PARENT_DISMISSED;
import static com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionLoggerKt.cancellationReasonDebugString;


import static java.util.Objects.requireNonNull;
import static java.util.Objects.requireNonNull;


@@ -99,6 +104,7 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collection;
import java.util.Collections;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;
@@ -143,6 +149,7 @@ public class NotifCollection implements Dumpable {
    private final Map<String, NotificationEntry> mNotificationSet = new ArrayMap<>();
    private final Map<String, NotificationEntry> mNotificationSet = new ArrayMap<>();
    private final Collection<NotificationEntry> mReadOnlyNotificationSet =
    private final Collection<NotificationEntry> mReadOnlyNotificationSet =
            Collections.unmodifiableCollection(mNotificationSet.values());
            Collections.unmodifiableCollection(mNotificationSet.values());
    private final HashMap<String, FutureDismissal> mFutureDismissals = new HashMap<>();


    @Nullable private CollectionReadyForBuildListener mBuildListener;
    @Nullable private CollectionReadyForBuildListener mBuildListener;
    private final List<NotifCollectionListener> mNotifCollectionListeners = new ArrayList<>();
    private final List<NotifCollectionListener> mNotifCollectionListeners = new ArrayList<>();
@@ -511,6 +518,7 @@ public class NotifCollection implements Dumpable {
            cancelDismissInterception(entry);
            cancelDismissInterception(entry);
            mEventQueue.add(new EntryRemovedEvent(entry, entry.mCancellationReason));
            mEventQueue.add(new EntryRemovedEvent(entry, entry.mCancellationReason));
            mEventQueue.add(new CleanUpEntryEvent(entry));
            mEventQueue.add(new CleanUpEntryEvent(entry));
            handleFutureDismissal(entry);
            return true;
            return true;
        } else {
        } else {
            return false;
            return false;
@@ -519,31 +527,32 @@ public class NotifCollection implements Dumpable {


    /**
    /**
     * Get the group summary entry
     * Get the group summary entry
     * @param group
     * @param groupKey
     * @return
     * @return
     */
     */
    @Nullable
    @Nullable
    public NotificationEntry getGroupSummary(String group) {
    public NotificationEntry getGroupSummary(String groupKey) {
        return mNotificationSet
        return mNotificationSet
                .values()
                .values()
                .stream()
                .stream()
                .filter(it -> Objects.equals(it.getSbn().getGroup(), group))
                .filter(it -> Objects.equals(it.getSbn().getGroupKey(), groupKey))
                .filter(it -> it.getSbn().getNotification().isGroupSummary())
                .filter(it -> it.getSbn().getNotification().isGroupSummary())
                .findFirst().orElse(null);
                .findFirst().orElse(null);
    }
    }


    /**
    /**
     * Checks if the entry is the only child in the logical group
     * Checks if the entry is the only child in the logical group;
     * @param entry
     * it need not have a summary to qualify
     * @return
     *
     * @param entry the entry to check
     */
     */
    public boolean isOnlyChildInGroup(NotificationEntry entry) {
    public boolean isOnlyChildInGroup(NotificationEntry entry) {
        String group = entry.getSbn().getGroup();
        String groupKey = entry.getSbn().getGroupKey();
        return mNotificationSet.get(entry.getKey()) == entry
        return mNotificationSet.get(entry.getKey()) == entry
                && mNotificationSet
                && mNotificationSet
                .values()
                .values()
                .stream()
                .stream()
                .filter(it -> Objects.equals(it.getSbn().getGroup(), group))
                .filter(it -> Objects.equals(it.getSbn().getGroupKey(), groupKey))
                .filter(it -> !it.getSbn().getNotification().isGroupSummary())
                .filter(it -> !it.getSbn().getNotification().isGroupSummary())
                .count() == 1;
                .count() == 1;
    }
    }
@@ -916,10 +925,139 @@ public class NotifCollection implements Dumpable {
        dispatchEventsAndRebuildList();
        dispatchEventsAndRebuildList();
    }
    }


    /**
     * A method to alert the collection that an async operation is happening, at the end of which a
     * dismissal request will be made.  This method has the additional guarantee that if a parent
     * notification exists for a single child, then that notification will also be dismissed.
     *
     * The runnable returned must be run at the end of the async operation to enact the cancellation
     *
     * @param entry the notification we want to dismiss
     * @param cancellationReason the reason for the cancellation
     * @param statsCreator the callback for generating the stats for an entry
     * @return the runnable to be run when the dismissal is ready to happen
     */
    public Runnable registerFutureDismissal(NotificationEntry entry, int cancellationReason,
            DismissedByUserStatsCreator statsCreator) {
        FutureDismissal dismissal = mFutureDismissals.get(entry.getKey());
        if (dismissal != null) {
            mLogger.logFutureDismissalReused(dismissal);
            return dismissal;
        }
        dismissal = new FutureDismissal(entry, cancellationReason, statsCreator);
        mFutureDismissals.put(entry.getKey(), dismissal);
        mLogger.logFutureDismissalRegistered(dismissal);
        return dismissal;
    }

    private void handleFutureDismissal(NotificationEntry entry) {
        final FutureDismissal futureDismissal = mFutureDismissals.remove(entry.getKey());
        if (futureDismissal != null) {
            futureDismissal.onSystemServerCancel(entry.mCancellationReason);
        }
    }

    /** A single method interface that callers can pass in when registering future dismissals */
    public interface DismissedByUserStatsCreator {
        DismissedByUserStats createDismissedByUserStats(NotificationEntry entry);
    }

    /** A class which tracks the double dismissal events coming in from both the system server and
     * the ui */
    public class FutureDismissal implements Runnable {
        private final NotificationEntry mEntry;
        private final DismissedByUserStatsCreator mStatsCreator;
        @Nullable
        private final NotificationEntry mSummaryToDismiss;
        private final String mLabel;

        private boolean mDidRun;
        private boolean mDidSystemServerCancel;

        private FutureDismissal(NotificationEntry entry, @CancellationReason int cancellationReason,
                DismissedByUserStatsCreator statsCreator) {
            mEntry = entry;
            mStatsCreator = statsCreator;
            mSummaryToDismiss = fetchSummaryToDismiss(entry);
            mLabel = "<FutureDismissal@" + Integer.toHexString(hashCode())
                    + " entry=" + logKey(mEntry)
                    + " reason=" + cancellationReasonDebugString(cancellationReason)
                    + " summary=" + logKey(mSummaryToDismiss)
                    + ">";
        }

        @Nullable
        private NotificationEntry fetchSummaryToDismiss(NotificationEntry entry) {
            if (isOnlyChildInGroup(entry)) {
                String group = entry.getSbn().getGroupKey();
                NotificationEntry summary = getGroupSummary(group);
                if (summary != null && summary.isDismissable()) return summary;
            }
            return null;
        }

        /** called when the entry has been removed from the collection */
        public void onSystemServerCancel(@CancellationReason int cancellationReason) {
            Assert.isMainThread();
            if (mDidSystemServerCancel) {
                mLogger.logFutureDismissalDoubleCancelledByServer(this);
                return;
            }
            mLogger.logFutureDismissalGotSystemServerCancel(this, cancellationReason);
            mDidSystemServerCancel = true;
            // TODO: Internally dismiss the summary now instead of waiting for onUiCancel
        }

        private void onUiCancel() {
            mFutureDismissals.remove(mEntry.getKey());
            final NotificationEntry currentEntry = getEntry(mEntry.getKey());
            // generate stats for the entry before dismissing summary, which could affect state
            final DismissedByUserStats stats = mStatsCreator.createDismissedByUserStats(mEntry);
            // dismiss the summary (if it exists)
            if (mSummaryToDismiss != null) {
                final NotificationEntry currentSummary = getEntry(mSummaryToDismiss.getKey());
                if (currentSummary == mSummaryToDismiss) {
                    mLogger.logFutureDismissalDismissing(this, "summary");
                    dismissNotification(mSummaryToDismiss,
                            mStatsCreator.createDismissedByUserStats(mSummaryToDismiss));
                } else {
                    mLogger.logFutureDismissalMismatchedEntry(this, "summary", currentSummary);
                }
            }
            // dismiss this entry (if it is still around)
            if (mDidSystemServerCancel) {
                mLogger.logFutureDismissalAlreadyCancelledByServer(this);
            } else if (currentEntry == mEntry) {
                mLogger.logFutureDismissalDismissing(this, "entry");
                dismissNotification(mEntry, stats);
            } else {
                mLogger.logFutureDismissalMismatchedEntry(this, "entry", currentEntry);
            }
        }

        /** called when the dismissal should be completed */
        @Override
        public void run() {
            Assert.isMainThread();
            if (mDidRun) {
                mLogger.logFutureDismissalDoubleRun(this);
                return;
            }
            mDidRun = true;
            onUiCancel();
        }

        /** provides a debug label for this instance */
        public String getLabel() {
            return mLabel;
        }
    }

    @IntDef(prefix = { "REASON_" }, value = {
    @IntDef(prefix = { "REASON_" }, value = {
            REASON_NOT_CANCELED,
            REASON_NOT_CANCELED,
            REASON_UNKNOWN,
            REASON_UNKNOWN,
            REASON_CLICK,
            REASON_CLICK,
            REASON_CANCEL,
            REASON_CANCEL_ALL,
            REASON_CANCEL_ALL,
            REASON_ERROR,
            REASON_ERROR,
            REASON_PACKAGE_CHANGED,
            REASON_PACKAGE_CHANGED,
@@ -937,6 +1075,9 @@ public class NotifCollection implements Dumpable {
            REASON_CHANNEL_BANNED,
            REASON_CHANNEL_BANNED,
            REASON_SNOOZED,
            REASON_SNOOZED,
            REASON_TIMEOUT,
            REASON_TIMEOUT,
            REASON_CHANNEL_REMOVED,
            REASON_CLEAR_DATA,
            REASON_ASSISTANT_CANCEL,
    })
    })
    @Retention(RetentionPolicy.SOURCE)
    @Retention(RetentionPolicy.SOURCE)
    public @interface CancellationReason {}
    public @interface CancellationReason {}
+1 −1
Original line number Original line Diff line number Diff line
@@ -93,7 +93,7 @@ class NotifCoordinatorsImpl @Inject constructor(
        mCoordinators.add(shadeEventCoordinator)
        mCoordinators.add(shadeEventCoordinator)
        mCoordinators.add(viewConfigCoordinator)
        mCoordinators.add(viewConfigCoordinator)
        mCoordinators.add(visualStabilityCoordinator)
        mCoordinators.add(visualStabilityCoordinator)
        mCoordinators.add(activityLaunchAnimCoordinator)
//        mCoordinators.add(activityLaunchAnimCoordinator) // NOTE: will delete in followup CL
        if (notifPipelineFlags.isSmartspaceDedupingEnabled()) {
        if (notifPipelineFlags.isSmartspaceDedupingEnabled()) {
            mCoordinators.add(smartspaceDedupingCoordinator)
            mCoordinators.add(smartspaceDedupingCoordinator)
        }
        }
+15 −44
Original line number Original line Diff line number Diff line
@@ -18,17 +18,17 @@ package com.android.systemui.statusbar.notification.collection.inflation;


import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;


import android.annotation.Nullable;
import android.os.SystemClock;
import android.os.SystemClock;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
import android.service.notification.NotificationStats;


import androidx.annotation.NonNull;

import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -43,54 +43,33 @@ public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback
    private final HeadsUpManager mHeadsUpManager;
    private final HeadsUpManager mHeadsUpManager;
    private final StatusBarStateController mStatusBarStateController;
    private final StatusBarStateController mStatusBarStateController;
    private final VisualStabilityCoordinator mVisualStabilityCoordinator;
    private final VisualStabilityCoordinator mVisualStabilityCoordinator;
    private final GroupMembershipManager mGroupMembershipManager;


    public OnUserInteractionCallbackImpl(
    public OnUserInteractionCallbackImpl(
            NotificationVisibilityProvider visibilityProvider,
            NotificationVisibilityProvider visibilityProvider,
            NotifCollection notifCollection,
            NotifCollection notifCollection,
            HeadsUpManager headsUpManager,
            HeadsUpManager headsUpManager,
            StatusBarStateController statusBarStateController,
            StatusBarStateController statusBarStateController,
            VisualStabilityCoordinator visualStabilityCoordinator,
            VisualStabilityCoordinator visualStabilityCoordinator
            GroupMembershipManager groupMembershipManager
    ) {
    ) {
        mVisibilityProvider = visibilityProvider;
        mVisibilityProvider = visibilityProvider;
        mNotifCollection = notifCollection;
        mNotifCollection = notifCollection;
        mHeadsUpManager = headsUpManager;
        mHeadsUpManager = headsUpManager;
        mStatusBarStateController = statusBarStateController;
        mStatusBarStateController = statusBarStateController;
        mVisualStabilityCoordinator = visualStabilityCoordinator;
        mVisualStabilityCoordinator = visualStabilityCoordinator;
        mGroupMembershipManager = groupMembershipManager;
    }
    }


    /**
    @NonNull
     * Callback triggered when a user:
    private DismissedByUserStats getDismissedByUserStats(NotificationEntry entry) {
     * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
     * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
     * {@see StatusBarNotificationActivityStarter}
     */
    @Override
    public void onDismiss(
            NotificationEntry entry,
            @NotificationListenerService.NotificationCancelReason int cancellationReason,
            @Nullable NotificationEntry groupSummaryToDismiss
    ) {
        int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
        int dismissalSurface = NotificationStats.DISMISSAL_SHADE;
        if (mHeadsUpManager.isAlerting(entry.getKey())) {
        if (mHeadsUpManager.isAlerting(entry.getKey())) {
            dismissalSurface = NotificationStats.DISMISSAL_PEEK;
            dismissalSurface = NotificationStats.DISMISSAL_PEEK;
        } else if (mStatusBarStateController.isDozing()) {
        } else if (mStatusBarStateController.isDozing()) {
            dismissalSurface = NotificationStats.DISMISSAL_AOD;
            dismissalSurface = NotificationStats.DISMISSAL_AOD;
        }
        }

        return new DismissedByUserStats(
        if (groupSummaryToDismiss != null) {
            onDismiss(groupSummaryToDismiss, cancellationReason, null);
        }

        mNotifCollection.dismissNotification(
                entry,
                new DismissedByUserStats(
                dismissalSurface,
                dismissalSurface,
                DISMISS_SENTIMENT_NEUTRAL,
                DISMISS_SENTIMENT_NEUTRAL,
                    mVisibilityProvider.obtain(entry, true))
                mVisibilityProvider.obtain(entry, true));
        );
    }
    }


    @Override
    @Override
@@ -100,19 +79,11 @@ public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback
                SystemClock.uptimeMillis());
                SystemClock.uptimeMillis());
    }
    }


    /**
    @NonNull
     * @param entry that is being dismissed
     * @return the group summary to dismiss along with this entry if this is the last entry in
     * the group. Else, returns null.
     */
    @Override
    @Override
    @Nullable
    public Runnable registerFutureDismissal(@NonNull NotificationEntry entry,
    public NotificationEntry getGroupSummaryToDismiss(NotificationEntry entry) {
            @CancellationReason int cancellationReason) {
        String group = entry.getSbn().getGroup();
        return mNotifCollection.registerFutureDismissal(
        if (mNotifCollection.isOnlyChildInGroup(entry)) {
                entry, cancellationReason, this::getDismissedByUserStats);
            NotificationEntry summary = mNotifCollection.getGroupSummary(group);
            if (summary != null && summary.isDismissable()) return summary;
        }
        return null;
    }
    }
}
}
+14 −5
Original line number Original line Diff line number Diff line
@@ -18,12 +18,15 @@ package com.android.systemui.statusbar.notification.collection.legacy;


import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;


import android.annotation.Nullable;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
import android.service.notification.NotificationStats;


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

import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
@@ -68,8 +71,7 @@ public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCal
     *                              along with this dismissal. If null, does not additionally
     *                              along with this dismissal. If null, does not additionally
     *                              dismiss any notifications.
     *                              dismiss any notifications.
     */
     */
    @Override
    private void onDismiss(
    public void onDismiss(
            NotificationEntry entry,
            NotificationEntry entry,
            @NotificationListenerService.NotificationCancelReason int cancellationReason,
            @NotificationListenerService.NotificationCancelReason int cancellationReason,
            @Nullable NotificationEntry groupSummaryToDismiss
            @Nullable NotificationEntry groupSummaryToDismiss
@@ -106,14 +108,21 @@ public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCal
     * @return the group summary to dismiss along with this entry if this is the last entry in
     * @return the group summary to dismiss along with this entry if this is the last entry in
     * the group. Else, returns null.
     * the group. Else, returns null.
     */
     */
    @Override
    @Nullable
    @Nullable
    public NotificationEntry getGroupSummaryToDismiss(NotificationEntry entry) {
    private NotificationEntry getGroupSummaryToDismiss(NotificationEntry entry) {
        if (mGroupMembershipManager.isOnlyChildInGroup(entry)) {
        if (mGroupMembershipManager.isOnlyChildInGroup(entry)) {
            NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(entry);
            NotificationEntry groupSummary = mGroupMembershipManager.getLogicalGroupSummary(entry);
            return groupSummary.isDismissable() ? groupSummary : null;
            return groupSummary.isDismissable() ? groupSummary : null;
        }
        }
        return null;
        return null;
    }
    }

    @Override
    @NonNull
    public Runnable registerFutureDismissal(@NonNull NotificationEntry entry,
            @CancellationReason int cancellationReason) {
        NotificationEntry groupSummaryToDismiss = getGroupSummaryToDismiss(entry);
        return () -> onDismiss(entry, cancellationReason, groupSummaryToDismiss);
    }
}
}
+81 −0
Original line number Original line Diff line number Diff line
@@ -28,7 +28,9 @@ import com.android.systemui.log.LogLevel.WTF
import com.android.systemui.log.dagger.NotificationLog
import com.android.systemui.log.dagger.NotificationLog
import com.android.systemui.statusbar.notification.collection.NotifCollection
import com.android.systemui.statusbar.notification.collection.NotifCollection
import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason
import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason
import com.android.systemui.statusbar.notification.collection.NotifCollection.FutureDismissal
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.logKey
import javax.inject.Inject
import javax.inject.Inject


fun cancellationReasonDebugString(@CancellationReason reason: Int) =
fun cancellationReasonDebugString(@CancellationReason reason: Int) =
@@ -36,6 +38,7 @@ fun cancellationReasonDebugString(@CancellationReason reason: Int) =
        -1 -> "REASON_NOT_CANCELED" // NotifCollection.REASON_NOT_CANCELED
        -1 -> "REASON_NOT_CANCELED" // NotifCollection.REASON_NOT_CANCELED
        NotifCollection.REASON_UNKNOWN -> "REASON_UNKNOWN"
        NotifCollection.REASON_UNKNOWN -> "REASON_UNKNOWN"
        NotificationListenerService.REASON_CLICK -> "REASON_CLICK"
        NotificationListenerService.REASON_CLICK -> "REASON_CLICK"
        NotificationListenerService.REASON_CANCEL -> "REASON_CANCEL"
        NotificationListenerService.REASON_CANCEL_ALL -> "REASON_CANCEL_ALL"
        NotificationListenerService.REASON_CANCEL_ALL -> "REASON_CANCEL_ALL"
        NotificationListenerService.REASON_ERROR -> "REASON_ERROR"
        NotificationListenerService.REASON_ERROR -> "REASON_ERROR"
        NotificationListenerService.REASON_PACKAGE_CHANGED -> "REASON_PACKAGE_CHANGED"
        NotificationListenerService.REASON_PACKAGE_CHANGED -> "REASON_PACKAGE_CHANGED"
@@ -53,6 +56,9 @@ fun cancellationReasonDebugString(@CancellationReason reason: Int) =
        NotificationListenerService.REASON_CHANNEL_BANNED -> "REASON_CHANNEL_BANNED"
        NotificationListenerService.REASON_CHANNEL_BANNED -> "REASON_CHANNEL_BANNED"
        NotificationListenerService.REASON_SNOOZED -> "REASON_SNOOZED"
        NotificationListenerService.REASON_SNOOZED -> "REASON_SNOOZED"
        NotificationListenerService.REASON_TIMEOUT -> "REASON_TIMEOUT"
        NotificationListenerService.REASON_TIMEOUT -> "REASON_TIMEOUT"
        NotificationListenerService.REASON_CHANNEL_REMOVED -> "REASON_CHANNEL_REMOVED"
        NotificationListenerService.REASON_CLEAR_DATA -> "REASON_CLEAR_DATA"
        NotificationListenerService.REASON_ASSISTANT_CANCEL -> "REASON_ASSISTANT_CANCEL"
        else -> "unknown"
        else -> "unknown"
    }
    }


@@ -241,6 +247,81 @@ class NotifCollectionLogger @Inject constructor(
            "ERROR suppressed due to initialization forgiveness: $str1"
            "ERROR suppressed due to initialization forgiveness: $str1"
        })
        })
    }
    }

    fun logFutureDismissalReused(dismissal: FutureDismissal) {
        buffer.log(TAG, INFO, {
            str1 = dismissal.label
        }, {
            "Reusing existing registration: $str1"
        })
    }

    fun logFutureDismissalRegistered(dismissal: FutureDismissal) {
        buffer.log(TAG, DEBUG, {
            str1 = dismissal.label
        }, {
            "Registered: $str1"
        })
    }

    fun logFutureDismissalDoubleCancelledByServer(dismissal: FutureDismissal) {
        buffer.log(TAG, WARNING, {
            str1 = dismissal.label
        }, {
            "System server double cancelled: $str1"
        })
    }

    fun logFutureDismissalDoubleRun(dismissal: FutureDismissal) {
        buffer.log(TAG, WARNING, {
            str1 = dismissal.label
        }, {
            "Double run: $str1"
        })
    }

    fun logFutureDismissalAlreadyCancelledByServer(dismissal: FutureDismissal) {
        buffer.log(TAG, DEBUG, {
            str1 = dismissal.label
        }, {
            "Ignoring: entry already cancelled by server: $str1"
        })
    }

    fun logFutureDismissalGotSystemServerCancel(
        dismissal: FutureDismissal,
        @CancellationReason cancellationReason: Int
    ) {
        buffer.log(TAG, DEBUG, {
            str1 = dismissal.label
            int1 = cancellationReason
        }, {
            "SystemServer cancelled: $str1 reason=${cancellationReasonDebugString(int1)}"
        })
    }

    fun logFutureDismissalDismissing(dismissal: FutureDismissal, type: String) {
        buffer.log(TAG, DEBUG, {
            str1 = dismissal.label
            str2 = type
        }, {
            "Dismissing $str2 for: $str1"
        })
    }

    fun logFutureDismissalMismatchedEntry(
        dismissal: FutureDismissal,
        type: String,
        latestEntry: NotificationEntry?
    ) {
        buffer.log(TAG, WARNING, {
            str1 = dismissal.label
            str2 = type
            str3 = latestEntry.logKey
        }, {
            "Mismatch: current $str2 is $str3 for: $str1"
        })
    }
}
}


private const val TAG = "NotifCollection"
private const val TAG = "NotifCollection"
Loading