diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt index ff0e47f3cfecc..e436ccfd66c67 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt @@ -77,6 +77,8 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( private val secureSettings: SecureSettings, private val globalSettings: GlobalSettings ) : CoreStartable(context), KeyguardNotificationVisibilityProvider { + private val showSilentNotifsUri = + secureSettings.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS) private val onStateChangedListeners = ListenerSet>() private var hideSilentNotificationsOnLockscreen: Boolean = false @@ -100,6 +102,9 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( // register lockscreen settings changed callbacks: val settingsObserver: ContentObserver = object : ContentObserver(handler) { override fun onChange(selfChange: Boolean, uri: Uri?) { + if (uri == showSilentNotifsUri) { + readShowSilentNotificationSetting() + } if (keyguardStateController.isShowing) { notifyStateChanged("Settings $uri changed") } @@ -152,62 +157,50 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( onStateChangedListeners.forEach { it.accept(reason) } } - override fun shouldHideNotification(entry: NotificationEntry): Boolean { - val sbn = entry.sbn - // FILTER OUT the notification when the keyguard is showing and... - if (keyguardStateController.isShowing) { - // ... user settings or the device policy manager doesn't allow lockscreen - // notifications; - if (!lockscreenUserManager.shouldShowLockscreenNotifications()) { - return true - } - val currUserId: Int = lockscreenUserManager.currentUserId - val notifUserId = - if (sbn.user.identifier == UserHandle.USER_ALL) currUserId - else sbn.user.identifier - - // ... user is in lockdown - if (keyguardUpdateMonitor.isUserInLockdown(currUserId) || - keyguardUpdateMonitor.isUserInLockdown(notifUserId)) { - return true - } - - // ... device is in public mode and the user's settings doesn't allow - // notifications to show in public mode - if (lockscreenUserManager.isLockscreenPublicMode(currUserId) || - lockscreenUserManager.isLockscreenPublicMode(notifUserId)) { - if (entry.ranking.lockscreenVisibilityOverride == Notification.VISIBILITY_SECRET) { - return true - } - if (!lockscreenUserManager.userAllowsNotificationsInPublic(currUserId) || - !lockscreenUserManager.userAllowsNotificationsInPublic( - notifUserId)) { - return true - } - } - - // ... neither this notification nor its group have high enough priority - // to be shown on the lockscreen - if (entry.parent != null) { - val parent = entry.parent - if (priorityExceedsLockscreenShowingThreshold(parent)) { - return false - } - } - return !priorityExceedsLockscreenShowingThreshold(entry) - } - return false + override fun shouldHideNotification(entry: NotificationEntry): Boolean = when { + // Keyguard state doesn't matter if the keyguard is not showing. + !keyguardStateController.isShowing -> false + // Notifications not allowed on the lockscreen, always hide. + !lockscreenUserManager.shouldShowLockscreenNotifications() -> true + // User settings do not allow this notification on the lockscreen, so hide it. + userSettingsDisallowNotification(entry) -> true + // Parent priority is high enough to be shown on the lockscreen, do not hide. + entry.parent?.let(::priorityExceedsLockscreenShowingThreshold) == true -> false + // Entry priority is high enough to be shown on the lockscreen, do not hide. + priorityExceedsLockscreenShowingThreshold(entry) -> false + // Priority is too low, hide. + else -> true } - private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry?): Boolean = - when { - entry == null -> false - hideSilentNotificationsOnLockscreen -> highPriorityProvider.isHighPriority(entry) - else -> entry.representativeEntry?.ranking?.isAmbient == false + private fun userSettingsDisallowNotification(entry: NotificationEntry): Boolean { + fun disallowForUser(user: Int) = when { + // user is in lockdown, always disallow + keyguardUpdateMonitor.isUserInLockdown(user) -> true + // device isn't public, no need to check public-related settings, so allow + !lockscreenUserManager.isLockscreenPublicMode(user) -> false + // entry is meant to be secret on the lockscreen, disallow + entry.ranking.lockscreenVisibilityOverride == Notification.VISIBILITY_SECRET -> true + // disallow if user disallows notifications in public + else -> !lockscreenUserManager.userAllowsNotificationsInPublic(user) } + val currentUser = lockscreenUserManager.currentUserId + val notifUser = entry.sbn.user.identifier + return when { + disallowForUser(currentUser) -> true + notifUser == UserHandle.USER_ALL -> false + notifUser == currentUser -> false + else -> disallowForUser(notifUser) + } + } + + private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry): Boolean = when { + hideSilentNotificationsOnLockscreen -> highPriorityProvider.isHighPriority(entry) + else -> entry.representativeEntry?.ranking?.isAmbient == false + } private fun readShowSilentNotificationSetting() { - hideSilentNotificationsOnLockscreen = + val showSilentNotifs = secureSettings.getBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, true) + hideSilentNotificationsOnLockscreen = !showSilentNotifs } -} \ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java index 32d625c707cf6..4e07d59242297 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.interruption; import static android.app.Notification.VISIBILITY_PUBLIC; import static android.app.Notification.VISIBILITY_SECRET; import static android.app.NotificationManager.IMPORTANCE_HIGH; +import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_MIN; import static com.android.systemui.statusbar.notification.collection.EntryUtilKt.modifyEntry; @@ -209,7 +210,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer listener = mock(Consumer.class); mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener); - mFakeSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1); + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, true); verify(listener).accept(anyString()); } @@ -220,7 +221,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer listener = mock(Consumer.class); mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener); - mFakeSettings.putInt(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1); + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, true); verify(listener).accept(anyString()); } @@ -231,7 +232,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer listener = mock(Consumer.class); mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener); - mFakeSettings.putInt(Settings.Global.ZEN_MODE, 1); + mFakeSettings.putBool(Settings.Global.ZEN_MODE, true); verify(listener).accept(anyString()); } @@ -242,7 +243,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer listener = mock(Consumer.class); mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener); - mFakeSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1); + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, true); verify(listener).accept(anyString()); } @@ -337,6 +338,25 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { assertTrue(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry)); } + @Test + public void showSilentOnLockscreenSetting() { + // GIVEN an 'unfiltered-keyguard-showing' state + setupUnfilteredState(mEntry); + + // WHEN the notification is not high priority and not ambient + mEntry.setRanking(new RankingBuilder() + .setKey(mEntry.getKey()) + .setImportance(IMPORTANCE_LOW) + .build()); + when(mHighPriorityProvider.isHighPriority(mEntry)).thenReturn(false); + + // WHEN the show silent notifs on lockscreen setting is true + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, true); + + // THEN do not filter out the entry + assertFalse(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry)); + } + @Test public void summaryExceedsThresholdToShow() { // GIVEN the notification doesn't exceed the threshold to show on the lockscreen @@ -360,6 +380,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { .build()); // WHEN its parent does exceed threshold tot show on the lockscreen + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false); when(mHighPriorityProvider.isHighPriority(parent)).thenReturn(true); // THEN don't filter out the entry