Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt +44 −51 Original line number Diff line number Diff line Loading @@ -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<Consumer<String>>() private var hideSilentNotificationsOnLockscreen: Boolean = false Loading @@ -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") } Loading Loading @@ -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 } private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry?): Boolean = when { entry == null -> 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 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 } } packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java +25 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -209,7 +210,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading @@ -220,7 +221,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading @@ -231,7 +232,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading @@ -242,7 +243,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading Loading @@ -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 Loading @@ -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 Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt +44 −51 Original line number Diff line number Diff line Loading @@ -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<Consumer<String>>() private var hideSilentNotificationsOnLockscreen: Boolean = false Loading @@ -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") } Loading Loading @@ -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 } private fun priorityExceedsLockscreenShowingThreshold(entry: ListEntry?): Boolean = when { entry == null -> 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 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 } }
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java +25 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -209,7 +210,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading @@ -220,7 +221,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading @@ -231,7 +232,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading @@ -242,7 +243,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { Consumer<String> 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()); } Loading Loading @@ -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 Loading @@ -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 Loading