From ea404e2fb3f42bacf470facb10cc15be5da474ec Mon Sep 17 00:00:00 2001 From: Nate Myren <ntmyren@google.com> Date: Wed, 15 May 2024 13:59:03 -0700 Subject: [PATCH] Hide notifications with sensitive content on the lock screen Bug: 343631648 Test: atest NotificationLockscreenUserManagerTest Flag: android.app.redact_sensitive_content_notifications_on_lockscreen DISABLED Change-Id: Ibc613b0859531e16651645288bedbdcbef7e9824 --- core/java/android/app/notification.aconfig | 7 +++++ ...NotificationLockscreenUserManagerTest.java | 26 ++++++++++++++++--- ...NotificationLockscreenUserManagerImpl.java | 16 +++++++----- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig index 6edae0b60fd9..2d783177e0d7 100644 --- a/core/java/android/app/notification.aconfig +++ b/core/java/android/app/notification.aconfig @@ -192,3 +192,10 @@ flag { description: "Removes all custom views" bug: "342602960" } + +flag { + name: "redact_sensitive_content_notifications_on_lockscreen" + namespace: "systemui" + description: "redacts notifications on the lockscreen if they have the 'sensitiveContent' flag" + bug: "343631648" +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java index 02993b8922b0..523a89ad5740 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java @@ -99,14 +99,14 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import platform.test.runner.parameterized.ParameterizedAndroidJunit4; -import platform.test.runner.parameterized.Parameters; - import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Executor; +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + @SmallTest @RunWith(ParameterizedAndroidJunit4.class) public class NotificationLockscreenUserManagerTest extends SysuiTestCase { @@ -162,6 +162,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { private NotificationEntry mCurrentUserNotif; private NotificationEntry mSecondaryUserNotif; private NotificationEntry mWorkProfileNotif; + private NotificationEntry mSensitiveContentNotif; private final FakeFeatureFlagsClassic mFakeFeatureFlags = new FakeFeatureFlagsClassic(); private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeExecutor mBackgroundExecutor = new FakeExecutor(mFakeSystemClock); @@ -224,6 +225,14 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mWorkProfileNotif.setRanking(new RankingBuilder(mWorkProfileNotif.getRanking()) .setChannel(channel) .setVisibilityOverride(VISIBILITY_NO_OVERRIDE).build()); + mSensitiveContentNotif = new NotificationEntryBuilder() + .setNotification(notifWithPrivateVisibility) + .setUser(new UserHandle(mCurrentUser.id)) + .build(); + mSensitiveContentNotif.setRanking(new RankingBuilder(mCurrentUserNotif.getRanking()) + .setChannel(channel) + .setSensitiveContent(true) + .setVisibilityOverride(VISIBILITY_NO_OVERRIDE).build()); when(mNotifCollection.getEntry(mWorkProfileNotif.getKey())).thenReturn(mWorkProfileNotif); mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext); @@ -458,6 +467,17 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); } + @Test + public void testHasSensitiveContent_redacted() { + // Allow private notifications for this user + mSettings.putIntForUser(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mCurrentUser.id); + changeSetting(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS); + + // Sensitive Content notifications are always redacted + assertTrue(mLockscreenUserManager.needsRedaction(mSensitiveContentNotif)); + } + @Test public void testUserSwitchedCallsOnUserSwitching() { mLockscreenUserManager.getUserTrackerCallbackForTest().onUserChanging(mSecondaryUser.id, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 854ef928847a..bb26f92e510d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar; import static android.app.Flags.keyguardPrivateNotifications; +import static android.app.Flags.redactSensitiveContentNotificationsOnLockscreen; import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED; import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; @@ -654,10 +655,12 @@ public class NotificationLockscreenUserManagerImpl implements !userAllowsPrivateNotificationsInPublic(mCurrentUserId); boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId); boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId); + boolean isNotifSensitive = redactSensitiveContentNotificationsOnLockscreen() + && ent.getRanking() != null && ent.getRanking().hasSensitiveContent(); - // redact notifications if the current user is redacting notifications; however if the - // notification is associated with a managed profile, we rely on the managed profile - // setting to determine whether to redact it + // redact notifications if the current user is redacting notifications or the notification + // contains sensitive content. However if the notification is associated with a managed + // profile, we rely on the managed profile setting to determine whether to redact it. boolean isNotifRedacted = (!isNotifForManagedProfile && isCurrentUserRedactingNotifs) || isNotifUserRedacted; @@ -666,10 +669,11 @@ public class NotificationLockscreenUserManagerImpl implements boolean userForcesRedaction = packageHasVisibilityOverride(ent.getSbn().getKey()); if (keyguardPrivateNotifications()) { - return !mKeyguardAllowingNotifications - || userForcesRedaction || notificationRequestsRedaction && isNotifRedacted; + return !mKeyguardAllowingNotifications || isNotifSensitive + || userForcesRedaction || (notificationRequestsRedaction && isNotifRedacted); } else { - return userForcesRedaction || notificationRequestsRedaction && isNotifRedacted; + return userForcesRedaction || isNotifSensitive + || (notificationRequestsRedaction && isNotifRedacted); } } -- GitLab