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

Commit 4b8bbda2 authored by Kevin's avatar Kevin
Browse files

Fix GroupAlertTransferHelper logic on update.

Previously, all transferred alerts were removed when the inflation was
aborted. This could cancel transfers when the child was simply updating.
Now, this only occurs on remove. On update, the previous heads up/
ambient inflation flag is carried over and the helper determines if
the content should actually heads up after inflation.

Bug: 111809944
Test: runtest systemui, manual
Change-Id: Ic7c5414849e2bfa1978bb1c57ed314c4997b8ea2
parent 01a53cbf
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -510,7 +510,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        NotificationData.Entry addedEntry = mNotificationData.get(key);
        if (addedEntry != null) {
            addedEntry.abortTask();
            mGroupAlertTransferHelper.onInflationAborted(addedEntry);
        }
    }

@@ -583,6 +582,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
    private void removeNotificationInternal(String key,
            @Nullable NotificationListenerService.RankingMap ranking, boolean forceRemove) {
        abortExistingInflation(key);
        mGroupAlertTransferHelper.cleanUpPendingAlertInfo(key);

        // Attempt to remove notifications from their alert managers (heads up, ambient pulse).
        // Though the remove itself may fail, it lets the manager know to remove as soon as
@@ -744,8 +744,12 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
        row.setEntry(entry);

        row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, shouldHeadsUp(entry));
        row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, shouldPulse(entry));
        if (shouldHeadsUp(entry)) {
            row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, true /* shouldInflate */);
        }
        if (shouldPulse(entry)) {
            row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true /* shouldInflate */);
        }
        row.setNeedsRedaction(
                Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry));
        row.inflateViews();
+47 −17
Original line number Diff line number Diff line
@@ -85,6 +85,29 @@ public class NotificationGroupAlertTransferHelper implements OnGroupChangeListen
        Dependency.get(StatusBarStateController.class).addListener(this);
    }

    /**
     * Whether or not a notification has transferred its alert state to the notification and
     * the notification should alert after inflating.
     *
     * @param entry notification to check
     * @return true if the entry was transferred to and should inflate + alert
     */
    public boolean isAlertTransferPending(@NonNull Entry entry) {
        PendingAlertInfo alertInfo = mPendingAlerts.get(entry.key);
        return alertInfo != null && alertInfo.isStillValid();
    }

    /**
     * Removes any alerts pending on this entry. Note that this will not stop any inflation tasks
     * started by a transfer, so this should only be used as clean-up for when inflation is stopped
     * and the pending alert no longer needs to happen.
     *
     * @param key notification key that may have info that needs to be cleaned up
     */
    public void cleanUpPendingAlertInfo(@NonNull String key) {
        mPendingAlerts.remove(key);
    }

    public void setHeadsUpManager(HeadsUpManager headsUpManager) {
        mHeadsUpManager = headsUpManager;
    }
@@ -180,20 +203,6 @@ public class NotificationGroupAlertTransferHelper implements OnGroupChangeListen
        }
    }

    /**
     * Called when the entry's reinflation has been aborted.
     *
     * @param entry entry whose inflation has been aborted
     */
    public void onInflationAborted(@NonNull Entry entry) {
        GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(
                mGroupManager.getGroupKey(entry.notification));
        if (groupAlertEntry == null) {
            return;
        }
        mPendingAlerts.remove(entry.key);
    }

    /**
     * Called when a new notification has been posted but is not inflated yet. We use this to see
     * as early as we can if we need to abort a transfer.
@@ -382,8 +391,7 @@ public class NotificationGroupAlertTransferHelper implements OnGroupChangeListen
            @NonNull AlertingNotificationManager alertManager) {
        @InflationFlag int contentFlag = alertManager.getContentFlag();
        if (!entry.row.isInflationFlagSet(contentFlag)) {
            // Take in the current alert manager in case it changes.
            mPendingAlerts.put(entry.key, new PendingAlertInfo(alertManager));
            mPendingAlerts.put(entry.key, new PendingAlertInfo(entry, alertManager));
            entry.row.updateInflationFlag(contentFlag, true /* shouldInflate */);
            entry.row.inflateViews();
            return;
@@ -409,7 +417,18 @@ public class NotificationGroupAlertTransferHelper implements OnGroupChangeListen
     * inflation completes.
     */
    private class PendingAlertInfo {
        /**
         * The alert manager when the transfer is initiated.
         */
        final AlertingNotificationManager mAlertManager;

        /**
         * The original notification when the transfer is initiated. This is used to determine if
         * the transfer is still valid if the notification is updated.
         */
        final StatusBarNotification mOriginalNotification;
        final Entry mEntry;

        /**
         * The notification is still pending inflation but we've decided that we no longer need
         * the content view (e.g. suppression might have changed and we decided we need to transfer
@@ -419,7 +438,9 @@ public class NotificationGroupAlertTransferHelper implements OnGroupChangeListen
         */
        boolean mAbortOnInflation;

        PendingAlertInfo(AlertingNotificationManager alertManager) {
        PendingAlertInfo(Entry entry, AlertingNotificationManager alertManager) {
            mOriginalNotification = entry.notification;
            mEntry = entry;
            mAlertManager = alertManager;
        }

@@ -437,6 +458,15 @@ public class NotificationGroupAlertTransferHelper implements OnGroupChangeListen
                // Alert manager has changed
                return false;
            }
            if (mEntry.notification.getGroupKey() != mOriginalNotification.getGroupKey()) {
                // Groups have changed
                return false;
            }
            if (mEntry.notification.getNotification().isGroupSummary()
                    != mOriginalNotification.getNotification().isGroupSummary()) {
                // Notification has changed from group summary to not or vice versa
                return false;
            }
            return true;
        }
    }
+64 −0
Original line number Diff line number Diff line
@@ -18,11 +18,14 @@ package com.android.systemui.statusbar.phone;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Notification;
import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -155,6 +158,7 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
        // content is not inflated.
        assertFalse(mHeadsUpManager.isAlerting(summaryEntry.key));
        assertFalse(mHeadsUpManager.isAlerting(childEntry.key));
        assertTrue(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
    }

    @Test
@@ -201,4 +205,64 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
        verify(childEntry.row, times(1)).freeContentViewWhenSafe(mHeadsUpManager.getContentFlag());
        assertFalse(mHeadsUpManager.isAlerting(childEntry.key));
    }

    @Test
    public void testCleanUpPendingAlertInfo() {
        NotificationData.Entry summaryEntry =
                mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
        NotificationData.Entry childEntry =
                mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
        when(childEntry.row.isInflationFlagSet(mHeadsUpManager.getContentFlag())).thenReturn(false);
        mHeadsUpManager.showNotification(summaryEntry);
        // Trigger a transfer of alert state from summary to child.
        mGroupManager.onEntryAdded(summaryEntry);
        mGroupManager.onEntryAdded(childEntry);

        mGroupAlertTransferHelper.cleanUpPendingAlertInfo(childEntry.key);

        assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
    }

    @Test
    public void testUpdateGroupChangeDoesNotTransfer() {
        NotificationData.Entry summaryEntry =
                mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
        NotificationData.Entry childEntry =
                mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
        when(childEntry.row.isInflationFlagSet(mHeadsUpManager.getContentFlag())).thenReturn(false);
        mHeadsUpManager.showNotification(summaryEntry);
        // Trigger a transfer of alert state from summary to child.
        mGroupManager.onEntryAdded(summaryEntry);
        mGroupManager.onEntryAdded(childEntry);

        // Notify that entry changed groups.
        StatusBarNotification oldNotification = childEntry.notification;
        StatusBarNotification newSbn = spy(childEntry.notification.clone());
        doReturn("other_group").when(newSbn).getGroupKey();
        childEntry.notification = newSbn;
        mGroupManager.onEntryUpdated(childEntry, oldNotification);

        assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
    }

    @Test
    public void testUpdateChildToSummaryDoesNotTransfer() {
        NotificationData.Entry summaryEntry =
                mGroupTestHelper.createSummaryNotification(Notification.GROUP_ALERT_SUMMARY);
        NotificationData.Entry childEntry =
                mGroupTestHelper.createChildNotification(Notification.GROUP_ALERT_SUMMARY);
        when(childEntry.row.isInflationFlagSet(mHeadsUpManager.getContentFlag())).thenReturn(false);
        mHeadsUpManager.showNotification(summaryEntry);
        // Trigger a transfer of alert state from summary to child.
        mGroupManager.onEntryAdded(summaryEntry);
        mGroupManager.onEntryAdded(childEntry);

        // Update that child to a summary.
        StatusBarNotification oldNotification = childEntry.notification;
        childEntry.notification = mGroupTestHelper.createSummaryNotification(
                Notification.GROUP_ALERT_SUMMARY).notification;
        mGroupManager.onEntryUpdated(childEntry, oldNotification);

        assertFalse(mGroupAlertTransferHelper.isAlertTransferPending(childEntry));
    }
}