diff options
6 files changed, 248 insertions, 58 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt index 1004ec195493..4d0e746735aa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt @@ -389,11 +389,11 @@ class HeadsUpCoordinator @Inject constructor( // First check whether this notification should launch a full screen intent, and // launch it if needed. val fsiDecision = mNotificationInterruptStateProvider.getFullScreenIntentDecision(entry) - if (fsiDecision != null && fsiDecision.shouldLaunch) { - mNotificationInterruptStateProvider.logFullScreenIntentDecision(entry, fsiDecision) + mNotificationInterruptStateProvider.logFullScreenIntentDecision(entry, fsiDecision) + if (fsiDecision.shouldLaunch) { mLaunchFullScreenIntentProvider.launchFullScreenIntent(entry) } else if (mFlags.fsiOnDNDUpdate() && - fsiDecision.equals(FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND)) { + fsiDecision == FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) { // If DND was the only reason this entry was suppressed, note it for potential // reconsideration on later ranking updates. addForFSIReconsideration(entry, mSystemClock.currentTimeMillis()) @@ -514,14 +514,24 @@ class HeadsUpCoordinator @Inject constructor( mNotificationInterruptStateProvider.getFullScreenIntentDecision(entry) if (decision.shouldLaunch) { // Log both the launch of the full screen and also that this was via a - // ranking update. - mLogger.logEntryUpdatedToFullScreen(entry.key) + // ranking update, and finally revoke candidacy for FSI reconsideration + mLogger.logEntryUpdatedToFullScreen(entry.key, decision.name) mNotificationInterruptStateProvider.logFullScreenIntentDecision( entry, decision) mLaunchFullScreenIntentProvider.launchFullScreenIntent(entry) + mFSIUpdateCandidates.remove(entry.key) // if we launch the FSI then this is no longer a candidate for HUN continue + } else if (decision == FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) { + // decision has not changed; no need to log + } else { + // some other condition is now blocking FSI; log that and revoke candidacy + // for FSI reconsideration + mLogger.logEntryDisqualifiedFromFullScreen(entry.key, decision.name) + mNotificationInterruptStateProvider.logFullScreenIntentDecision( + entry, decision) + mFSIUpdateCandidates.remove(entry.key) } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt index 2c6bf6b51451..e9365594fad7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt @@ -70,11 +70,21 @@ class HeadsUpCoordinatorLogger constructor( }) } - fun logEntryUpdatedToFullScreen(key: String) { + fun logEntryUpdatedToFullScreen(key: String, reason: String) { buffer.log(TAG, LogLevel.DEBUG, { str1 = key + str2 = reason + }, { + "updating entry to launch full screen intent: $str1 because $str2" + }) + } + + fun logEntryDisqualifiedFromFullScreen(key: String, reason: String) { + buffer.log(TAG, LogLevel.DEBUG, { + str1 = key + str2 = reason }, { - "updating entry to launch full screen intent: $str1" + "updated entry no longer qualifies for full screen intent: $str1 because $str2" }) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java index 9001470ad406..5ba8801e0f63 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.notification.interruption; +import androidx.annotation.NonNull; + import com.android.systemui.statusbar.notification.collection.NotificationEntry; /** @@ -153,7 +155,8 @@ public interface NotificationInterruptStateProvider { * @param entry the entry to evaluate * @return FullScreenIntentDecision representing the decision for whether to show the intent */ - FullScreenIntentDecision getFullScreenIntentDecision(NotificationEntry entry); + @NonNull + FullScreenIntentDecision getFullScreenIntentDecision(@NonNull NotificationEntry entry); /** * Write the full screen launch decision for the given entry to logs. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java index 9f45b9d67189..274377f5b0dd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java @@ -35,6 +35,8 @@ import android.service.dreams.IDreamManager; import android.service.notification.StatusBarNotification; import android.util.Log; +import androidx.annotation.NonNull; + import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; @@ -232,6 +234,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter // suppressor. // // If the entry was not suppressed by DND, just returns the given decision. + @NonNull private FullScreenIntentDecision getDecisionGivenSuppression(FullScreenIntentDecision decision, boolean suppressedByDND) { if (suppressedByDND) { @@ -243,7 +246,7 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter } @Override - public FullScreenIntentDecision getFullScreenIntentDecision(NotificationEntry entry) { + public FullScreenIntentDecision getFullScreenIntentDecision(@NonNull NotificationEntry entry) { if (entry.getSbn().getNotification().fullScreenIntent == null) { if (entry.isStickyAndNotDemoted()) { return FullScreenIntentDecision.NO_FSI_SHOW_STICKY_HUN; @@ -336,52 +339,30 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter final int uid = entry.getSbn().getUid(); final String packageName = entry.getSbn().getPackageName(); switch (decision) { - case NO_FSI_SHOW_STICKY_HUN: - mLogger.logNoFullscreen(entry, "Permission denied, show sticky HUN"); - return; case NO_FULL_SCREEN_INTENT: - return; - case NO_FSI_SUPPRESSED_BY_DND: - case NO_FSI_SUPPRESSED_ONLY_BY_DND: - mLogger.logNoFullscreen(entry, "Suppressed by DND"); - return; - case NO_FSI_NOT_IMPORTANT_ENOUGH: - mLogger.logNoFullscreen(entry, "Not important enough"); + // explicitly prevent logging for this (frequent) case return; case NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR: android.util.EventLog.writeEvent(0x534e4554, "231322873", uid, "groupAlertBehavior"); mUiEventLogger.log(FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR, uid, packageName); - mLogger.logNoFullscreenWarning(entry, "GroupAlertBehavior will prevent HUN"); - return; - case FSI_DEVICE_NOT_INTERACTIVE: - mLogger.logFullscreen(entry, "Device is not interactive"); - return; - case FSI_DEVICE_IS_DREAMING: - mLogger.logFullscreen(entry, "Device is dreaming"); - return; - case FSI_KEYGUARD_SHOWING: - mLogger.logFullscreen(entry, "Keyguard is showing"); - return; - case NO_FSI_EXPECTED_TO_HUN: - mLogger.logNoFullscreen(entry, "Expected to HUN"); - return; - case FSI_KEYGUARD_OCCLUDED: - mLogger.logFullscreen(entry, - "Expected not to HUN while keyguard occluded"); - return; - case FSI_LOCKED_SHADE: - mLogger.logFullscreen(entry, "Keyguard is showing and not occluded"); + mLogger.logNoFullscreenWarning(entry, + decision + ": GroupAlertBehavior will prevent HUN"); return; case NO_FSI_NO_HUN_OR_KEYGUARD: android.util.EventLog.writeEvent(0x534e4554, "231322873", uid, "no hun or keyguard"); mUiEventLogger.log(FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD, uid, packageName); - mLogger.logNoFullscreenWarning(entry, "Expected not to HUN while not on keyguard"); + mLogger.logNoFullscreenWarning(entry, + decision + ": Expected not to HUN while not on keyguard"); return; - case FSI_EXPECTED_NOT_TO_HUN: - mLogger.logFullscreen(entry, "Expected not to HUN"); + default: + if (decision.shouldLaunch) { + mLogger.logFullscreen(entry, decision.name()); + } else { + mLogger.logNoFullscreen(entry, decision.name()); + } } } 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 cb4f119dce0a..4bb14a1eba0d 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 @@ -22,6 +22,7 @@ import android.testing.TestableLooper.RunWithLooper import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.dump.logcatLogBuffer +import com.android.systemui.flags.Flags import com.android.systemui.statusbar.NotificationRemoteInputManager import com.android.systemui.statusbar.notification.NotifPipelineFlags import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder @@ -58,6 +59,7 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyString +import org.mockito.BDDMockito.clearInvocations import org.mockito.BDDMockito.given import org.mockito.Mockito.never import org.mockito.Mockito.times @@ -166,6 +168,12 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { 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) + + // 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) } @Test @@ -810,6 +818,39 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { } @Test + fun onEntryAdded_whenLaunchingFSI_doesLogDecision() { + // GIVEN A new notification can FSI + setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + mCollectionListener.onEntryAdded(mEntry) + + verify(mLaunchFullScreenIntentProvider).launchFullScreenIntent(mEntry) + verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( + mEntry, 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) + + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( + mEntry, 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) + + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( + mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + } + + @Test fun testOnRankingApplied_noFSIOnUpdateWhenFlagOff() { // Ensure the feature flag is off whenever(mFlags.fsiOnDNDUpdate()).thenReturn(false) @@ -818,13 +859,22 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) mCollectionListener.onEntryAdded(mEntry) + // Verify that this causes a log + verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision( + mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + clearInvocations(mNotificationInterruptStateProvider) + // and it is then updated to allow full screen setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) whenever(mNotifPipeline.allNotifs).thenReturn(listOf(mEntry)) mCollectionListener.onRankingApplied() // THEN it should not full screen because the feature is off - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(mEntry) + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + + // VERIFY that no additional logging happens either + verify(mNotificationInterruptStateProvider, never()) + .logFullScreenIntentDecision(any(), any()) } @Test @@ -836,8 +886,11 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { setShouldFullScreen(mEntry, FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) mCollectionListener.onEntryAdded(mEntry) - // at this point, it should not have full screened - verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(mEntry) + // at this point, it should not have full screened, but should have logged + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision(mEntry, + FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + clearInvocations(mNotificationInterruptStateProvider) // and it is then updated to allow full screen AND HUN setShouldFullScreen(mEntry, FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) @@ -847,10 +900,110 @@ class HeadsUpCoordinatorTest : SysuiTestCase() { mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) - // THEN it should full screen but it should NOT HUN + // 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, + FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + clearInvocations(mNotificationInterruptStateProvider) + + // WHEN ranking updates again and the pipeline reruns + clearInvocations(mLaunchFullScreenIntentProvider) + mCollectionListener.onRankingApplied() + mBeforeTransformGroupsListener.onBeforeTransformGroups(listOf(mEntry)) + mBeforeFinalizeFilterListener.onBeforeFinalizeFilter(listOf(mEntry)) + + // VERIFY that the FSI does not launch again or log + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(mNotificationInterruptStateProvider, never()) + .logFullScreenIntentDecision(any(), any()) + } + + @Test + fun testOnRankingApplied_withOnlyDndSuppressionAllowsFsiLater() { + // Turn on the feature + whenever(mFlags.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) + + // at this point, it should not have full screened, but should have logged + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(mNotificationInterruptStateProvider).logFullScreenIntentDecision(mEntry, + FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND) + clearInvocations(mNotificationInterruptStateProvider) + + // 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)) + + // 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()) + + // Same decision as before; is not logged + verify(mNotificationInterruptStateProvider, never()) + .logFullScreenIntentDecision(any(), any()) + clearInvocations(mNotificationInterruptStateProvider) + + // 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)) + + // 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, + FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE) + clearInvocations(mNotificationInterruptStateProvider) + } + + @Test + fun testOnRankingApplied_newNonFullScreenAnswerInvalidatesCandidate() { + // Turn on the feature + whenever(mFlags.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) + + // at this point, it should not have full screened + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(mEntry) + + // 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)) + + // THEN it should NOT full screen or HUN + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + verify(mHeadsUpViewBinder, never()).bindHeadsUpView(any(), any()) + verify(mHeadsUpManager, 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)) + + // VERIFY that the FSI didn't happen, but that we do HUN + verify(mLaunchFullScreenIntentProvider, never()).launchFullScreenIntent(any()) + finishBind(mEntry) + verify(mHeadsUpManager).showNotification(mEntry) } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java index 07d0dbd65afb..8acf507e3452 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java @@ -36,9 +36,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.app.ActivityManager; @@ -76,6 +79,10 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + /** * Tests for the interruption state provider which understands whether the system & notification * is in a state allowing a particular notification to hun, pulse, or bubble. @@ -560,7 +567,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isFalse(); verify(mLogger, never()).logFullscreen(any(), any()); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); - verify(mLogger).logNoFullscreen(entry, "Suppressed by DND"); + verify(mLogger).logNoFullscreen(entry, "NO_FSI_SUPPRESSED_ONLY_BY_DND"); } @Test @@ -579,7 +586,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isFalse(); verify(mLogger, never()).logFullscreen(any(), any()); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); - verify(mLogger).logNoFullscreen(entry, "Suppressed by DND"); + verify(mLogger).logNoFullscreen(entry, "NO_FSI_SUPPRESSED_BY_DND"); } @Test @@ -599,7 +606,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isEqualTo(FullScreenIntentDecision.NO_FSI_NOT_IMPORTANT_ENOUGH); assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) .isFalse(); - verify(mLogger).logNoFullscreen(entry, "Not important enough"); + verify(mLogger).logNoFullscreen(entry, "NO_FSI_NOT_IMPORTANT_ENOUGH"); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); verify(mLogger, never()).logFullscreen(any(), any()); } @@ -622,7 +629,8 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) .isFalse(); verify(mLogger, never()).logNoFullscreen(any(), any()); - verify(mLogger).logNoFullscreenWarning(entry, "GroupAlertBehavior will prevent HUN"); + verify(mLogger).logNoFullscreenWarning(entry, + "NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR: GroupAlertBehavior will prevent HUN"); verify(mLogger, never()).logFullscreen(any(), any()); assertThat(mUiEventLoggerFake.numLogs()).isEqualTo(1); @@ -652,7 +660,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isTrue(); verify(mLogger, never()).logNoFullscreen(any(), any()); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); - verify(mLogger).logFullscreen(entry, "Device is not interactive"); + verify(mLogger).logFullscreen(entry, "FSI_DEVICE_NOT_INTERACTIVE"); } @Test @@ -674,7 +682,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isTrue(); verify(mLogger, never()).logNoFullscreen(any(), any()); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); - verify(mLogger).logFullscreen(entry, "Device is dreaming"); + verify(mLogger).logFullscreen(entry, "FSI_DEVICE_IS_DREAMING"); } @Test @@ -696,7 +704,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isTrue(); verify(mLogger, never()).logNoFullscreen(any(), any()); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); - verify(mLogger).logFullscreen(entry, "Keyguard is showing"); + verify(mLogger).logFullscreen(entry, "FSI_KEYGUARD_SHOWING"); } @Test @@ -717,7 +725,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isEqualTo(FullScreenIntentDecision.NO_FSI_EXPECTED_TO_HUN); assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) .isFalse(); - verify(mLogger).logNoFullscreen(entry, "Expected to HUN"); + verify(mLogger).logNoFullscreen(entry, "NO_FSI_EXPECTED_TO_HUN"); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); verify(mLogger, never()).logFullscreen(any(), any()); } @@ -737,7 +745,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isTrue(); verify(mLogger, never()).logNoFullscreen(any(), any()); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); - verify(mLogger).logFullscreen(entry, "Expected not to HUN"); + verify(mLogger).logFullscreen(entry, "FSI_EXPECTED_NOT_TO_HUN"); } @Test @@ -756,7 +764,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isEqualTo(FullScreenIntentDecision.NO_FSI_EXPECTED_TO_HUN); assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) .isFalse(); - verify(mLogger).logNoFullscreen(entry, "Expected to HUN"); + verify(mLogger).logNoFullscreen(entry, "NO_FSI_EXPECTED_TO_HUN"); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); verify(mLogger, never()).logFullscreen(any(), any()); } @@ -802,7 +810,7 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isEqualTo(FullScreenIntentDecision.NO_FSI_EXPECTED_TO_HUN); assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) .isFalse(); - verify(mLogger).logNoFullscreen(entry, "Expected to HUN"); + verify(mLogger).logNoFullscreen(entry, "NO_FSI_EXPECTED_TO_HUN"); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); verify(mLogger, never()).logFullscreen(any(), any()); } @@ -848,12 +856,37 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase { .isEqualTo(FullScreenIntentDecision.NO_FSI_EXPECTED_TO_HUN); assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) .isFalse(); - verify(mLogger).logNoFullscreen(entry, "Expected to HUN"); + verify(mLogger).logNoFullscreen(entry, "NO_FSI_EXPECTED_TO_HUN"); verify(mLogger, never()).logNoFullscreenWarning(any(), any()); verify(mLogger, never()).logFullscreen(any(), any()); } @Test + public void logFullScreenIntentDecision_shouldAlmostAlwaysLogOneTime() { + NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false); + Set<FullScreenIntentDecision> warnings = new HashSet<>(Arrays.asList( + FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR, + FullScreenIntentDecision.NO_FSI_NO_HUN_OR_KEYGUARD + )); + for (FullScreenIntentDecision decision : FullScreenIntentDecision.values()) { + clearInvocations(mLogger); + boolean expectedToLog = decision != FullScreenIntentDecision.NO_FULL_SCREEN_INTENT; + boolean isWarning = warnings.contains(decision); + mNotifInterruptionStateProvider.logFullScreenIntentDecision(entry, decision); + if (decision.shouldLaunch) { + verify(mLogger).logFullscreen(eq(entry), contains(decision.name())); + } else if (expectedToLog) { + if (isWarning) { + verify(mLogger).logNoFullscreenWarning(eq(entry), contains(decision.name())); + } else { + verify(mLogger).logNoFullscreen(eq(entry), contains(decision.name())); + } + } + verifyNoMoreInteractions(mLogger); + } + } + + @Test public void testShouldHeadsUp_snoozed_unlocked_withStrictRules() throws Exception { when(mFlags.fullScreenIntentRequiresKeyguard()).thenReturn(true); NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false); |