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

Commit 3371d1f2 authored by Lyn's avatar Lyn
Browse files

Set avalanche HUN duration based on next top HUN priority

Bug: 315362456
Flag: ACONFIG notification_throttle_hun DEVELOPMENT
Test: AvalancheControllerTest
Change-Id: I35962c0f97bc65f0df8688e4156be1daf82117e1
parent 3a2fcbc6
Loading
Loading
Loading
Loading
+71 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.policy.HeadsUpManagerTestUtil.createFullScreenIntentEntry
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.settings.FakeGlobalSettings
import com.android.systemui.util.time.FakeSystemClock
@@ -97,6 +98,12 @@ class AvalancheControllerTest : SysuiTestCase() {
        return entry
    }

    private fun createFsiHeadsUpEntry(id: Int): BaseHeadsUpManager.HeadsUpEntry {
        val entry = testableHeadsUpManager!!.createHeadsUpEntry()
        entry.setEntry(createFullScreenIntentEntry(id, mContext))
        return entry
    }

    @Test
    fun testUpdate_isShowing_runsRunnable() {
        // Entry is showing
@@ -238,4 +245,68 @@ class AvalancheControllerTest : SysuiTestCase() {
        // Next entry is shown
        Truth.assertThat(mAvalancheController.headsUpEntryShowing).isEqualTo(nextEntry)
    }

    @Test
    fun testGetDurationMs_lastEntry_useAutoDismissTime() {
        // Entry is showing
        val showingEntry = createHeadsUpEntry(id = 0)
        mAvalancheController.headsUpEntryShowing = showingEntry

        // Nothing is next
        mAvalancheController.clearNext()

        val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
        Truth.assertThat(durationMs).isEqualTo(5000)
    }

    @Test
    fun testGetDurationMs_nextEntryLowerPriority_500() {
        // Entry is showing
        val showingEntry = createFsiHeadsUpEntry(id = 1)
        mAvalancheController.headsUpEntryShowing = showingEntry

        // There's another entry waiting to show next
        val nextEntry = createHeadsUpEntry(id = 0)
        mAvalancheController.addToNext(nextEntry, runnableMock!!)

        // Next entry has lower priority
        Truth.assertThat(nextEntry.compareNonTimeFields(showingEntry)).isEqualTo(1)

        val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
        Truth.assertThat(durationMs).isEqualTo(5000)
    }

    @Test
    fun testGetDurationMs_nextEntrySamePriority_1000() {
        // Entry is showing
        val showingEntry = createHeadsUpEntry(id = 0)
        mAvalancheController.headsUpEntryShowing = showingEntry

        // There's another entry waiting to show next
        val nextEntry = createHeadsUpEntry(id = 1)
        mAvalancheController.addToNext(nextEntry, runnableMock!!)

        // Same priority
        Truth.assertThat(nextEntry.compareNonTimeFields(showingEntry)).isEqualTo(0)

        val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
        Truth.assertThat(durationMs).isEqualTo(1000)
    }

    @Test
    fun testGetDurationMs_nextEntryHigherPriority_500() {
        // Entry is showing
        val showingEntry = createHeadsUpEntry(id = 0)
        mAvalancheController.headsUpEntryShowing = showingEntry

        // There's another entry waiting to show next
        val nextEntry = createFsiHeadsUpEntry(id = 1)
        mAvalancheController.addToNext(nextEntry, runnableMock!!)

        // Next entry has higher priority
        Truth.assertThat(nextEntry.compareNonTimeFields(showingEntry)).isEqualTo(-1)

        val durationMs = mAvalancheController.getDurationMs(showingEntry, autoDismissMs = 5000)
        Truth.assertThat(durationMs).isEqualTo(500)
    }
}
+8 −19
Original line number Diff line number Diff line
@@ -117,21 +117,6 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
        return HeadsUpManagerTestUtil.createEntry(id, notif);
    }

    private PendingIntent createFullScreenIntent() {
        return PendingIntent.getActivity(
                getContext(), 0, new Intent(getContext(), this.getClass()),
                PendingIntent.FLAG_MUTABLE_UNAUDITED);
    }

    private NotificationEntry createFullScreenIntentEntry(int id) {
        final Notification notif = new Notification.Builder(mContext, "")
                .setSmallIcon(R.drawable.ic_person)
                .setFullScreenIntent(createFullScreenIntent(), /* highPriority */ true)
                .build();
        return HeadsUpManagerTestUtil.createEntry(id, notif);
    }


    private void useAccessibilityTimeout(boolean use) {
        if (use) {
            doReturn(TEST_A11Y_AUTO_DISMISS_TIME).when(mAccessibilityMgr)
@@ -239,7 +224,8 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
    @Test
    public void testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() {
        final BaseHeadsUpManager hum = createHeadsUpManager();
        final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
        final NotificationEntry notifEntry =
                HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);

        // Add notifEntry to ANM mAlertEntries map and make it NOT unpinned
        hum.showNotification(notifEntry);
@@ -254,7 +240,8 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
    @Test
    public void testShouldHeadsUpBecomePinned_wasUnpinned_false() {
        final BaseHeadsUpManager hum = createHeadsUpManager();
        final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
        final NotificationEntry notifEntry =
                HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);

        // Add notifEntry to ANM mAlertEntries map and make it unpinned
        hum.showNotification(notifEntry);
@@ -443,7 +430,8 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
    @Test
    public void testIsSticky_hasFullScreenIntent_true() {
        final BaseHeadsUpManager hum = createHeadsUpManager();
        final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
        final NotificationEntry notifEntry =
                HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);

        hum.showNotification(notifEntry);

@@ -554,7 +542,8 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {

        // Needs full screen intent in order to be pinned
        final BaseHeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry();
        entryToPin.setEntry(createFullScreenIntentEntry(/* id = */ 0));
        entryToPin.setEntry(
                HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext));

        // Note: the standard way to show a notification would be calling showNotification rather
        // than onAlertEntryAdded. However, in practice showNotification in effect adds
+14 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.statusbar.policy;
import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.UserHandle;

import android.content.Context;
@@ -67,4 +69,16 @@ public class HeadsUpManagerTestUtil {
        return new NotificationEntryBuilder().setSbn(
                HeadsUpManagerTestUtil.createSbn(id, context)).build();
    }

    protected static NotificationEntry createFullScreenIntentEntry(int id, Context context) {
        final PendingIntent intent = PendingIntent.getActivity(
                context, 0, new Intent(),
                PendingIntent.FLAG_IMMUTABLE);

        final Notification notif = new Notification.Builder(context, "")
                .setSmallIcon(com.android.systemui.res.R.drawable.ic_person)
                .setFullScreenIntent(intent, /* highPriority */ true)
                .build();
        return HeadsUpManagerTestUtil.createEntry(id, notif);
    }
}
+25 −9
Original line number Diff line number Diff line
@@ -131,21 +131,37 @@ class AvalancheController @Inject constructor() {
    }

    /**
     * Returns true if given HeadsUpEntry is the last one tracked by AvalancheController. Used by
     * BaseHeadsUpManager.HeadsUpEntry.calculateFinishTime to shorten display duration during active
     * avalanche.
     * Returns duration based on
     * 1) Whether HeadsUpEntry is the last one tracked byAvalancheController
     * 2) The priority of the top HUN in the next batch Used by
     *    BaseHeadsUpManager.HeadsUpEntry.calculateFinishTime to shorten display duration.
     */
    fun shortenDuration(entry: HeadsUpEntry): Boolean {
    fun getDurationMs(entry: HeadsUpEntry, autoDismissMs: Int): Int {
        if (!NotificationThrottleHun.isEnabled) {
            // Use default display duration, like we always did before AvalancheController existed
            return false
            // Use default duration, like we did before AvalancheController existed
            return autoDismissMs
        }
        val showingList: MutableList<HeadsUpEntry> = mutableListOf()
        headsUpEntryShowing?.let { showingList.add(it) }
        val allEntryList = showingList + nextList

        // Shorten duration if not last entry
        return allEntryList.indexOf(entry) != allEntryList.size - 1
        val entryList = showingList + nextList
        if (entryList.indexOf(entry) == entryList.size - 1) {
            // Use default duration if last entry
            return autoDismissMs
        }

        nextList.sort()
        val nextEntry = nextList[0]

        if (nextEntry.compareNonTimeFields(entry) == -1) {
            // Next entry is higher priority
            return 500
        } else if (nextEntry.compareNonTimeFields(entry) == 0) {
            // Next entry is same priority
            return 1000
        } else {
            return autoDismissMs
        }
    }

    /**
+9 −4
Original line number Diff line number Diff line
@@ -767,7 +767,7 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager {
            return mEarliestRemovalTime < mSystemClock.elapsedRealtime();
        }

        public int compareTo(@NonNull HeadsUpEntry headsUpEntry) {
        public int compareNonTimeFields(HeadsUpEntry headsUpEntry) {
            boolean isPinned = mEntry.isRowPinned();
            boolean otherPinned = headsUpEntry.mEntry.isRowPinned();
            if (isPinned && !otherPinned) {
@@ -797,7 +797,14 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager {
            } else if (!mRemoteInputActive && headsUpEntry.mRemoteInputActive) {
                return 1;
            }
            return 0;
        }

        public int compareTo(@NonNull HeadsUpEntry headsUpEntry) {
            int nonTimeCompareResult = compareNonTimeFields(headsUpEntry);
            if (nonTimeCompareResult != 0) {
                return nonTimeCompareResult;
            }
            if (mPostTime > headsUpEntry.mPostTime) {
                return -1;
            } else if (mPostTime == headsUpEntry.mPostTime) {
@@ -920,10 +927,8 @@ public abstract class BaseHeadsUpManager implements HeadsUpManager {
            int requestedTimeOutMs;
            if (isStickyForSomeTime()) {
                requestedTimeOutMs = mStickyForSomeTimeAutoDismissTime;
            } else if (mAvalancheController.shortenDuration(this)) {
                requestedTimeOutMs = 1000;
            } else {
                requestedTimeOutMs = mAutoDismissTime;
                requestedTimeOutMs = mAvalancheController.getDurationMs(this, mAutoDismissTime);
            }
            final long duration = getRecommendedHeadsUpTimeoutMs(requestedTimeOutMs);
            return mPostTime + duration;