Merge "Fix bug where FSI decision was not logged unless FSI was launching." into udc-dev
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
"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
|
||||
}, {
|
||||
"updated entry no longer qualifies for full screen intent: $str1 because $str2"
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -809,6 +817,39 @@ class HeadsUpCoordinatorTest : SysuiTestCase() {
|
||||
verify(mHeadsUpManager, never()).showNotification(any())
|
||||
}
|
||||
|
||||
@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
|
||||
@@ -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
|
||||
|
||||
@@ -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,11 +856,36 @@ 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);
|
||||
|
||||
Reference in New Issue
Block a user