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

Commit 4a2cef77 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Do not show snooze button for cancelled notifications" into udc-dev

parents 67d30ecf c5a1730b
Loading
Loading
Loading
Loading
+5 −14
Original line number Diff line number Diff line
@@ -307,7 +307,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
            }

            entriesToLocallyDismiss.add(entry);
            if (!isCanceled(entry)) {
            if (!entry.isCanceled()) {
                // send message to system server if this notification hasn't already been cancelled
                mBgExecutor.execute(() -> {
                    try {
@@ -387,7 +387,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
            entry.setDismissState(DISMISSED);
            mLogger.logNotifDismissed(entry);

            if (isCanceled(entry)) {
            if (entry.isCanceled()) {
                canceledEntries.add(entry);
            } else {
                // Mark any children as dismissed as system server will auto-dismiss them as well
@@ -396,7 +396,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
                        if (shouldAutoDismissChildren(otherEntry, entry.getSbn().getGroupKey())) {
                            otherEntry.setDismissState(PARENT_DISMISSED);
                            mLogger.logChildDismissed(otherEntry);
                            if (isCanceled(otherEntry)) {
                            if (otherEntry.isCanceled()) {
                                canceledEntries.add(otherEntry);
                            }
                        }
@@ -523,7 +523,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
                            + logKey(entry)));
        }

        if (!isCanceled(entry)) {
        if (!entry.isCanceled()) {
            throw mEulogizer.record(
                    new IllegalStateException("Cannot remove notification " + logKey(entry)
                            + ": has not been marked for removal"));
@@ -587,7 +587,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
    private void applyRanking(@NonNull RankingMap rankingMap) {
        ArrayMap<String, NotificationEntry> currentEntriesWithoutRankings = null;
        for (NotificationEntry entry : mNotificationSet.values()) {
            if (!isCanceled(entry)) {
            if (!entry.isCanceled()) {

                // TODO: (b/148791039) We should crash if we are ever handed a ranking with
                //  incomplete entries. Right now, there's a race condition in NotificationListener
@@ -815,15 +815,6 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
        return ranking;
    }

    /**
     * True if the notification has been canceled by system server. Usually, such notifications are
     * immediately removed from the collection, but can sometimes stick around due to lifetime
     * extenders.
     */
    private boolean isCanceled(NotificationEntry entry) {
        return entry.mCancellationReason != REASON_NOT_CANCELED;
    }

    private boolean cannotBeLifetimeExtended(NotificationEntry entry) {
        final boolean locallyDismissedByUser = entry.getDismissState() != NOT_DISMISSED;
        final boolean systemServerReportedUserCancel =
+9 −0
Original line number Diff line number Diff line
@@ -321,6 +321,15 @@ public final class NotificationEntry extends ListEntry {
        mDismissState = requireNonNull(dismissState);
    }

    /**
     * True if the notification has been canceled by system server. Usually, such notifications are
     * immediately removed from the collection, but can sometimes stick around due to lifetime
     * extenders.
     */
    public boolean isCanceled() {
        return mCancellationReason != REASON_NOT_CANCELED;
    }

    @Nullable public NotifFilter getExcludingFilter() {
        return getAttachState().getExcludingFilter();
    }
+3 −3
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ class NotifUiAdjustmentProvider @Inject constructor(
    private val userTracker: UserTracker
) {
    private val dirtyListeners = ListenerSet<Runnable>()
    private var isSnoozeEnabled = false
    private var isSnoozeSettingsEnabled = false

    /**
     *  Update the snooze enabled value on user switch
@@ -95,7 +95,7 @@ class NotifUiAdjustmentProvider @Inject constructor(
    }

    private fun updateSnoozeEnabled() {
        isSnoozeEnabled =
        isSnoozeSettingsEnabled =
            secureSettings.getIntForUser(SHOW_NOTIFICATION_SNOOZE, 0, UserHandle.USER_CURRENT) == 1
    }

@@ -118,7 +118,7 @@ class NotifUiAdjustmentProvider @Inject constructor(
        smartActions = entry.ranking.smartActions,
        smartReplies = entry.ranking.smartReplies,
        isConversation = entry.ranking.isConversation,
        isSnoozeEnabled = isSnoozeEnabled,
        isSnoozeEnabled = isSnoozeSettingsEnabled && !entry.isCanceled,
        isMinimized = isEntryMinimized(entry),
        needsRedaction = lockscreenUserManager.needsRedaction(entry),
    )
+41 −0
Original line number Diff line number Diff line
@@ -16,14 +16,18 @@

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

import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;

import static com.android.systemui.statusbar.notification.collection.GroupEntry.ROOT_ENTRY;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -31,6 +35,7 @@ import static org.mockito.Mockito.when;

import static java.util.Objects.requireNonNull;

import android.database.ContentObserver;
import android.os.Handler;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
@@ -294,6 +299,42 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
        assertFalse(mUninflatedFilter.shouldFilterOut(mEntry, 0));
    }

    @Test
    public void testEntryCancellationWillRebindViews() {
        // Configure NotifUiAdjustmentProvider to set up SHOW_NOTIFICATION_SNOOZE value
        mEntry = spy(mEntry);
        mAdjustmentProvider.addDirtyListener(mock(Runnable.class));
        when(mSecureSettings.getIntForUser(eq(SHOW_NOTIFICATION_SNOOZE), anyInt(), anyInt()))
                .thenReturn(1);
        ArgumentCaptor<ContentObserver> contentObserverCaptor = ArgumentCaptor.forClass(
                ContentObserver.class);
        verify(mSecureSettings).registerContentObserverForUser(eq(SHOW_NOTIFICATION_SNOOZE),
                contentObserverCaptor.capture(), anyInt());
        ContentObserver contentObserver = contentObserverCaptor.getValue();
        contentObserver.onChange(false);

        // GIVEN an inflated notification
        mCollectionListener.onEntryInit(mEntry);
        mBeforeFilterListener.onBeforeFinalizeFilter(List.of(mEntry));
        verify(mNotifInflater).inflateViews(eq(mEntry), any(), any());
        mNotifInflater.invokeInflateCallbackForEntry(mEntry);

        // Verify that snooze is initially enabled: from Settings & notification is not cancelled
        assertTrue(mAdjustmentProvider.calculateAdjustment(mEntry).isSnoozeEnabled());

        // WHEN notification is cancelled, rebind views because snooze enabled value changes
        when(mEntry.isCanceled()).thenReturn(true);
        mBeforeFilterListener.onBeforeFinalizeFilter(List.of(mEntry));

        assertFalse(mAdjustmentProvider.calculateAdjustment(mEntry).isSnoozeEnabled());

        // THEN we rebind it
        verify(mNotifInflater).rebindViews(eq(mEntry), any(), any());

        // THEN we do not filter it because it's not the first inflation.
        assertFalse(mUninflatedFilter.shouldFilterOut(mEntry, 0));
    }

    @Test
    public void testDoesntFilterInflatedNotifs() {
        // GIVEN an inflated notification