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

Commit c88a1427 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "NM Binder Perf: Correctly invalidate mKnownNotifications in cancelAll()" into main

parents ab0eb701 a6a9f06e
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -768,6 +768,10 @@ public class NotificationManager {
        INotificationManager service = service();
        String sender = mContext.getPackageName();

        if (discardNotify(mContext.getUser(), targetPackage, tag, id, notification)) {
            return;
        }

        try {
            if (localLOGV) Log.v(TAG, sender + ": notify(" + id + ", " + notification + ")");
            service.enqueueNotificationWithTag(targetPackage, sender, tag, id,
@@ -918,6 +922,10 @@ public class NotificationManager {
     * @param id An identifier for this notification.
     */
    public void cancelAsPackage(@NonNull String targetPackage, @Nullable String tag, int id) {
        if (discardCancel(mContext.getUser(), targetPackage, tag, id)) {
            return;
        }

        INotificationManager service = service();
        try {
            service.cancelNotificationWithTag(targetPackage, mContext.getOpPackageName(),
@@ -981,16 +989,20 @@ public class NotificationManager {
     */
    public void cancelAll()
    {
        String pkg = mContext.getPackageName();
        UserHandle user = mContext.getUser();

        if (Flags.nmBinderPerfThrottleNotify()) {
            synchronized (mThrottleLock) {
                for (NotificationKey key : mKnownNotifications.snapshot().keySet()) {
                    if (key.pkg.equals(pkg) && key.user.equals(user)) {
                        mKnownNotifications.put(key, KNOWN_STATUS_CANCELLED);
                    }
                }
            }
        }

        INotificationManager service = service();
        String pkg = mContext.getPackageName();
        if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
        try {
            service.cancelAllNotifications(pkg, mContext.getUserId());
@@ -1014,7 +1026,7 @@ public class NotificationManager {
    public void setNotificationDelegate(@Nullable String delegate) {
        INotificationManager service = service();
        String pkg = mContext.getPackageName();
        if (localLOGV) Log.v(TAG, pkg + ": cancelAll()");
        if (localLOGV) Log.v(TAG, pkg + ": setNotificationDelegate()");
        try {
            service.setNotificationDelegate(pkg, delegate);
        } catch (RemoteException e) {
+78 −0
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@ package android.app;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@@ -102,6 +104,22 @@ public class NotificationManagerTest {
                any(), any(), anyInt(), any(), anyInt());
    }

    @Test
    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
    public void notifyAsPackage_rapidUpdate_isThrottled() throws Exception {
        Notification n = exampleNotification();

        for (int i = 0; i < 100; i++) {
            mNotificationManager.notifyAsPackage("some.package.name", "tag", 1, n);
            mClock.advanceByMillis(5);
        }

        verify(mNotificationManager.mBackendService, atLeast(20)).enqueueNotificationWithTag(
                eq("some.package.name"), any(), any(), anyInt(), any(), anyInt());
        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(
                eq("some.package.name"), any(), any(), anyInt(), any(), anyInt());
    }

    @Test
    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
    public void cancel_unnecessaryAndRapid_isThrottled() throws Exception {
@@ -165,6 +183,66 @@ public class NotificationManagerTest {
                any(), any(), anyInt(), anyInt());
    }

    @Test
    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
    public void enqueue_afterCancel_isNotUpdateAndIsNotThrottled() throws Exception {
        // First, hit the enqueue threshold.
        Notification n = exampleNotification();
        for (int i = 0; i < 100; i++) {
            mNotificationManager.notify(1, n);
            mClock.advanceByMillis(1);
        }
        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
                any(), any(), anyInt(), any(), anyInt());
        reset(mNotificationManager.mBackendService);

        // Now cancel that notification and then post it again. That should work.
        mNotificationManager.cancel(1);
        mNotificationManager.notify(1, n);
        verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(),
                anyInt(), any(), anyInt());
    }

    @Test
    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
    public void enqueue_afterCancelAsPackage_isNotUpdateAndIsNotThrottled() throws Exception {
        // First, hit the enqueue threshold.
        Notification n = exampleNotification();
        for (int i = 0; i < 100; i++) {
            mNotificationManager.notify(1, n);
            mClock.advanceByMillis(1);
        }
        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
                any(), any(), anyInt(), any(), anyInt());
        reset(mNotificationManager.mBackendService);

        // Now cancel that notification and then post it again. That should work.
        mNotificationManager.cancelAsPackage(mContext.getPackageName(), /* tag= */ null, 1);
        mNotificationManager.notify(1, n);
        verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(),
                anyInt(), any(), anyInt());
    }

    @Test
    @EnableFlags(Flags.FLAG_NM_BINDER_PERF_THROTTLE_NOTIFY)
    public void enqueue_afterCancelAll_isNotUpdateAndIsNotThrottled() throws Exception {
        // First, hit the enqueue threshold.
        Notification n = exampleNotification();
        for (int i = 0; i < 100; i++) {
            mNotificationManager.notify(1, n);
            mClock.advanceByMillis(1);
        }
        verify(mNotificationManager.mBackendService, atMost(30)).enqueueNotificationWithTag(any(),
                any(), any(), anyInt(), any(), anyInt());
        reset(mNotificationManager.mBackendService);

        // Now cancel all notifications and then post it again. That should work.
        mNotificationManager.cancelAll();
        mNotificationManager.notify(1, n);
        verify(mNotificationManager.mBackendService).enqueueNotificationWithTag(any(), any(), any(),
                anyInt(), any(), anyInt());
    }

    private Notification exampleNotification() {
        return new Notification.Builder(mContext, "channel")
                .setSmallIcon(android.R.drawable.star_big_on)