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

Commit 6e488d45 authored by Mady Mellor's avatar Mady Mellor Committed by Automerger Merge Worker
Browse files

Merge "Make bubble flag removals from notification delegate (sysui) sticky"...

Merge "Make bubble flag removals from notification delegate (sysui) sticky" into rvc-dev am: b68f9f98

Change-Id: I11dbf9cb0eccfebf4f446e6fc2a84d96697b1ccf
parents 99513c66 b68f9f98
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -76,7 +76,8 @@ public class BubbleExtractor implements NotificationSignalExtractor {
                record.setAllowBubble(appCanShowBubble);
            }
        }
        final boolean applyFlag = mBubbleChecker.isNotificationAppropriateToBubble(record);
        final boolean applyFlag = mBubbleChecker.isNotificationAppropriateToBubble(record)
                && !record.isFlagBubbleRemoved();
        if (applyFlag) {
            record.getNotification().flags |= FLAG_BUBBLE;
        } else {
+3 −0
Original line number Diff line number Diff line
@@ -1214,10 +1214,12 @@ public class NotificationManagerService extends SystemService {
                        // apps querying noMan will know that their notification is not showing
                        // as a bubble.
                        r.getNotification().flags &= ~FLAG_BUBBLE;
                        r.setFlagBubbleRemoved(true);
                    } else {
                        // Enqueue will trigger resort & if the flag is allowed to be true it'll
                        // be applied there.
                        r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
                        r.setFlagBubbleRemoved(false);
                        mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(),
                                r, isAppForeground));
                    }
@@ -5637,6 +5639,7 @@ public class NotificationManagerService extends SystemService {
        final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
        r.setIsAppImportanceLocked(mPreferencesHelper.getIsAppImportanceLocked(pkg, callingUid));
        r.setPostSilently(postSilently);
        r.setFlagBubbleRemoved(false);

        if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
            final boolean fgServiceShown = channel.isFgServiceShown();
+14 −0
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ public final class NotificationRecord {
    private boolean mSuggestionsGeneratedByAssistant;
    private boolean mEditChoicesBeforeSending;
    private boolean mHasSeenSmartReplies;
    private boolean mFlagBubbleRemoved;
    private boolean mPostSilently;
    /**
     * Whether this notification (and its channels) should be considered user locked. Used in
@@ -1201,6 +1202,19 @@ public final class NotificationRecord {
        return stats.hasBeenVisiblyExpanded();
    }

    /**
     * When the bubble state on a notif changes due to user action (e.g. dismiss a bubble) then
     * this value is set until an update or bubble change event due to user action (e.g. create
     * bubble from sysui)
     **/
    public boolean isFlagBubbleRemoved() {
        return mFlagBubbleRemoved;
    }

    public void setFlagBubbleRemoved(boolean flagBubbleRemoved) {
        mFlagBubbleRemoved = flagBubbleRemoved;
    }

    public void setSystemGeneratedSmartActions(
            ArrayList<Notification.Action> systemGeneratedSmartActions) {
        mSystemGeneratedSmartActions = systemGeneratedSmartActions;
+30 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import org.mockito.MockitoAnnotations;
public class BubbleExtractorTest extends UiServiceTestCase {

    @Mock RankingConfig mConfig;
    @Mock BubbleExtractor.BubbleChecker mBubbleChecker;
    BubbleExtractor mBubbleExtractor;

    private String mPkg = "com.android.server.notification";
@@ -141,4 +142,33 @@ public class BubbleExtractorTest extends UiServiceTestCase {

        assertFalse(r.canBubble());
    }

    @Test
    public void testFlagBubble_true() {
        when(mConfig.bubblesEnabled()).thenReturn(true);
        when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
        NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED);

        mBubbleExtractor.setBubbleChecker(mBubbleChecker);
        when(mBubbleChecker.isNotificationAppropriateToBubble(r)).thenReturn(true);
        mBubbleExtractor.process(r);

        assertTrue(r.canBubble());
        assertTrue(r.getNotification().isBubbleNotification());
    }

    @Test
    public void testFlagBubble_noFlag_previouslyRemoved() {
        when(mConfig.bubblesEnabled()).thenReturn(true);
        when(mConfig.areBubblesAllowed(mPkg, mUid)).thenReturn(true);
        NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED);
        r.setFlagBubbleRemoved(true);

        mBubbleExtractor.setBubbleChecker(mBubbleChecker);
        when(mBubbleChecker.isNotificationAppropriateToBubble(r)).thenReturn(true);
        mBubbleExtractor.process(r);

        assertTrue(r.canBubble());
        assertFalse(r.getNotification().isBubbleNotification());
    }
}
+71 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
import android.app.IActivityManager;
@@ -154,6 +155,7 @@ import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.InstanceIdSequenceFake;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.DeviceIdleInternal;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiServiceTestCase;
@@ -380,12 +382,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {

        MockitoAnnotations.initMocks(this);

        DeviceIdleInternal deviceIdleInternal = mock(DeviceIdleInternal.class);
        when(deviceIdleInternal.getNotificationWhitelistDuration()).thenReturn(3000L);
        ActivityManagerInternal activityManagerInternal = mock(ActivityManagerInternal.class);

        LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
        LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
        LocalServices.removeServiceForTest(WindowManagerInternal.class);
        LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
        LocalServices.addService(StatusBarManagerInternal.class, mStatusBar);
        LocalServices.removeServiceForTest(DeviceIdleInternal.class);
        LocalServices.addService(DeviceIdleInternal.class, deviceIdleInternal);
        LocalServices.removeServiceForTest(ActivityManagerInternal.class);
        LocalServices.addService(ActivityManagerInternal.class, activityManagerInternal);

        doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());

@@ -5591,6 +5601,67 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
    }

    @Test
    public void testNotificationBubbleIsFlagRemoved_resetOnUpdate() throws Exception {
        // Bubbles are allowed!
        setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */);
        // Notif with bubble metadata
        NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                "testNotificationBubbleIsFlagRemoved_resetOnUpdate");

        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        // Flag shouldn't be modified
        NotificationRecord recordToCheck = mService.getNotificationRecord(nr.getSbn().getKey());
        assertFalse(recordToCheck.isFlagBubbleRemoved());

        // Notify we're not a bubble
        mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false);
        waitForIdle();
        // Flag should be modified
        recordToCheck = mService.getNotificationRecord(nr.getSbn().getKey());
        assertTrue(recordToCheck.isFlagBubbleRemoved());


        // Update the notif
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        // And the flag is reset
        recordToCheck = mService.getNotificationRecord(nr.getSbn().getKey());
        assertFalse(recordToCheck.isFlagBubbleRemoved());
    }

    @Test
    public void testNotificationBubbleIsFlagRemoved_resetOnBubbleChangedTrue() throws Exception {
        // Bubbles are allowed!
        setUpPrefsForBubbles(PKG, mUid, true /* global */, true /* app */, true /* channel */);
        // Notif with bubble metadata
        NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                "testNotificationBubbleIsFlagRemoved_trueOnBubbleChangedTrue");

        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        // Flag shouldn't be modified
        NotificationRecord recordToCheck = mService.getNotificationRecord(nr.getSbn().getKey());
        assertFalse(recordToCheck.isFlagBubbleRemoved());

        // Notify we're not a bubble
        mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false);
        waitForIdle();
        // Flag should be modified
        recordToCheck = mService.getNotificationRecord(nr.getSbn().getKey());
        assertTrue(recordToCheck.isFlagBubbleRemoved());

        // Notify we are a bubble
        mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true);
        waitForIdle();
        // And the flag is reset
        assertFalse(recordToCheck.isFlagBubbleRemoved());
    }

    @Test
    public void testOnBubbleNotificationSuppressionChanged() throws Exception {
        // Bubbles are allowed!