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

Commit e0b1ad1c authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[Notif] Merge HeadsUpManagerPhone into BaseHeadsUpManager.

Arc used to have its own implementation of BaseHeadsUpManager, which is
why HeadsUpManagerPhone was originally created. Since the Arc
implementation no longer exists, we can combine BaseHeadsUpManager and
HeadsUpManagerPhone into a single class to reduce cognitive load.

Also adds explicit @Override to methods that are implementing the
HeadsUpManager interface, and moves Javadoc from HeadsUpManagerPhone to
the HeadsUpManagerinterface. Otherwise, tries to leave the existing code
unchanged.

Bug: 378142453
Flag: EXEMPT refactor
Test: SysUI + all variants compile
Test: Key notification CUJs work:
 - Receive notif while unlocked -> notif HUNs
 - Swipe up on HUN -> notif snoozed
 - Swipe left/right on HUN -> notif dismissed
 - Tap on HUN -> launches activity
 - Receive notif while locked with bypass enabled -> notif HUNs
 - Receive notif while locked with bypass disabled -> notif becomes part
   of stack
 - Enable notification cooldown -> notifs cool down

Test: atest BaseHeadsUpManagerTest HeadsUpManagerPhoneTest
Change-Id: Id1722d845c910f95e9ec37c39f67195ddbf7226f
parent 622356e8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.statusbar.NotificationRemoteInputManager
import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
import com.android.systemui.statusbar.notification.HeadsUpManagerPhone
import com.android.systemui.statusbar.notification.NotifPipelineFlags
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotifPipeline
@@ -52,6 +51,7 @@ import com.android.systemui.statusbar.notification.interruption.NotificationInte
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback
import com.android.systemui.statusbar.phone.NotificationGroupTestHelper
import com.android.systemui.statusbar.policy.BaseHeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
import com.android.systemui.testKosmos
import com.android.systemui.util.concurrency.FakeExecutor
@@ -101,7 +101,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() {

    private val notifPipeline: NotifPipeline = mock()
    private val logger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true)
    private val headsUpManager: HeadsUpManagerPhone = mock()
    private val headsUpManager: BaseHeadsUpManager = mock()
    private val headsUpViewBinder: HeadsUpViewBinder = mock()
    private val visualInterruptionDecisionProvider: VisualInterruptionDecisionProvider = mock()
    private val remoteInputManager: NotificationRemoteInputManager = mock()
+21 −7
Original line number Diff line number Diff line
@@ -24,11 +24,19 @@ import androidx.test.filters.SmallTest
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.plugins.statusbar.statusBarStateController
import com.android.systemui.shade.domain.interactor.shadeInteractor
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
import com.android.systemui.statusbar.phone.keyguardBypassController
import com.android.systemui.statusbar.policy.HeadsUpManagerTestUtil.createFullScreenIntentEntry
import com.android.systemui.testKosmos
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.kotlin.JavaAdapter
import com.android.systemui.util.settings.FakeGlobalSettings
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -48,6 +56,7 @@ import org.mockito.junit.MockitoRule
@RunWith(AndroidJUnit4::class)
@EnableFlags(NotificationThrottleHun.FLAG_NAME)
class AvalancheControllerTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    // For creating mocks
    @get:Rule var rule: MockitoRule = MockitoJUnit.rule()
@@ -61,7 +70,6 @@ class AvalancheControllerTest : SysuiTestCase() {
    @Mock private val mAccessibilityMgr: AccessibilityManagerWrapper? = null
    private val mUiEventLoggerFake = UiEventLoggerFake()
    @Mock private lateinit var mHeadsUpManagerLogger: HeadsUpManagerLogger

    @Mock private lateinit var mBgHandler: Handler

    private val mLogger = Mockito.spy(HeadsUpManagerLogger(logcatLogBuffer()))
@@ -76,26 +84,33 @@ class AvalancheControllerTest : SysuiTestCase() {
        Mockito.`when`(
                mAccessibilityMgr!!.getRecommendedTimeoutMillis(
                    ArgumentMatchers.anyInt(),
                    ArgumentMatchers.anyInt()
                    ArgumentMatchers.anyInt(),
                )
            )
            .then { i: InvocationOnMock -> i.getArgument(0) }

        // Initialize AvalancheController and TestableHeadsUpManager during setUp instead of
        // declaration, where mocks are null
        mAvalancheController = AvalancheController(dumpManager, mUiEventLoggerFake,
                mHeadsUpManagerLogger, mBgHandler)
        mAvalancheController =
            AvalancheController(dumpManager, mUiEventLoggerFake, mHeadsUpManagerLogger, mBgHandler)

        testableHeadsUpManager =
            TestableHeadsUpManager(
                mContext,
                mLogger,
                kosmos.statusBarStateController,
                kosmos.keyguardBypassController,
                GroupMembershipManagerImpl(),
                kosmos.visualStabilityProvider,
                kosmos.configurationController,
                mExecutor,
                mGlobalSettings,
                mSystemClock,
                mAccessibilityMgr,
                mUiEventLoggerFake,
                mAvalancheController
                JavaAdapter(kosmos.testScope),
                kosmos.shadeInteractor,
                mAvalancheController,
            )
    }

@@ -270,7 +285,6 @@ class AvalancheControllerTest : SysuiTestCase() {
        assertThat(mAvalancheController.headsUpEntryShowing).isEqualTo(nextEntry)
    }


    @Test
    fun testDelete_deleteSecondToLastEntry_showingEntryKeyBecomesPreviousHunKey() {
        mAvalancheController.previousHunKey = ""
@@ -305,7 +319,7 @@ class AvalancheControllerTest : SysuiTestCase() {
        mAvalancheController.delete(showingEntry, runnableMock!!, "testLabel")

        // Next entry is shown
        assertThat(mAvalancheController.previousHunKey).isEqualTo("");
        assertThat(mAvalancheController.previousHunKey).isEqualTo("")
    }

    @Test
+30 −42
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
@@ -49,15 +51,21 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.kosmos.KosmosJavaAdapter;
import com.android.systemui.res.R;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.settings.FakeGlobalSettings;
import com.android.systemui.util.time.FakeSystemClock;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -73,7 +81,10 @@ import java.util.List;
@SmallTest
@TestableLooper.RunWithLooper
@RunWith(ParameterizedAndroidJunit4.class)
// TODO(b/378142453): Merge this with BaseHeadsUpManagerTest.
public class BaseHeadsUpManagerTest extends SysuiTestCase {
    protected KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);

    @Rule
    public MockitoRule rule = MockitoJUnit.rule();

@@ -85,6 +96,7 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
    private final HeadsUpManagerLogger mLogger = spy(new HeadsUpManagerLogger(logcatLogBuffer()));
    @Mock private Handler mBgHandler;
    @Mock private DumpManager dumpManager;
    @Mock private ShadeInteractor mShadeInteractor;
    private AvalancheController mAvalancheController;

    @Mock private AccessibilityManagerWrapper mAccessibilityMgr;
@@ -108,8 +120,22 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
    }

    private BaseHeadsUpManager createHeadsUpManager() {
        return new TestableHeadsUpManager(mContext, mLogger, mExecutor, mGlobalSettings,
                mSystemClock, mAccessibilityMgr, mUiEventLoggerFake, mAvalancheController);
        return new TestableHeadsUpManager(
                mContext,
                mLogger,
                mKosmos.getStatusBarStateController(),
                mKosmos.getKeyguardBypassController(),
                new GroupMembershipManagerImpl(),
                mKosmos.getVisualStabilityProvider(),
                mKosmos.getConfigurationController(),
                mExecutor,
                mGlobalSettings,
                mSystemClock,
                mAccessibilityMgr,
                mUiEventLoggerFake,
                new JavaAdapter(mKosmos.getTestScope()),
                mShadeInteractor,
                mAvalancheController);
    }

    private NotificationEntry createStickyEntry(int id) {
@@ -152,6 +178,8 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
        super.SysuiSetup();
        mAvalancheController = new AvalancheController(dumpManager, mUiEventLoggerFake, mLogger,
                mBgHandler);
        when(mShadeInteractor.isAnyExpanded()).thenReturn(MutableStateFlow(true));
        when(mKosmos.getKeyguardBypassController().getBypassEnabled()).thenReturn(false);
    }

    @Test
@@ -298,46 +326,6 @@ public class BaseHeadsUpManagerTest extends SysuiTestCase {
        verify(mLogger, times(1)).logNotificationActuallyRemoved(eq(notifEntry));
    }

    @Test
    public void testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() {
        final BaseHeadsUpManager hum = createHeadsUpManager();
        final NotificationEntry notifEntry =
                HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);

        // Add notifEntry to ANM mAlertEntries map and make it NOT unpinned
        hum.showNotification(notifEntry);

        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
                notifEntry.getKey());
        headsUpEntry.mWasUnpinned = false;

        assertTrue(hum.shouldHeadsUpBecomePinned(notifEntry));
    }

    @Test
    public void testShouldHeadsUpBecomePinned_wasUnpinned_false() {
        final BaseHeadsUpManager hum = createHeadsUpManager();
        final NotificationEntry notifEntry =
                HeadsUpManagerTestUtil.createFullScreenIntentEntry(/* id = */ 0, mContext);

        // Add notifEntry to ANM mAlertEntries map and make it unpinned
        hum.showNotification(notifEntry);

        final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
                notifEntry.getKey());
        headsUpEntry.mWasUnpinned = true;

        assertFalse(hum.shouldHeadsUpBecomePinned(notifEntry));
    }

    @Test
    public void testShouldHeadsUpBecomePinned_noFSI_false() {
        final BaseHeadsUpManager hum = createHeadsUpManager();
        final NotificationEntry entry = HeadsUpManagerTestUtil.createEntry(/* id = */ 0, mContext);

        assertFalse(hum.shouldHeadsUpBecomePinned(entry));
    }


    @Test
    public void testShowNotification_autoDismissesIncludingTouchAcceptanceDelay() {
+74 −186

File changed.

Preview size limit exceeded, changes collapsed.

+32 −9
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.statusbar.policy;

import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.util.concurrency.MockExecutorHandlerKt.mockExecutorHandler;

import static org.mockito.Mockito.spy;
@@ -28,8 +27,14 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.logging.UiEventLogger;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shade.domain.interactor.ShadeInteractor;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.settings.GlobalSettings;
import com.android.systemui.util.time.SystemClock;

@@ -37,16 +42,39 @@ class TestableHeadsUpManager extends BaseHeadsUpManager {

    private HeadsUpEntry mLastCreatedEntry;

    TestableHeadsUpManager(Context context,
    TestableHeadsUpManager(
            Context context,
            HeadsUpManagerLogger logger,
            StatusBarStateController statusBarStateController,
            KeyguardBypassController bypassController,
            GroupMembershipManager groupMembershipManager,
            VisualStabilityProvider visualStabilityProvider,
            ConfigurationController configurationController,
            DelayableExecutor executor,
            GlobalSettings globalSettings,
            SystemClock systemClock,
            AccessibilityManagerWrapper accessibilityManagerWrapper,
            UiEventLogger uiEventLogger,
            JavaAdapter javaAdapter,
            ShadeInteractor shadeInteractor,
            AvalancheController avalancheController) {
        super(context, logger, mockExecutorHandler(executor), globalSettings, systemClock,
                executor, accessibilityManagerWrapper, uiEventLogger, avalancheController);
        super(
                context,
                logger,
                statusBarStateController,
                bypassController,
                groupMembershipManager,
                visualStabilityProvider,
                configurationController,
                mockExecutorHandler(executor),
                globalSettings,
                systemClock,
                executor,
                accessibilityManagerWrapper,
                uiEventLogger,
                javaAdapter,
                shadeInteractor,
                avalancheController);

        mTouchAcceptanceDelay = BaseHeadsUpManagerTest.TEST_TOUCH_ACCEPTANCE_TIME;
        mMinimumDisplayTime = BaseHeadsUpManagerTest.TEST_MINIMUM_DISPLAY_TIME;
@@ -61,11 +89,6 @@ class TestableHeadsUpManager extends BaseHeadsUpManager {
        return mLastCreatedEntry;
    }

    @Override
    public int getContentFlag() {
        return FLAG_CONTENT_VIEW_CONTRACTED;
    }

    // The following are only implemented by HeadsUpManagerPhone. If you need them, use that.
    @Override
    public void addHeadsUpPhoneListener(@NonNull OnHeadsUpPhoneListenerChange listener) {
Loading