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

Commit 943f7989 authored by Ibrahim Yilmaz's avatar Ibrahim Yilmaz
Browse files

Throttle Spammy onNotificationChannelModified

onNotificationChannelModified events are logged in rapid succession. With this change, we throttle some of them by 1 sec.

Test: presubmit && logcat logs && atest NotifCollectionTest
Bug: 262010037
Change-Id: I9106bbfda463322136c3e289734ea69d6780747d
parent 69d2637f
Loading
Loading
Loading
Loading
+33 −4
Original line number Diff line number Diff line
@@ -164,6 +164,11 @@ public class NotifCollection implements Dumpable, PipelineDumpable {


    private Queue<NotifEvent> mEventQueue = new ArrayDeque<>();
    private final Runnable mRebuildListRunnable = () -> {
        if (mBuildListener != null) {
            mBuildListener.onBuildList(mReadOnlyNotificationSet, "asynchronousUpdate");
        }
    };

    private boolean mAttached = false;
    private boolean mAmDispatchingToOtherCode;
@@ -458,7 +463,7 @@ public class NotifCollection implements Dumpable, PipelineDumpable {
            int modificationType) {
        Assert.isMainThread();
        mEventQueue.add(new ChannelChangedEvent(pkgName, user, channel, modificationType));
        dispatchEventsAndRebuildList("onNotificationChannelModified");
        dispatchEventsAndAsynchronouslyRebuildList();
    }

    private void onNotificationsInitialized() {
@@ -613,15 +618,39 @@ public class NotifCollection implements Dumpable, PipelineDumpable {

    private void dispatchEventsAndRebuildList(String reason) {
        Trace.beginSection("NotifCollection.dispatchEventsAndRebuildList");
        if (mMainHandler.hasCallbacks(mRebuildListRunnable)) {
            mMainHandler.removeCallbacks(mRebuildListRunnable);
        }

        dispatchEvents();

        if (mBuildListener != null) {
            mBuildListener.onBuildList(mReadOnlyNotificationSet, reason);
        }
        Trace.endSection();
    }

    private void dispatchEventsAndAsynchronouslyRebuildList() {
        Trace.beginSection("NotifCollection.dispatchEventsAndAsynchronouslyRebuildList");

        dispatchEvents();

        if (!mMainHandler.hasCallbacks(mRebuildListRunnable)) {
            mMainHandler.postDelayed(mRebuildListRunnable, 1000L);
        }

        Trace.endSection();
    }

    private void dispatchEvents() {
        Trace.beginSection("NotifCollection.dispatchEvents");

        mAmDispatchingToOtherCode = true;
        while (!mEventQueue.isEmpty()) {
            mEventQueue.remove().dispatchTo(mNotifCollectionListeners);
        }
        mAmDispatchingToOtherCode = false;

        if (mBuildListener != null) {
            mBuildListener.onBuildList(mReadOnlyNotificationSet, reason);
        }
        Trace.endSection();
    }

+85 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.mockito.stubbing.Answer;

import java.util.Arrays;
import java.util.Collection;
@@ -375,6 +376,90 @@ public class NotifCollectionTest extends SysuiTestCase {
                NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
    }

    @Test
    public void testScheduleBuildNotificationListWhenChannelChanged() {
        // GIVEN
        final NotificationEntryBuilder neb = buildNotif(TEST_PACKAGE, 48);
        final NotificationChannel channel = new NotificationChannel(
                "channelId",
                "channelName",
                NotificationManager.IMPORTANCE_DEFAULT);
        neb.setChannel(channel);

        final NotifEvent notif = mNoMan.postNotif(neb);
        final NotificationEntry entry = mCollectionListener.getEntry(notif.key);

        when(mMainHandler.hasCallbacks(any())).thenReturn(false);

        clearInvocations(mBuildListener);

        // WHEN
        mNotifHandler.onNotificationChannelModified(TEST_PACKAGE,
                entry.getSbn().getUser(), channel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);

        // THEN
        verify(mMainHandler).postDelayed(any(), eq(1000L));
    }

    @Test
    public void testCancelScheduledBuildNotificationListEventWhenNotifUpdatedSynchronously() {
        // GIVEN
        final NotificationEntry entry1 = buildNotif(TEST_PACKAGE, 1)
                .setGroup(mContext, "group_1")
                .build();
        final NotificationEntry entry2 = buildNotif(TEST_PACKAGE, 2)
                .setGroup(mContext, "group_1")
                .setContentTitle(mContext, "New version")
                .build();
        final NotificationEntry entry3 = buildNotif(TEST_PACKAGE, 3)
                .setGroup(mContext, "group_1")
                .build();

        final List<CoalescedEvent> entriesToBePosted = Arrays.asList(
                new CoalescedEvent(entry1.getKey(), 0, entry1.getSbn(), entry1.getRanking(), null),
                new CoalescedEvent(entry2.getKey(), 1, entry2.getSbn(), entry2.getRanking(), null),
                new CoalescedEvent(entry3.getKey(), 2, entry3.getSbn(), entry3.getRanking(), null)
        );

        when(mMainHandler.hasCallbacks(any())).thenReturn(true);

        // WHEN
        mNotifHandler.onNotificationBatchPosted(entriesToBePosted);

        // THEN
        verify(mMainHandler).removeCallbacks(any());
    }

    @Test
    public void testBuildNotificationListWhenChannelChanged() {
        // GIVEN
        final NotificationEntryBuilder neb = buildNotif(TEST_PACKAGE, 48);
        final NotificationChannel channel = new NotificationChannel(
                "channelId",
                "channelName",
                NotificationManager.IMPORTANCE_DEFAULT);
        neb.setChannel(channel);

        final NotifEvent notif = mNoMan.postNotif(neb);
        final NotificationEntry entry = mCollectionListener.getEntry(notif.key);

        when(mMainHandler.hasCallbacks(any())).thenReturn(false);
        when(mMainHandler.postDelayed(any(), eq(1000L))).thenAnswer((Answer) invocation -> {
            final Runnable runnable = invocation.getArgument(0);
            runnable.run();
            return null;
        });

        clearInvocations(mBuildListener);

        // WHEN
        mNotifHandler.onNotificationChannelModified(TEST_PACKAGE,
                entry.getSbn().getUser(), channel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);

        // THEN
        verifyBuiltList(List.of(entry));
    }

    @Test
    public void testRankingsAreUpdatedForOtherNotifs() {
        // GIVEN a collection with one notif