From e1fa8bdcd2c213d5862e61ed0c2769c37f7cf946 Mon Sep 17 00:00:00 2001 From: Steve Elliott Date: Thu, 2 Jun 2022 16:25:26 -0400 Subject: [PATCH] Ensure notifs are filtered when device is locked ...even when the device is not presently on the lock screen (ex: occluded by Camera) Fixes: 234327150 Test: manual 1. Post a notification w/ Notify.apk 2. Enable setting to hide notifications on the lock screen. 3. Lock the device 4. Launch camera from the lockscreen 5. Open the notification shade. Observe: No notifications are present in the shade. Change-Id: I33a40e6e9cec3caf8e485ea942d70458c9af887c --- .../KeyguardNotificationVisibilityProvider.kt | 15 +++-- ...ardNotificationVisibilityProviderTest.java | 56 ++++++++++++++++++- 2 files changed, 64 insertions(+), 7 deletions(-) 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 cff42f29a6268..6cd3a6a728654 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 @@ -107,8 +107,7 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( if (uri == showSilentNotifsUri) { readShowSilentNotificationSetting() } - if (statusBarStateController.getCurrentOrUpcomingState() - == StatusBarState.KEYGUARD) { + if (isLockedOrLocking) { notifyStateChanged("Settings $uri changed") } } @@ -134,14 +133,16 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( // register (maybe) public mode changed callbacks: statusBarStateController.addCallback(object : StatusBarStateController.StateListener { + override fun onStateChanged(newState: Int) { + notifyStateChanged("onStatusBarStateChanged") + } override fun onUpcomingStateChanged(state: Int) { notifyStateChanged("onStatusBarUpcomingStateChanged") } }) broadcastDispatcher.registerReceiver(object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { - if (statusBarStateController.getCurrentOrUpcomingState() - == StatusBarState.KEYGUARD) { + if (isLockedOrLocking) { // maybe public mode changed notifyStateChanged(intent.action!!) } @@ -163,7 +164,7 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( override fun shouldHideNotification(entry: NotificationEntry): Boolean = when { // Keyguard state doesn't matter if the keyguard is not showing. - statusBarStateController.getCurrentOrUpcomingState() != StatusBarState.KEYGUARD -> false + !isLockedOrLocking -> 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. @@ -208,6 +209,10 @@ private class KeyguardNotificationVisibilityProviderImpl @Inject constructor( } } + private val isLockedOrLocking get() = + keyguardStateController.isShowing || + statusBarStateController.currentOrUpcomingState == StatusBarState.KEYGUARD + private fun readShowSilentNotificationSetting() { val showSilentNotifs = secureSettings.getBoolForUser(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 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 3a85972aa470a..541749b49474a 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 @@ -173,7 +173,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { } @Test - public void notifyListeners_onStatusBarStateChanged() { + public void notifyListeners_onStatusBarUpcomingStateChanged() { ArgumentCaptor callbackCaptor = ArgumentCaptor.forClass(StatusBarStateController.StateListener.class); verify(mStatusBarStateController).addCallback(callbackCaptor.capture()); @@ -187,6 +187,21 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { verify(listener).accept(anyString()); } + @Test + public void notifyListeners_onStatusBarStateChanged() { + ArgumentCaptor callbackCaptor = + ArgumentCaptor.forClass(StatusBarStateController.StateListener.class); + verify(mStatusBarStateController).addCallback(callbackCaptor.capture()); + StatusBarStateController.StateListener callback = callbackCaptor.getValue(); + + Consumer listener = mock(Consumer.class); + mKeyguardNotificationVisibilityProvider.addOnStateChangedListener(listener); + + callback.onStateChanged(0); + + verify(listener).accept(anyString()); + } + @Test public void notifyListeners_onReceiveUserSwitchBroadcast() { ArgumentCaptor callbackCaptor = @@ -254,7 +269,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { } @Test - public void hideSilentNotificationsPerUserSetting() { + public void keyguardShowing_hideSilentNotifications_perUserSetting() { when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD); mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, true); mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false); @@ -266,6 +281,41 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { assertTrue(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry)); } + @Test + public void keyguardShowing_hideSilentNotifications_perUserSetting_withHighPriorityParent() { + when(mKeyguardStateController.isShowing()).thenReturn(true); + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, true); + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false); + GroupEntry parent = new GroupEntryBuilder() + .setKey("parent") + .addChild(mEntry) + .setSummary(new NotificationEntryBuilder() + .setUser(new UserHandle(NOTIF_USER_ID)) + .setImportance(IMPORTANCE_LOW) + .build()) + .build(); + mEntry = new NotificationEntryBuilder() + .setUser(new UserHandle(NOTIF_USER_ID)) + .setImportance(IMPORTANCE_LOW) + .setParent(parent) + .build(); + when(mHighPriorityProvider.isHighPriority(any())).thenReturn(false); + assertTrue(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry)); + } + + @Test + public void hideSilentNotificationsPerUserSetting() { + when(mKeyguardStateController.isShowing()).thenReturn(true); + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, true); + mFakeSettings.putBool(Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, false); + mEntry = new NotificationEntryBuilder() + .setUser(new UserHandle(NOTIF_USER_ID)) + .setImportance(IMPORTANCE_LOW) + .build(); + when(mHighPriorityProvider.isHighPriority(any())).thenReturn(false); + assertTrue(mKeyguardNotificationVisibilityProvider.shouldHideNotification(mEntry)); + } + @Test public void notifyListeners_onSettingChange_zenMode() { when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD); @@ -301,6 +351,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { public void keyguardNotShowing() { // GIVEN the lockscreen isn't showing setupUnfilteredState(mEntry); + when(mKeyguardStateController.isShowing()).thenReturn(false); when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(SHADE); // THEN don't filter out the entry @@ -443,6 +494,7 @@ public class KeyguardNotificationVisibilityProviderTest extends SysuiTestCase { */ private void setupUnfilteredState(NotificationEntry entry) { // keyguard is showing + when(mKeyguardStateController.isShowing()).thenReturn(true); when(mStatusBarStateController.getCurrentOrUpcomingState()).thenReturn(KEYGUARD); // show notifications on the lockscreen