diff options
| author | 2020-04-21 16:26:47 -0400 | |
|---|---|---|
| committer | 2020-04-27 09:30:40 -0400 | |
| commit | 11976b6401d935cce2ac9e1652fcf4f95682b904 (patch) | |
| tree | 78bd00629fe3d5e1ed5ed5d1988c1bb2282ee08a | |
| parent | 3b145e0b19f82ecf3f31b7702f8915308002bafe (diff) | |
Separate managed/primary profile sensitive notifs
Previously if the current (primary) user didn't allow sensitive
notifications to show all their info on the lockscreen, then
notifications for managed profiles also wouldn't show their sensitive
info despite the user intentionally allowing work profile notifications
to be shown on the lock screen.
Now, if a notification is sent to a managed/work profile, then we only
use the work profile setting to redact the sensitive notification
information on the lockscreen. For all other notifications, we
additionally check the current user's redactivility setting.
Test: atest NotificationLockscreenUserManagerTest
Fixes: 143536631
Change-Id: I468ca0b68188a594ebf0b78ebcc3bc0bb93687ac
2 files changed, 141 insertions, 14 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 12298817d5a6..0ddd2a624bf7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -182,7 +182,7 @@ public class NotificationLockscreenUserManagerImpl implements protected final Context mContext; private final Handler mMainHandler; protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>(); - protected final ArrayList<UserInfo> mCurrentManagedProfiles = new ArrayList<>(); + protected final SparseArray<UserInfo> mCurrentManagedProfiles = new SparseArray<>(); protected int mCurrentUserId = 0; protected NotificationPresenter mPresenter; @@ -425,8 +425,9 @@ public class NotificationLockscreenUserManagerImpl implements */ public boolean allowsManagedPrivateNotificationsInPublic() { synchronized (mLock) { - for (UserInfo profile : mCurrentManagedProfiles) { - if (!userAllowsPrivateNotificationsInPublic(profile.id)) { + for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) { + if (!userAllowsPrivateNotificationsInPublic( + mCurrentManagedProfiles.valueAt(i).id)) { return false; } } @@ -490,15 +491,22 @@ public class NotificationLockscreenUserManagerImpl implements public boolean needsRedaction(NotificationEntry ent) { int userId = ent.getSbn().getUserId(); - boolean currentUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(mCurrentUserId); - boolean notiUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(userId); - boolean redactedLockscreen = currentUserWantsRedaction || notiUserWantsRedaction; + boolean isCurrentUserRedactingNotifs = + !userAllowsPrivateNotificationsInPublic(mCurrentUserId); + boolean isNotifForManagedProfile = mCurrentManagedProfiles.contains(userId); + boolean isNotifUserRedacted = !userAllowsPrivateNotificationsInPublic(userId); + + // 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 + boolean isNotifRedacted = (!isNotifForManagedProfile && isCurrentUserRedactingNotifs) + || isNotifUserRedacted; boolean notificationRequestsRedaction = ent.getSbn().getNotification().visibility == Notification.VISIBILITY_PRIVATE; boolean userForcesRedaction = packageHasVisibilityOverride(ent.getSbn().getKey()); - return userForcesRedaction || notificationRequestsRedaction && redactedLockscreen; + return userForcesRedaction || notificationRequestsRedaction && isNotifRedacted; } private boolean packageHasVisibilityOverride(String key) { @@ -519,7 +527,7 @@ public class NotificationLockscreenUserManagerImpl implements for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) { mCurrentProfiles.put(user.id, user); if (UserManager.USER_TYPE_PROFILE_MANAGED.equals(user.userType)) { - mCurrentManagedProfiles.add(user); + mCurrentManagedProfiles.put(user.id, user); } } } @@ -551,7 +559,7 @@ public class NotificationLockscreenUserManagerImpl implements public boolean isAnyManagedProfilePublicMode() { synchronized (mLock) { for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) { - if (isLockscreenPublicMode(mCurrentManagedProfiles.get(i).id)) { + if (isLockscreenPublicMode(mCurrentManagedProfiles.valueAt(i).id)) { return true; } } @@ -668,8 +676,8 @@ public class NotificationLockscreenUserManagerImpl implements } pw.print(" mCurrentManagedProfiles="); synchronized (mLock) { - for (UserInfo userInfo : mCurrentManagedProfiles) { - pw.print("" + userInfo.id + " "); + for (int i = mCurrentManagedProfiles.size() - 1; i >= 0; i--) { + pw.print("" + mCurrentManagedProfiles.valueAt(i).id + " "); } } pw.println(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java index c6d57e6df028..e984d207be44 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java @@ -42,6 +42,7 @@ import android.content.pm.UserInfo; import android.database.ContentObserver; import android.os.Handler; import android.os.Looper; +import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.testing.AndroidTestingRunner; @@ -99,6 +100,9 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { private UserInfo mSecondaryUser; private UserInfo mWorkUser; private TestNotificationLockscreenUserManager mLockscreenUserManager; + private NotificationEntry mCurrentUserNotif; + private NotificationEntry mSecondaryUserNotif; + private NotificationEntry mWorkProfileNotif; @Before public void setUp() { @@ -116,6 +120,21 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { mDependency.injectTestDependency(Dependency.MAIN_HANDLER, Handler.createAsync(Looper.myLooper())); + Notification notifWithPrivateVisibility = new Notification(); + notifWithPrivateVisibility.visibility = Notification.VISIBILITY_PRIVATE; + mCurrentUserNotif = new NotificationEntryBuilder() + .setNotification(notifWithPrivateVisibility) + .setUser(new UserHandle(mCurrentUser.id)) + .build(); + mSecondaryUserNotif = new NotificationEntryBuilder() + .setNotification(notifWithPrivateVisibility) + .setUser(new UserHandle(mSecondaryUser.id)) + .build(); + mWorkProfileNotif = new NotificationEntryBuilder() + .setNotification(notifWithPrivateVisibility) + .setUser(new UserHandle(mWorkUser.id)) + .build(); + mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext); mLockscreenUserManager.setUpWithPresenter(mPresenter); } @@ -155,7 +174,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); - assertFalse(mLockscreenUserManager.userAllowsNotificationsInPublic(mCurrentUser.id)); + assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mCurrentUser.id)); } @Test @@ -163,7 +182,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); - assertFalse(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic()); + assertFalse(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); } @Test @@ -171,7 +190,107 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { Settings.Secure.putIntForUser(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); - assertTrue(mLockscreenUserManager.allowsManagedPrivateNotificationsInPublic()); + assertTrue(mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(mWorkUser.id)); + } + + @Test + public void testCurrentUserPrivateNotificationsNotRedacted() { + // GIVEN current user doesn't allow private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN current user's notification is redacted + assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + } + + @Test + public void testCurrentUserPrivateNotificationsRedacted() { + // GIVEN current user allows private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN current user's notification isn't redacted + assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + } + + @Test + public void testWorkPrivateNotificationsRedacted() { + // GIVEN work profile doesn't private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN work profile notification is redacted + assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + } + + @Test + public void testWorkPrivateNotificationsNotRedacted() { + // GIVEN work profile allows private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN work profile notification isn't redacted + assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + } + + @Test + public void testWorkPrivateNotificationsNotRedacted_otherUsersRedacted() { + // GIVEN work profile allows private notifications to show but the other users don't + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mWorkUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, + mSecondaryUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN the work profile notification doesn't need to be redacted + assertFalse(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + + // THEN the current user and secondary user notifications do need to be redacted + assertTrue(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); + } + + @Test + public void testWorkProfileRedacted_otherUsersNotRedacted() { + // GIVEN work profile doesn't allow private notifications to show but the other users do + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mWorkUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mCurrentUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mSecondaryUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN the work profile notification needs to be redacted + assertTrue(mLockscreenUserManager.needsRedaction(mWorkProfileNotif)); + + // THEN the current user and secondary user notifications don't need to be redacted + assertFalse(mLockscreenUserManager.needsRedaction(mCurrentUserNotif)); + assertFalse(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); + } + + @Test + public void testSecondaryUserNotRedacted_currentUserRedacted() { + // GIVEN secondary profile allows private notifications to show but the current user + // doesn't allow private notifications to show + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, mCurrentUser.id); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, + mSecondaryUser.id); + mLockscreenUserManager.getLockscreenSettingsObserverForTest().onChange(false); + + // THEN the secondary profile notification still needs to be redacted because the current + // user's setting takes precedence + assertTrue(mLockscreenUserManager.needsRedaction(mSecondaryUserNotif)); } @Test |