From 35599671d5422e37b92b50a35d73e3a964f39463 Mon Sep 17 00:00:00 2001 From: Julia Tuttle Date: Fri, 31 Mar 2023 19:39:21 -0400 Subject: [PATCH 1/2] HeadsUpCoordinatorTest: Remove m- prefix on fields Taking the opportunity to fix this code style issue since I'm about to modify a good fraction of the file anyway in ag/22322506. Bug: 261728888 Test: atest HeadsUpCoordinatorTest Change-Id: Ibdc23e85af495ed150c6f5899d97ddd2e40ce713 --- .../coordinator/HeadsUpCoordinatorTest.kt | 1094 ++++++++--------- 1 file changed, 547 insertions(+), 547 deletions(-) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt index 4bb14a1eba0db..e6a8d38f37a95 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt @@ -71,241 +71,241 @@ import org.mockito.MockitoAnnotations @RunWith(AndroidTestingRunner::class) @RunWithLooper class HeadsUpCoordinatorTest : SysuiTestCase() { - private lateinit var mCoordinator: HeadsUpCoordinator + private lateinit var coordinator: HeadsUpCoordinator // captured listeners and pluggables: - private lateinit var mCollectionListener: NotifCollectionListener - private lateinit var mNotifPromoter: NotifPromoter - private lateinit var mNotifLifetimeExtender: NotifLifetimeExtender - private lateinit var mBeforeTransformGroupsListener: OnBeforeTransformGroupsListener - private lateinit var mBeforeFinalizeFilterListener: OnBeforeFinalizeFilterListener - private lateinit var mOnHeadsUpChangedListener: OnHeadsUpChangedListener - private lateinit var mNotifSectioner: NotifSectioner - private lateinit var mActionPressListener: Consumer + private lateinit var collectionListener: NotifCollectionListener + private lateinit var notifPromoter: NotifPromoter + private lateinit var notifLifetimeExtender: NotifLifetimeExtender + private lateinit var beforeTransformGroupsListener: OnBeforeTransformGroupsListener + private lateinit var beforeFinalizeFilterListener: OnBeforeFinalizeFilterListener + private lateinit var onHeadsUpChangedListener: OnHeadsUpChangedListener + private lateinit var notifSectioner: NotifSectioner + private lateinit var actionPressListener: Consumer - private val mNotifPipeline: NotifPipeline = mock() - private val mLogger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true) - private val mHeadsUpManager: HeadsUpManager = mock() - private val mHeadsUpViewBinder: HeadsUpViewBinder = mock() - private val mNotificationInterruptStateProvider: NotificationInterruptStateProvider = mock() - private val mRemoteInputManager: NotificationRemoteInputManager = mock() - private val mEndLifetimeExtension: OnEndLifetimeExtensionCallback = mock() - private val mHeaderController: NodeController = mock() - private val mLaunchFullScreenIntentProvider: LaunchFullScreenIntentProvider = mock() - private val mFlags: NotifPipelineFlags = mock() + private val notifPipeline: NotifPipeline = mock() + private val logger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true) + private val headsUpManager: HeadsUpManager = mock() + private val headsUpViewBinder: HeadsUpViewBinder = mock() + private val notificationInterruptStateProvider: NotificationInterruptStateProvider = mock() + private val remoteInputManager: NotificationRemoteInputManager = mock() + private val endLifetimeExtension: OnEndLifetimeExtensionCallback = mock() + private val headerController: NodeController = mock() + private val launchFullScreenIntentProvider: LaunchFullScreenIntentProvider = mock() + private val flags: NotifPipelineFlags = mock() - private lateinit var mEntry: NotificationEntry - private lateinit var mGroupSummary: NotificationEntry - private lateinit var mGroupPriority: NotificationEntry - private lateinit var mGroupSibling1: NotificationEntry - private lateinit var mGroupSibling2: NotificationEntry - private lateinit var mGroupChild1: NotificationEntry - private lateinit var mGroupChild2: NotificationEntry - private lateinit var mGroupChild3: NotificationEntry - private val mSystemClock = FakeSystemClock() - private val mExecutor = FakeExecutor(mSystemClock) - private val mHuns: ArrayList = ArrayList() - private lateinit var mHelper: NotificationGroupTestHelper + private lateinit var entry: NotificationEntry + private lateinit var groupSummary: NotificationEntry + private lateinit var groupPriority: NotificationEntry + private lateinit var groupSibling1: NotificationEntry + private lateinit var groupSibling2: NotificationEntry + private lateinit var groupChild1: NotificationEntry + private lateinit var groupChild2: NotificationEntry + private lateinit var groupChild3: NotificationEntry + private val systemClock = FakeSystemClock() + private val executor = FakeExecutor(systemClock) + private val huns: ArrayList = ArrayList() + private lateinit var helper: NotificationGroupTestHelper @Before fun setUp() { MockitoAnnotations.initMocks(this) - mHelper = NotificationGroupTestHelper(mContext) - mCoordinator = HeadsUpCoordinator( - mLogger, - mSystemClock, - mHeadsUpManager, - mHeadsUpViewBinder, - mNotificationInterruptStateProvider, - mRemoteInputManager, - mLaunchFullScreenIntentProvider, - mFlags, - mHeaderController, - mExecutor) - mCoordinator.attach(mNotifPipeline) + helper = NotificationGroupTestHelper(mContext) + coordinator = HeadsUpCoordinator( + logger, + systemClock, + headsUpManager, + headsUpViewBinder, + notificationInterruptStateProvider, + remoteInputManager, + launchFullScreenIntentProvider, + flags, + headerController, + executor) + coordinator.attach(notifPipeline) // capture arguments: - mCollectionListener = withArgCaptor { - verify(mNotifPipeline).addCollectionListener(capture()) + collectionListener = withArgCaptor { + verify(notifPipeline).addCollectionListener(capture()) } - mNotifPromoter = withArgCaptor { - verify(mNotifPipeline).addPromoter(capture()) + notifPromoter = withArgCaptor { + verify(notifPipeline).addPromoter(capture()) } - mNotifLifetimeExtender = withArgCaptor { - verify(mNotifPipeline).addNotificationLifetimeExtender(capture()) + notifLifetimeExtender = withArgCaptor { + verify(notifPipeline).addNotificationLifetimeExtender(capture()) } - mBeforeTransformGroupsListener = withArgCaptor { - verify(mNotifPipeline).addOnBeforeTransformGroupsListener(capture()) + beforeTransformGroupsListener = withArgCaptor { + verify(notifPipeline).addOnBeforeTransformGroupsListener(capture()) } - mBeforeFinalizeFilterListener = withArgCaptor { - verify(mNotifPipeline).addOnBeforeFinalizeFilterListener(capture()) + beforeFinalizeFilterListener = withArgCaptor { + verify(notifPipeline).addOnBeforeFinalizeFilterListener(capture()) } - mOnHeadsUpChangedListener = withArgCaptor { - verify(mHeadsUpManager).addListener(capture()) + onHeadsUpChangedListener = withArgCaptor { + verify(headsUpManager).addListener(capture()) } - mActionPressListener = withArgCaptor { - verify(mRemoteInputManager).addActionPressListener(capture()) + actionPressListener = withArgCaptor { + verify(remoteInputManager).addActionPressListener(capture()) } - given(mHeadsUpManager.allEntries).willAnswer { mHuns.stream() } - given(mHeadsUpManager.isAlerting(anyString())).willAnswer { invocation -> + given(headsUpManager.allEntries).willAnswer { huns.stream() } + given(headsUpManager.isAlerting(anyString())).willAnswer { invocation -> val key = invocation.getArgument(0) - mHuns.any { entry -> entry.key == key } + huns.any { entry -> entry.key == key } } - given(mHeadsUpManager.canRemoveImmediately(anyString())).willAnswer { invocation -> + given(headsUpManager.canRemoveImmediately(anyString())).willAnswer { invocation -> val key = invocation.getArgument(0) - !mHuns.any { entry -> entry.key == key } + !huns.any { entry -> entry.key == key } } - whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) - mNotifSectioner = mCoordinator.sectioner - mNotifLifetimeExtender.setCallback(mEndLifetimeExtension) - mEntry = NotificationEntryBuilder().build() + whenever(headsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) + notifSectioner = coordinator.sectioner + notifLifetimeExtender.setCallback(endLifetimeExtension) + entry = NotificationEntryBuilder().build() // Same summary we can use for either set of children - mGroupSummary = mHelper.createSummaryNotification(GROUP_ALERT_ALL, 0, "summary", 500) + groupSummary = helper.createSummaryNotification(GROUP_ALERT_ALL, 0, "summary", 500) // One set of children with GROUP_ALERT_SUMMARY - mGroupPriority = mHelper.createChildNotification(GROUP_ALERT_SUMMARY, 0, "priority", 400) - mGroupSibling1 = mHelper.createChildNotification(GROUP_ALERT_SUMMARY, 1, "sibling", 300) - mGroupSibling2 = mHelper.createChildNotification(GROUP_ALERT_SUMMARY, 2, "sibling", 200) + groupPriority = helper.createChildNotification(GROUP_ALERT_SUMMARY, 0, "priority", 400) + groupSibling1 = helper.createChildNotification(GROUP_ALERT_SUMMARY, 1, "sibling", 300) + groupSibling2 = helper.createChildNotification(GROUP_ALERT_SUMMARY, 2, "sibling", 200) // Another set of children with GROUP_ALERT_ALL - mGroupChild1 = mHelper.createChildNotification(GROUP_ALERT_ALL, 1, "child", 350) - mGroupChild2 = mHelper.createChildNotification(GROUP_ALERT_ALL, 2, "child", 250) - mGroupChild3 = mHelper.createChildNotification(GROUP_ALERT_ALL, 3, "child", 150) + groupChild1 = helper.createChildNotification(GROUP_ALERT_ALL, 1, "child", 350) + groupChild2 = helper.createChildNotification(GROUP_ALERT_ALL, 2, "child", 250) + groupChild3 = helper.createChildNotification(GROUP_ALERT_ALL, 3, "child", 150) // Set the default FSI decision setShouldFullScreen(any(), FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) // Run tests with default feature flag state - whenever(mFlags.fsiOnDNDUpdate()).thenReturn(Flags.FSI_ON_DND_UPDATE.default) + whenever(flags.fsiOnDNDUpdate()).thenReturn(Flags.FSI_ON_DND_UPDATE.default) } @Test fun testCancelStickyNotification() { - whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true) - addHUN(mEntry) - whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false, true) - whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 0L) - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - mExecutor.advanceClockToLast() - mExecutor.runAllReady() - verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(false)) - verify(mHeadsUpManager, times(1)).removeNotification(anyString(), eq(true)) + whenever(headsUpManager.isSticky(anyString())).thenReturn(true) + addHUN(entry) + whenever(headsUpManager.canRemoveImmediately(anyString())).thenReturn(false, true) + whenever(headsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 0L) + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + executor.advanceClockToLast() + executor.runAllReady() + verify(headsUpManager, times(0)).removeNotification(anyString(), eq(false)) + verify(headsUpManager, times(1)).removeNotification(anyString(), eq(true)) } @Test fun testCancelAndReAddStickyNotification() { - whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true) - addHUN(mEntry) - whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false, true, false) - whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - addHUN(mEntry) - assertFalse(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - mExecutor.advanceClockToLast() - mExecutor.runAllReady() - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(false)) - verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(true)) + whenever(headsUpManager.isSticky(anyString())).thenReturn(true) + addHUN(entry) + whenever(headsUpManager.canRemoveImmediately(anyString())).thenReturn(false, true, false) + whenever(headsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + addHUN(entry) + assertFalse(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + executor.advanceClockToLast() + executor.runAllReady() + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + verify(headsUpManager, times(0)).removeNotification(anyString(), eq(false)) + verify(headsUpManager, times(0)).removeNotification(anyString(), eq(true)) } @Test fun hunNotRemovedWhenExtensionCancelled() { - whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true) - addHUN(mEntry) - whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false) - whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - mNotifLifetimeExtender.cancelLifetimeExtension(mEntry) - mExecutor.advanceClockToLast() - mExecutor.runAllReady() - verify(mHeadsUpManager, times(0)).removeNotification(anyString(), any()) + whenever(headsUpManager.isSticky(anyString())).thenReturn(true) + addHUN(entry) + whenever(headsUpManager.canRemoveImmediately(anyString())).thenReturn(false) + whenever(headsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + notifLifetimeExtender.cancelLifetimeExtension(entry) + executor.advanceClockToLast() + executor.runAllReady() + verify(headsUpManager, times(0)).removeNotification(anyString(), any()) } @Test fun hunExtensionCancelledWhenHunActionPressed() { - whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true) - addHUN(mEntry) - whenever(mHeadsUpManager.canRemoveImmediately(anyString())).thenReturn(false) - whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - mActionPressListener.accept(mEntry) - mExecutor.advanceClockToLast() - mExecutor.runAllReady() - verify(mHeadsUpManager, times(1)).removeNotification(eq(mEntry.key), eq(true)) + whenever(headsUpManager.isSticky(anyString())).thenReturn(true) + addHUN(entry) + whenever(headsUpManager.canRemoveImmediately(anyString())).thenReturn(false) + whenever(headsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L) + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + actionPressListener.accept(entry) + executor.advanceClockToLast() + executor.runAllReady() + verify(headsUpManager, times(1)).removeNotification(eq(entry.key), eq(true)) } @Test fun testCancelUpdatedStickyNotification() { - whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(true) - addHUN(mEntry) - whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 500L) - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - addHUN(mEntry) - mExecutor.advanceClockToLast() - mExecutor.runAllReady() - verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(false)) - verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(true)) + whenever(headsUpManager.isSticky(anyString())).thenReturn(true) + addHUN(entry) + whenever(headsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 500L) + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + addHUN(entry) + executor.advanceClockToLast() + executor.runAllReady() + verify(headsUpManager, times(0)).removeNotification(anyString(), eq(false)) + verify(headsUpManager, times(0)).removeNotification(anyString(), eq(true)) } @Test fun testCancelNotification() { - whenever(mHeadsUpManager.isSticky(anyString())).thenReturn(false) - addHUN(mEntry) - whenever(mHeadsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 500L) - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, 0)) - mExecutor.advanceClockToLast() - mExecutor.runAllReady() - verify(mHeadsUpManager, times(1)).removeNotification(anyString(), eq(false)) - verify(mHeadsUpManager, times(0)).removeNotification(anyString(), eq(true)) + whenever(headsUpManager.isSticky(anyString())).thenReturn(false) + addHUN(entry) + whenever(headsUpManager.getEarliestRemovalTime(anyString())).thenReturn(1000L, 500L) + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, 0)) + executor.advanceClockToLast() + executor.runAllReady() + verify(headsUpManager, times(1)).removeNotification(anyString(), eq(false)) + verify(headsUpManager, times(0)).removeNotification(anyString(), eq(true)) } @Test fun testOnEntryAdded_shouldFullScreen() { - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_EXPECTED_NOT_TO_HUN) - mCollectionListener.onEntryAdded(mEntry) - verify(mLaunchFullScreenIntentProvider).launchFullScreenIntent(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_EXPECTED_NOT_TO_HUN) + collectionListener.onEntryAdded(entry) + verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry) } @Test fun testOnEntryAdded_shouldNotFullScreen() { - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) - mCollectionListener.onEntryAdded(mEntry) - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) + collectionListener.onEntryAdded(entry) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) } @Test fun testPromotesAddedHUN() { // GIVEN the current entry should heads up - whenever(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(true) + whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(true) // WHEN the notification is added but not yet binding - mCollectionListener.onEntryAdded(mEntry) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mEntry), any()) + collectionListener.onEntryAdded(entry) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any()) // THEN only promote mEntry - assertTrue(mNotifPromoter.shouldPromoteToTopLevel(mEntry)) + assertTrue(notifPromoter.shouldPromoteToTopLevel(entry)) } @Test fun testPromotesBindingHUN() { // GIVEN the current entry should heads up - whenever(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(true) + whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(true) // WHEN the notification started binding on the previous run - mCollectionListener.onEntryAdded(mEntry) - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) - verify(mHeadsUpViewBinder).bindHeadsUpView(eq(mEntry), any()) + collectionListener.onEntryAdded(entry) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) + verify(headsUpViewBinder).bindHeadsUpView(eq(entry), any()) // THEN only promote mEntry - assertTrue(mNotifPromoter.shouldPromoteToTopLevel(mEntry)) + assertTrue(notifPromoter.shouldPromoteToTopLevel(entry)) } @Test fun testPromotesCurrentHUN() { // GIVEN the current HUN is set to mEntry - addHUN(mEntry) + addHUN(entry) // THEN only promote the current HUN, mEntry - assertTrue(mNotifPromoter.shouldPromoteToTopLevel(mEntry)) - assertFalse(mNotifPromoter.shouldPromoteToTopLevel(NotificationEntryBuilder() + assertTrue(notifPromoter.shouldPromoteToTopLevel(entry)) + assertFalse(notifPromoter.shouldPromoteToTopLevel(NotificationEntryBuilder() .setPkg("test-package2") .build())) } @@ -313,11 +313,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { @Test fun testIncludeInSectionCurrentHUN() { // GIVEN the current HUN is set to mEntry - addHUN(mEntry) + addHUN(entry) // THEN only section the current HUN, mEntry - assertTrue(mNotifSectioner.isInSection(mEntry)) - assertFalse(mNotifSectioner.isInSection(NotificationEntryBuilder() + assertTrue(notifSectioner.isInSection(entry)) + assertFalse(notifSectioner.isInSection(NotificationEntryBuilder() .setPkg("test-package") .build())) } @@ -325,11 +325,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { @Test fun testLifetimeExtendsCurrentHUN() { // GIVEN there is a HUN, mEntry - addHUN(mEntry) + addHUN(entry) // THEN only the current HUN, mEntry, should be lifetimeExtended - assertTrue(mNotifLifetimeExtender.maybeExtendLifetime(mEntry, /* cancellationReason */ 0)) - assertFalse(mNotifLifetimeExtender.maybeExtendLifetime( + assertTrue(notifLifetimeExtender.maybeExtendLifetime(entry, /* cancellationReason */ 0)) + assertFalse(notifLifetimeExtender.maybeExtendLifetime( NotificationEntryBuilder() .setPkg("test-package") .build(), /* cancellationReason */ 0)) @@ -338,726 +338,726 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { @Test fun testShowHUNOnInflationFinished() { // WHEN a notification should HUN and its inflation is finished - whenever(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(true) + whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(true) - mCollectionListener.onEntryAdded(mEntry) - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) - verify(mHeadsUpManager, never()).showNotification(mEntry) + collectionListener.onEntryAdded(entry) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) + verify(headsUpManager, never()).showNotification(entry) withArgCaptor { - verify(mHeadsUpViewBinder).bindHeadsUpView(eq(mEntry), capture()) - }.onBindFinished(mEntry) + verify(headsUpViewBinder).bindHeadsUpView(eq(entry), capture()) + }.onBindFinished(entry) // THEN we tell the HeadsUpManager to show the notification - verify(mHeadsUpManager).showNotification(mEntry) + verify(headsUpManager).showNotification(entry) } @Test fun testNoHUNOnInflationFinished() { // WHEN a notification shouldn't HUN and its inflation is finished - whenever(mNotificationInterruptStateProvider.shouldHeadsUp(mEntry)).thenReturn(false) - mCollectionListener.onEntryAdded(mEntry) - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(false) + collectionListener.onEntryAdded(entry) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN we never bind the heads up view or tell HeadsUpManager to show the notification - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mEntry), any()) - verify(mHeadsUpManager, never()).showNotification(mEntry) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(entry), any()) + verify(headsUpManager, never()).showNotification(entry) } @Test fun testOnEntryUpdated_toAlert() { // GIVEN that an entry is posted that should not heads up - setShouldHeadsUp(mEntry, false) - mCollectionListener.onEntryAdded(mEntry) + setShouldHeadsUp(entry, false) + collectionListener.onEntryAdded(entry) // WHEN it's updated to heads up - setShouldHeadsUp(mEntry) - mCollectionListener.onEntryUpdated(mEntry) - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + setShouldHeadsUp(entry) + collectionListener.onEntryUpdated(entry) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN the notification alerts - finishBind(mEntry) - verify(mHeadsUpManager).showNotification(mEntry) + finishBind(entry) + verify(headsUpManager).showNotification(entry) } @Test fun testOnEntryUpdated_toNotAlert() { // GIVEN that an entry is posted that should heads up - setShouldHeadsUp(mEntry) - mCollectionListener.onEntryAdded(mEntry) + setShouldHeadsUp(entry) + collectionListener.onEntryAdded(entry) // WHEN it's updated to not heads up - setShouldHeadsUp(mEntry, false) - mCollectionListener.onEntryUpdated(mEntry) - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + setShouldHeadsUp(entry, false) + collectionListener.onEntryUpdated(entry) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN the notification is never bound or shown - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - verify(mHeadsUpManager, never()).showNotification(any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(headsUpManager, never()).showNotification(any()) } @Test fun testOnEntryRemovedRemovesHeadsUpNotification() { // GIVEN the current HUN is mEntry - addHUN(mEntry) + addHUN(entry) // WHEN mEntry is removed from the notification collection - mCollectionListener.onEntryRemoved(mEntry, /* cancellation reason */ 0) - whenever(mRemoteInputManager.isSpinning(any())).thenReturn(false) + collectionListener.onEntryRemoved(entry, /* cancellation reason */ 0) + whenever(remoteInputManager.isSpinning(any())).thenReturn(false) // THEN heads up manager should remove the entry - verify(mHeadsUpManager).removeNotification(mEntry.key, false) + verify(headsUpManager).removeNotification(entry.key, false) } private fun addHUN(entry: NotificationEntry) { - mHuns.add(entry) - whenever(mHeadsUpManager.topEntry).thenReturn(entry) - mOnHeadsUpChangedListener.onHeadsUpStateChanged(entry, true) - mNotifLifetimeExtender.cancelLifetimeExtension(entry) + huns.add(entry) + whenever(headsUpManager.topEntry).thenReturn(entry) + onHeadsUpChangedListener.onHeadsUpStateChanged(entry, true) + notifLifetimeExtender.cancelLifetimeExtension(entry) } @Test fun testTransferIsolatedChildAlert_withGroupAlertSummary() { - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mGroupSummary, mGroupSibling1)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs).thenReturn(listOf(groupSummary, groupSibling1)) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupSibling1) - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mGroupSibling1)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mGroupSibling1)) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupSibling1) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupSibling1)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupSibling1)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupSibling1) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupSibling1) - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupSibling1) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupSibling1) // In addition make sure we have explicitly marked the summary as having interrupted due // to the alert being transferred - assertTrue(mGroupSummary.hasInterrupted()) + assertTrue(groupSummary.hasInterrupted()) } @Test fun testTransferIsolatedChildAlert_withGroupAlertAll() { - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mGroupSummary, mGroupChild1)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs).thenReturn(listOf(groupSummary, groupChild1)) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupChild1) - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mGroupChild1)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mGroupChild1)) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupChild1) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupChild1)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupChild1)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupChild1) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupChild1) - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupChild1) - assertTrue(mGroupSummary.hasInterrupted()) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupChild1) + assertTrue(groupSummary.hasInterrupted()) } @Test fun testTransferTwoIsolatedChildAlert_withGroupAlertSummary() { // WHEN a notification should HUN and its inflation is finished - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupSibling1, mGroupSibling2, mGroupPriority)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupSibling1, groupSibling2, groupPriority)) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupSibling1) - mCollectionListener.onEntryAdded(mGroupSibling2) - val entryList = listOf(mGroupSibling1, mGroupSibling2) - mBeforeTransformGroupsListener.onBeforeTransformGroups(entryList) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(entryList) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupSibling1) + collectionListener.onEntryAdded(groupSibling2) + val entryList = listOf(groupSibling1, groupSibling2) + beforeTransformGroupsListener.onBeforeTransformGroups(entryList) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(entryList) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupSibling1) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling2), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupSibling1) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any()) // THEN we tell the HeadsUpManager to show the notification - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupSibling1) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling2) - assertTrue(mGroupSummary.hasInterrupted()) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupSibling1) + verify(headsUpManager, never()).showNotification(groupSibling2) + assertTrue(groupSummary.hasInterrupted()) } @Test fun testTransferTwoIsolatedChildAlert_withGroupAlertAll() { // WHEN a notification should HUN and its inflation is finished - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupChild1, mGroupChild2, mGroupPriority)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupChild1, groupChild2, groupPriority)) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupChild1) - mCollectionListener.onEntryAdded(mGroupChild2) - val entryList = listOf(mGroupChild1, mGroupChild2) - mBeforeTransformGroupsListener.onBeforeTransformGroups(entryList) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(entryList) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupChild1) + collectionListener.onEntryAdded(groupChild2) + val entryList = listOf(groupChild1, groupChild2) + beforeTransformGroupsListener.onBeforeTransformGroups(entryList) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(entryList) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupChild1) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupChild2), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupChild1) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any()) // THEN we tell the HeadsUpManager to show the notification - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupChild1) - verify(mHeadsUpManager, never()).showNotification(mGroupChild2) - assertTrue(mGroupSummary.hasInterrupted()) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupChild1) + verify(headsUpManager, never()).showNotification(groupChild2) + assertTrue(groupSummary.hasInterrupted()) } @Test fun testTransferToPriorityOnAddWithTwoSiblings() { // WHEN a notification should HUN and its inflation is finished - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupSibling1, mGroupSibling2, mGroupPriority)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupSibling1, groupSibling2, groupPriority)) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupPriority) - mCollectionListener.onEntryAdded(mGroupSibling1) - mCollectionListener.onEntryAdded(mGroupSibling2) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupPriority) + collectionListener.onEntryAdded(groupSibling1) + collectionListener.onEntryAdded(groupSibling2) val beforeTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupPriority, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupPriority, groupSibling2)) .build() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) val afterTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupSibling2)) .build() - mBeforeFinalizeFilterListener - .onBeforeFinalizeFilter(listOf(mGroupPriority, afterTransformGroup)) + beforeFinalizeFilterListener + .onBeforeFinalizeFilter(listOf(groupPriority, afterTransformGroup)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupPriority) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling1), any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling2), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupPriority) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any()) // THEN we tell the HeadsUpManager to show the notification - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupPriority) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling1) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling2) - assertTrue(mGroupSummary.hasInterrupted()) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupPriority) + verify(headsUpManager, never()).showNotification(groupSibling1) + verify(headsUpManager, never()).showNotification(groupSibling2) + assertTrue(groupSummary.hasInterrupted()) } @Test fun testTransferToPriorityOnUpdateWithTwoSiblings() { - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupSibling1, mGroupSibling2, mGroupPriority)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupSibling1, groupSibling2, groupPriority)) - mCollectionListener.onEntryUpdated(mGroupSummary) - mCollectionListener.onEntryUpdated(mGroupPriority) - mCollectionListener.onEntryUpdated(mGroupSibling1) - mCollectionListener.onEntryUpdated(mGroupSibling2) + collectionListener.onEntryUpdated(groupSummary) + collectionListener.onEntryUpdated(groupPriority) + collectionListener.onEntryUpdated(groupSibling1) + collectionListener.onEntryUpdated(groupSibling2) val beforeTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupPriority, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupPriority, groupSibling2)) .build() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) val afterTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupSibling2)) .build() - mBeforeFinalizeFilterListener - .onBeforeFinalizeFilter(listOf(mGroupPriority, afterTransformGroup)) + beforeFinalizeFilterListener + .onBeforeFinalizeFilter(listOf(groupPriority, afterTransformGroup)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupPriority) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling1), any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling2), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupPriority) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any()) - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupPriority) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling1) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling2) - assertTrue(mGroupSummary.hasInterrupted()) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupPriority) + verify(headsUpManager, never()).showNotification(groupSibling1) + verify(headsUpManager, never()).showNotification(groupSibling2) + assertTrue(groupSummary.hasInterrupted()) } @Test fun testTransferToPriorityOnUpdateWithTwoNonUpdatedSiblings() { - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupSibling1, mGroupSibling2, mGroupPriority)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupSibling1, groupSibling2, groupPriority)) - mCollectionListener.onEntryUpdated(mGroupSummary) - mCollectionListener.onEntryUpdated(mGroupPriority) + collectionListener.onEntryUpdated(groupSummary) + collectionListener.onEntryUpdated(groupPriority) val beforeTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupPriority, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupPriority, groupSibling2)) .build() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) val afterTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupSibling2)) .build() - mBeforeFinalizeFilterListener - .onBeforeFinalizeFilter(listOf(mGroupPriority, afterTransformGroup)) + beforeFinalizeFilterListener + .onBeforeFinalizeFilter(listOf(groupPriority, afterTransformGroup)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupPriority) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling1), any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling2), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupPriority) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any()) - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupPriority) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling1) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling2) - assertTrue(mGroupSummary.hasInterrupted()) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupPriority) + verify(headsUpManager, never()).showNotification(groupSibling1) + verify(headsUpManager, never()).showNotification(groupSibling2) + assertTrue(groupSummary.hasInterrupted()) } @Test fun testNoTransferToPriorityOnUpdateOfTwoSiblings() { - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupSibling1, mGroupSibling2, mGroupPriority)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupSibling1, groupSibling2, groupPriority)) - mCollectionListener.onEntryUpdated(mGroupSummary) - mCollectionListener.onEntryUpdated(mGroupSibling1) - mCollectionListener.onEntryUpdated(mGroupSibling2) + collectionListener.onEntryUpdated(groupSummary) + collectionListener.onEntryUpdated(groupSibling1) + collectionListener.onEntryUpdated(groupSibling2) val beforeTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupPriority, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupPriority, groupSibling2)) .build() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(beforeTransformGroup)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) val afterTransformGroup = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupSibling2)) .build() - mBeforeFinalizeFilterListener - .onBeforeFinalizeFilter(listOf(mGroupPriority, afterTransformGroup)) + beforeFinalizeFilterListener + .onBeforeFinalizeFilter(listOf(groupPriority, afterTransformGroup)) - finishBind(mGroupSummary) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupPriority), any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling1), any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling2), any()) + finishBind(groupSummary) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupPriority), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any()) - verify(mHeadsUpManager).showNotification(mGroupSummary) - verify(mHeadsUpManager, never()).showNotification(mGroupPriority) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling1) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling2) + verify(headsUpManager).showNotification(groupSummary) + verify(headsUpManager, never()).showNotification(groupPriority) + verify(headsUpManager, never()).showNotification(groupSibling1) + verify(headsUpManager, never()).showNotification(groupSibling2) } @Test fun testNoTransferTwoChildAlert_withGroupAlertSummary() { - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupSibling1, mGroupSibling2)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupSibling1, groupSibling2)) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupSibling1) - mCollectionListener.onEntryAdded(mGroupSibling2) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupSibling1) + collectionListener.onEntryAdded(groupSibling2) val groupEntry = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupSibling1, mGroupSibling2)) + .setSummary(groupSummary) + .setChildren(listOf(groupSibling1, groupSibling2)) .build() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry)) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry)) - finishBind(mGroupSummary) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling1), any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSibling2), any()) + finishBind(groupSummary) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling1), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSibling2), any()) - verify(mHeadsUpManager).showNotification(mGroupSummary) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling1) - verify(mHeadsUpManager, never()).showNotification(mGroupSibling2) + verify(headsUpManager).showNotification(groupSummary) + verify(headsUpManager, never()).showNotification(groupSibling1) + verify(headsUpManager, never()).showNotification(groupSibling2) } @Test fun testNoTransferTwoChildAlert_withGroupAlertAll() { - setShouldHeadsUp(mGroupSummary) - whenever(mNotifPipeline.allNotifs) - .thenReturn(listOf(mGroupSummary, mGroupChild1, mGroupChild2)) + setShouldHeadsUp(groupSummary) + whenever(notifPipeline.allNotifs) + .thenReturn(listOf(groupSummary, groupChild1, groupChild2)) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupChild1) - mCollectionListener.onEntryAdded(mGroupChild2) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupChild1) + collectionListener.onEntryAdded(groupChild2) val groupEntry = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupChild1, mGroupChild2)) + .setSummary(groupSummary) + .setChildren(listOf(groupChild1, groupChild2)) .build() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry)) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry)) - finishBind(mGroupSummary) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupChild1), any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupChild2), any()) + finishBind(groupSummary) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild1), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any()) - verify(mHeadsUpManager).showNotification(mGroupSummary) - verify(mHeadsUpManager, never()).showNotification(mGroupChild1) - verify(mHeadsUpManager, never()).showNotification(mGroupChild2) + verify(headsUpManager).showNotification(groupSummary) + verify(headsUpManager, never()).showNotification(groupChild1) + verify(headsUpManager, never()).showNotification(groupChild2) } @Test fun testNoTransfer_groupSummaryNotAlerting() { // When we have a group where the summary should not alert and exactly one child should // alert, we should never mark the group summary as interrupted (because it doesn't). - setShouldHeadsUp(mGroupSummary, false) - setShouldHeadsUp(mGroupChild1, true) - setShouldHeadsUp(mGroupChild2, false) + setShouldHeadsUp(groupSummary, false) + setShouldHeadsUp(groupChild1, true) + setShouldHeadsUp(groupChild2, false) - mCollectionListener.onEntryAdded(mGroupSummary) - mCollectionListener.onEntryAdded(mGroupChild1) - mCollectionListener.onEntryAdded(mGroupChild2) + collectionListener.onEntryAdded(groupSummary) + collectionListener.onEntryAdded(groupChild1) + collectionListener.onEntryAdded(groupChild2) val groupEntry = GroupEntryBuilder() - .setSummary(mGroupSummary) - .setChildren(listOf(mGroupChild1, mGroupChild2)) + .setSummary(groupSummary) + .setChildren(listOf(groupChild1, groupChild2)) .build() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry)) + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(groupEntry)) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(groupEntry)) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupSummary), any()) - finishBind(mGroupChild1) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(eq(mGroupChild2), any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupSummary), any()) + finishBind(groupChild1) + verify(headsUpViewBinder, never()).bindHeadsUpView(eq(groupChild2), any()) - verify(mHeadsUpManager, never()).showNotification(mGroupSummary) - verify(mHeadsUpManager).showNotification(mGroupChild1) - verify(mHeadsUpManager, never()).showNotification(mGroupChild2) - assertFalse(mGroupSummary.hasInterrupted()) + verify(headsUpManager, never()).showNotification(groupSummary) + verify(headsUpManager).showNotification(groupChild1) + verify(headsUpManager, never()).showNotification(groupChild2) + assertFalse(groupSummary.hasInterrupted()) } @Test fun testOnRankingApplied_newEntryShouldAlert() { // GIVEN that mEntry has never interrupted in the past, and now should // and is new enough to do so - assertFalse(mEntry.hasInterrupted()) - mCoordinator.setUpdateTime(mEntry, mSystemClock.currentTimeMillis()) - setShouldHeadsUp(mEntry) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) + assertFalse(entry.hasInterrupted()) + coordinator.setUpdateTime(entry, systemClock.currentTimeMillis()) + setShouldHeadsUp(entry) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) // WHEN a ranking applied update occurs - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN the notification is shown - finishBind(mEntry) - verify(mHeadsUpManager).showNotification(mEntry) + finishBind(entry) + verify(headsUpManager).showNotification(entry) } @Test fun testOnRankingApplied_alreadyAlertedEntryShouldNotAlertAgain() { // GIVEN that mEntry has alerted in the past, even if it's new - mEntry.setInterruption() - mCoordinator.setUpdateTime(mEntry, mSystemClock.currentTimeMillis()) - setShouldHeadsUp(mEntry) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) + entry.setInterruption() + coordinator.setUpdateTime(entry, systemClock.currentTimeMillis()) + setShouldHeadsUp(entry) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) // WHEN a ranking applied update occurs - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN the notification is never bound or shown - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - verify(mHeadsUpManager, never()).showNotification(any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(headsUpManager, never()).showNotification(any()) } @Test fun testOnRankingApplied_entryUpdatedToHun() { // GIVEN that mEntry is added in a state where it should not HUN - setShouldHeadsUp(mEntry, false) - mCollectionListener.onEntryAdded(mEntry) + setShouldHeadsUp(entry, false) + collectionListener.onEntryAdded(entry) // and it is then updated such that it should now HUN - setShouldHeadsUp(mEntry) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) + setShouldHeadsUp(entry) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) // WHEN a ranking applied update occurs - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN the notification is shown - finishBind(mEntry) - verify(mHeadsUpManager).showNotification(mEntry) + finishBind(entry) + verify(headsUpManager).showNotification(entry) } @Test fun testOnRankingApplied_entryUpdatedButTooOld() { // GIVEN that mEntry is added in a state where it should not HUN - setShouldHeadsUp(mEntry, false) - mCollectionListener.onEntryAdded(mEntry) + setShouldHeadsUp(entry, false) + collectionListener.onEntryAdded(entry) // and it was actually added 10s ago - mCoordinator.setUpdateTime(mEntry, mSystemClock.currentTimeMillis() - 10000) + coordinator.setUpdateTime(entry, systemClock.currentTimeMillis() - 10000) // WHEN it is updated to HUN and then a ranking update occurs - setShouldHeadsUp(mEntry) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + setShouldHeadsUp(entry) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN the notification is never bound or shown - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - verify(mHeadsUpManager, never()).showNotification(any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(headsUpManager, never()).showNotification(any()) } @Test fun onEntryAdded_whenLaunchingFSI_doesLogDecision() { // GIVEN A new notification can FSI - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + collectionListener.onEntryAdded(entry) - verify(mLaunchFullScreenIntentProvider).launchFullScreenIntent(mEntry) - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( - mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision( + entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) } @Test fun onEntryAdded_whenNotLaunchingFSI_doesLogDecision() { // GIVEN A new notification can't FSI - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) + collectionListener.onEntryAdded(entry) - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( - mEntry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision( + entry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) } @Test fun onEntryAdded_whenNotLaunchingFSIBecauseOfDnd_doesLogDecision() { // GIVEN A new notification can't FSI because of DND - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + collectionListener.onEntryAdded(entry) - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( - mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision( + entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) } @Test fun testOnRankingApplied_noFSIOnUpdateWhenFlagOff() { // Ensure the feature flag is off - whenever(mFlags.fsiOnDNDUpdate()).thenReturn(false) + whenever(flags.fsiOnDNDUpdate()).thenReturn(false) // GIVEN that mEntry was previously suppressed from full-screen only by DND - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + collectionListener.onEntryAdded(entry) // Verify that this causes a log - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( - mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - clearInvocations(mNotificationInterruptStateProvider) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision( + entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + clearInvocations(notificationInterruptStateProvider) // and it is then updated to allow full screen - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) - mCollectionListener.onRankingApplied() + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) + collectionListener.onRankingApplied() // THEN it should not full screen because the feature is off - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) // VERIFY that no additional logging happens either - verify(mNotificationInterruptStateProvider, never()) + verify(notificationInterruptStateProvider, never()) .logFullScreenIntentDecision(any(), any()) } @Test fun testOnRankingApplied_updateToFullScreen() { // Turn on the feature - whenever(mFlags.fsiOnDNDUpdate()).thenReturn(true) + whenever(flags.fsiOnDNDUpdate()).thenReturn(true) // GIVEN that mEntry was previously suppressed from full-screen only by DND - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + collectionListener.onEntryAdded(entry) // at this point, it should not have full screened, but should have logged - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision(mEntry, + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - clearInvocations(mNotificationInterruptStateProvider) + clearInvocations(notificationInterruptStateProvider) // and it is then updated to allow full screen AND HUN - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - setShouldHeadsUp(mEntry) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + setShouldHeadsUp(entry) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN it should full screen and log but it should NOT HUN - verify(mLaunchFullScreenIntentProvider).launchFullScreenIntent(mEntry) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - verify(mHeadsUpManager, never()).showNotification(any()) - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision(mEntry, + verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(headsUpManager, never()).showNotification(any()) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - clearInvocations(mNotificationInterruptStateProvider) + clearInvocations(notificationInterruptStateProvider) // WHEN ranking updates again and the pipeline reruns - clearInvocations(mLaunchFullScreenIntentProvider) - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + clearInvocations(launchFullScreenIntentProvider) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // VERIFY that the FSI does not launch again or log - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(mNotificationInterruptStateProvider, never()) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(notificationInterruptStateProvider, never()) .logFullScreenIntentDecision(any(), any()) } @Test fun testOnRankingApplied_withOnlyDndSuppressionAllowsFsiLater() { // Turn on the feature - whenever(mFlags.fsiOnDNDUpdate()).thenReturn(true) + whenever(flags.fsiOnDNDUpdate()).thenReturn(true) // GIVEN that mEntry was previously suppressed from full-screen only by DND - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + collectionListener.onEntryAdded(entry) // at this point, it should not have full screened, but should have logged - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision(mEntry, + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - clearInvocations(mNotificationInterruptStateProvider) + clearInvocations(notificationInterruptStateProvider) // ranking is applied with only DND blocking FSI - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN it should still not yet full screen or HUN - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - verify(mHeadsUpManager, never()).showNotification(any()) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(headsUpManager, never()).showNotification(any()) // Same decision as before; is not logged - verify(mNotificationInterruptStateProvider, never()) + verify(notificationInterruptStateProvider, never()) .logFullScreenIntentDecision(any(), any()) - clearInvocations(mNotificationInterruptStateProvider) + clearInvocations(notificationInterruptStateProvider) // and it is then updated to allow full screen AND HUN - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - setShouldHeadsUp(mEntry) - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + setShouldHeadsUp(entry) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN it should full screen and log but it should NOT HUN - verify(mLaunchFullScreenIntentProvider).launchFullScreenIntent(mEntry) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - verify(mHeadsUpManager, never()).showNotification(any()) - verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision(mEntry, + verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(headsUpManager, never()).showNotification(any()) + verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - clearInvocations(mNotificationInterruptStateProvider) + clearInvocations(notificationInterruptStateProvider) } @Test fun testOnRankingApplied_newNonFullScreenAnswerInvalidatesCandidate() { // Turn on the feature - whenever(mFlags.fsiOnDNDUpdate()).thenReturn(true) + whenever(flags.fsiOnDNDUpdate()).thenReturn(true) // GIVEN that mEntry was previously suppressed from full-screen only by DND - whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - mCollectionListener.onEntryAdded(mEntry) + whenever(notifPipeline.allNotifs).thenReturn(listOf(entry)) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + collectionListener.onEntryAdded(entry) // at this point, it should not have full screened - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(mEntry) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(entry) // now some other condition blocks FSI in addition to DND - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_BY_DND) - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_BY_DND) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // THEN it should NOT full screen or HUN - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) - verify(mHeadsUpManager, never()).showNotification(any()) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(headsUpManager, never()).showNotification(any()) // NOW the DND logic changes and FSI and HUN are available - clearInvocations(mLaunchFullScreenIntentProvider) - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - setShouldHeadsUp(mEntry) - mCollectionListener.onRankingApplied() - mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) - mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + clearInvocations(launchFullScreenIntentProvider) + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + setShouldHeadsUp(entry) + collectionListener.onRankingApplied() + beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) + beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) // VERIFY that the FSI didn't happen, but that we do HUN - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - finishBind(mEntry) - verify(mHeadsUpManager).showNotification(mEntry) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + finishBind(entry) + verify(headsUpManager).showNotification(entry) } @Test fun testOnRankingApplied_noFSIWhenAlsoSuppressedForOtherReasons() { // Feature on - whenever(mFlags.fsiOnDNDUpdate()).thenReturn(true) + whenever(flags.fsiOnDNDUpdate()).thenReturn(true) // GIVEN that mEntry is suppressed by DND (functionally), but not *only* DND - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_BY_DND) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_BY_DND) + collectionListener.onEntryAdded(entry) // and it is updated to full screen later - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - mCollectionListener.onRankingApplied() + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + collectionListener.onRankingApplied() // THEN it should still not full screen because something else was blocking it before - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(mEntry) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(entry) } @Test fun testOnRankingApplied_noFSIWhenTooOld() { // Feature on - whenever(mFlags.fsiOnDNDUpdate()).thenReturn(true) + whenever(flags.fsiOnDNDUpdate()).thenReturn(true) // GIVEN that mEntry is suppressed only by DND - setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - mCollectionListener.onEntryAdded(mEntry) + setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + collectionListener.onEntryAdded(entry) // but it's >10s old - mCoordinator.addForFSIReconsideration(mEntry, mSystemClock.currentTimeMillis() - 10000) + coordinator.addForFSIReconsideration(entry, systemClock.currentTimeMillis() - 10000) // and it is updated to full screen later - setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_EXPECTED_NOT_TO_HUN) - mCollectionListener.onRankingApplied() + setShouldFullScreen(entry, FullScreenIntentDecision.FSI_EXPECTED_NOT_TO_HUN) + collectionListener.onRankingApplied() // THEN it should still not full screen because it's too old - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(mEntry) + verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(entry) } private fun setShouldHeadsUp(entry: NotificationEntry, should: Boolean = true) { - whenever(mNotificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(should) - whenever(mNotificationInterruptStateProvider.checkHeadsUp(eq(entry), any())) + whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(should) + whenever(notificationInterruptStateProvider.checkHeadsUp(eq(entry), any())) .thenReturn(should) } private fun setShouldFullScreen(entry: NotificationEntry, decision: FullScreenIntentDecision) { - whenever(mNotificationInterruptStateProvider.getFullScreenIntentDecision(entry)) + whenever(notificationInterruptStateProvider.getFullScreenIntentDecision(entry)) .thenReturn(decision) } private fun finishBind(entry: NotificationEntry) { - verify(mHeadsUpManager, never()).showNotification(entry) + verify(headsUpManager, never()).showNotification(entry) withArgCaptor { - verify(mHeadsUpViewBinder).bindHeadsUpView(eq(entry), capture()) + verify(headsUpViewBinder).bindHeadsUpView(eq(entry), capture()) }.onBindFinished(entry) } } From 36c1010e4a71120552f5d6119a4b6a5b33b38a3a Mon Sep 17 00:00:00 2001 From: Julia Tuttle Date: Tue, 28 Mar 2023 14:13:01 -0400 Subject: [PATCH 2/2] HeadsUpCoordinatorTest: Factor out some methods To make the transition from the NotificationInterruptStateProvider interface to the VisualInterruptionDecisionProvider interface smoother, factor all the calls into those classes out into a few methods. Bug: 261728888 Test: atest HeadsUpCoordinatorTest Change-Id: I19407258a503065cfe14ddc941b723e21bc148d9 --- .../coordinator/HeadsUpCoordinatorTest.kt | 90 ++++++++++++------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt index e6a8d38f37a95..ba91d87c659a8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt @@ -273,7 +273,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { @Test fun testPromotesAddedHUN() { // GIVEN the current entry should heads up - whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(true) + setShouldHeadsUp(entry, true) // WHEN the notification is added but not yet binding collectionListener.onEntryAdded(entry) @@ -286,7 +286,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { @Test fun testPromotesBindingHUN() { // GIVEN the current entry should heads up - whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(true) + setShouldHeadsUp(entry, true) // WHEN the notification started binding on the previous run collectionListener.onEntryAdded(entry) @@ -338,7 +338,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { @Test fun testShowHUNOnInflationFinished() { // WHEN a notification should HUN and its inflation is finished - whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(true) + setShouldHeadsUp(entry, true) collectionListener.onEntryAdded(entry) beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) @@ -355,7 +355,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { @Test fun testNoHUNOnInflationFinished() { // WHEN a notification shouldn't HUN and its inflation is finished - whenever(notificationInterruptStateProvider.shouldHeadsUp(entry)).thenReturn(false) + setShouldHeadsUp(entry, false) collectionListener.onEntryAdded(entry) beforeTransformGroupsListener.onBeforeTransformGroups(listOf(entry)) beforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(entry)) @@ -824,8 +824,10 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { collectionListener.onEntryAdded(entry) verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry) - verify(notificationInterruptStateProvider).logFullScreenIntentDecision( - entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + verifyLoggedFullScreenIntentDecision( + entry, + FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE + ) } @Test @@ -835,8 +837,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { collectionListener.onEntryAdded(entry) verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(notificationInterruptStateProvider).logFullScreenIntentDecision( - entry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) + verifyLoggedFullScreenIntentDecision(entry, FullScreenIntentDecision.NO_FULL_SCREEN_INTENT) } @Test @@ -846,8 +847,10 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { collectionListener.onEntryAdded(entry) verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(notificationInterruptStateProvider).logFullScreenIntentDecision( - entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + verifyLoggedFullScreenIntentDecision( + entry, + FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND + ) } @Test @@ -860,9 +863,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { collectionListener.onEntryAdded(entry) // Verify that this causes a log - verify(notificationInterruptStateProvider).logFullScreenIntentDecision( - entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - clearInvocations(notificationInterruptStateProvider) + verifyLoggedFullScreenIntentDecision( + entry, + FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND + ) + clearInterruptionProviderInvocations() // and it is then updated to allow full screen setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) @@ -873,8 +878,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) // VERIFY that no additional logging happens either - verify(notificationInterruptStateProvider, never()) - .logFullScreenIntentDecision(any(), any()) + verifyNoFullScreenIntentDecisionLogged() } @Test @@ -888,9 +892,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { // at this point, it should not have full screened, but should have logged verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, - FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - clearInvocations(notificationInterruptStateProvider) + verifyLoggedFullScreenIntentDecision( + entry, + FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND + ) + clearInterruptionProviderInvocations() // and it is then updated to allow full screen AND HUN setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) @@ -904,9 +910,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry) verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) verify(headsUpManager, never()).showNotification(any()) - verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, - FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - clearInvocations(notificationInterruptStateProvider) + verifyLoggedFullScreenIntentDecision( + entry, + FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE + ) + clearInterruptionProviderInvocations() // WHEN ranking updates again and the pipeline reruns clearInvocations(launchFullScreenIntentProvider) @@ -916,8 +924,7 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { // VERIFY that the FSI does not launch again or log verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(notificationInterruptStateProvider, never()) - .logFullScreenIntentDecision(any(), any()) + verifyNoFullScreenIntentDecisionLogged() } @Test @@ -931,9 +938,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { // at this point, it should not have full screened, but should have logged verify(launchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) - verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, - FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) - clearInvocations(notificationInterruptStateProvider) + verifyLoggedFullScreenIntentDecision( + entry, + FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND + ) + clearInterruptionProviderInvocations() // ranking is applied with only DND blocking FSI setShouldFullScreen(entry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) @@ -947,9 +956,8 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { verify(headsUpManager, never()).showNotification(any()) // Same decision as before; is not logged - verify(notificationInterruptStateProvider, never()) - .logFullScreenIntentDecision(any(), any()) - clearInvocations(notificationInterruptStateProvider) + verifyNoFullScreenIntentDecisionLogged() + clearInterruptionProviderInvocations() // and it is then updated to allow full screen AND HUN setShouldFullScreen(entry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) @@ -963,9 +971,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { verify(launchFullScreenIntentProvider).launchFullScreenIntent(entry) verify(headsUpViewBinder, never()).bindHeadsUpView(any(), any()) verify(headsUpManager, never()).showNotification(any()) - verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, - FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) - clearInvocations(notificationInterruptStateProvider) + verifyLoggedFullScreenIntentDecision( + entry, + FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE + ) + clearInterruptionProviderInvocations() } @Test @@ -1054,6 +1064,22 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { .thenReturn(decision) } + private fun verifyLoggedFullScreenIntentDecision( + entry: NotificationEntry, + decision: FullScreenIntentDecision + ) { + verify(notificationInterruptStateProvider).logFullScreenIntentDecision(entry, decision) + } + + private fun verifyNoFullScreenIntentDecisionLogged() { + verify(notificationInterruptStateProvider, never()) + .logFullScreenIntentDecision(any(), any()) + } + + private fun clearInterruptionProviderInvocations() { + clearInvocations(notificationInterruptStateProvider) + } + private fun finishBind(entry: NotificationEntry) { verify(headsUpManager, never()).showNotification(entry) withArgCaptor {