Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1d68bec authored by Steve Elliott's avatar Steve Elliott
Browse files

Requery silent notifs lockscreen setting on change

Fixes: 226586443
Test: manual
  1. Settings > Notifications > Notification on lock screen > Show all
  2. Receive a silent notification
  3. Lock device
  4. Verify silent notification visible on lockscreen
Test: atest KeyguardNotificationVisibilityProviderTest

Change-Id: I4a0b8b2985cb3a1c7b3d5c8e5176122aa8627440
parent 4f027ec4
Loading
Loading
Loading
Loading
+44 −51
Original line number Diff line number Diff line
@@ -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

@@ -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
    }

    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
    }
}
+25 −4
Original line number Diff line number Diff line
@@ -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<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());
    }
@@ -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());
    }
@@ -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());
    }
@@ -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());
    }
@@ -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