From 0a8f3dd2a8f47fee05a7cd499b42117bbae9a656 Mon Sep 17 00:00:00 2001 From: Jeff DeCew Date: Thu, 21 Jul 2022 16:15:11 +0000 Subject: [PATCH] Fix Notification redaction when power cycling a non-dozing device while occluded. This issue was originally raised in the S timeline, but had already been fixed by the refactor to use UnlockedScreenOffAnimationController, which called updateIsKeyguard(/*force*/ true) from onFinishedWakingUp(). This solved the problem of re-triggering the redaction, but it also intriduced a new bug where the keyguard could end up briefly showing on top of the occluding activity when AOD was supported but off. As a result, they limited the call to when the AOD was on (and animations were controlling, etc). This CL uses the opposite check to make sure we recalcualte redaction (and only redaction, not the whole keyguard) when waking up while occluded. We also needed to make sure that we rerun the notification pipeline when updating public information so that any necessary public views are sure to inflate. That rerun has been limited in scope to conditions where the public mode information has detectably changed. Bug: 237349699 Bug: 238990302 Bug: 239828798 Test: CTS Verifier NotificationPrivacyTest on emulator, AOD off, AOD on Change-Id: I95443ee6b77377aceb54b983d34131628027da9b --- ...NotificationLockscreenUserManagerImpl.java | 7 +++- ...tificationStackScrollLayoutController.java | 7 ++++ .../statusbar/phone/CentralSurfacesImpl.java | 12 +++++++ ...NotificationLockscreenUserManagerTest.java | 35 +++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java index 38a208b72edca..f4ca7edb146d3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java @@ -642,6 +642,8 @@ public class NotificationLockscreenUserManagerImpl implements // - device keyguard is shown in secure mode; // - profile is locked with a work challenge. SparseArray currentProfiles = getCurrentProfiles(); + SparseBooleanArray oldPublicModes = mLockscreenPublicMode.clone(); + SparseBooleanArray oldWorkChallenges = mUsersWithSeparateWorkChallenge.clone(); mUsersWithSeparateWorkChallenge.clear(); for (int i = currentProfiles.size() - 1; i >= 0; i--) { final int userId = currentProfiles.valueAt(i).id; @@ -660,7 +662,10 @@ public class NotificationLockscreenUserManagerImpl implements } getEntryManager().updateNotifications("NotificationLockscreenUserManager.updatePublicMode"); // TODO(b/234738798): Migrate KeyguardNotificationVisibilityProvider to use this listener - // notifyNotificationStateChanged(); + if (!mLockscreenPublicMode.equals(oldPublicModes) + || !mUsersWithSeparateWorkChallenge.equals(oldWorkChallenges)) { + notifyNotificationStateChanged(); + } } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 596b767bb4345..85f1689714a37 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -324,6 +324,13 @@ public class NotificationStackScrollLayoutController { } }; + /** + * Recalculate sensitiveness without animation; called when waking up while keyguard occluded. + */ + public void updateSensitivenessForOccludedWakeup() { + mView.updateSensitiveness(false, mLockscreenUserManager.isAnyProfilePublicMode()); + } + /** * Set the overexpansion of the panel to be applied to the view. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index fff7b6a9e4f0d..816f7a3cb7a90 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -3649,6 +3649,18 @@ public class CentralSurfacesImpl extends CoreStartable implements public void onFinishedWakingUp() { mWakeUpCoordinator.setFullyAwake(true); mWakeUpCoordinator.setWakingUp(false); + if (mKeyguardStateController.isOccluded() + && !mDozeParameters.canControlUnlockedScreenOff()) { + // When the keyguard is occluded we don't use the KEYGUARD state which would + // normally cause these redaction updates. If AOD is on, the KEYGUARD state is used + // to show the doze, AND UnlockedScreenOffAnimationController.onFinishedWakingUp() + // would force a KEYGUARD state that would take care of recalculating redaction. + // So if AOD is off or unsupported we need to trigger these updates at screen on + // when the keyguard is occluded. + mLockscreenUserManager.updatePublicMode(); + mNotificationPanelViewController.getNotificationStackScrollLayoutController() + .updateSensitivenessForOccludedWakeup(); + } if (mLaunchCameraWhenFinishedWaking) { mNotificationPanelViewController.launchCamera(mLastCameraLaunchSource); mLaunchCameraWhenFinishedWaking = false; 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 7687d12045414..dd2b66765fae6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java @@ -29,7 +29,9 @@ import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -59,6 +61,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationLockscreenUserManager.KeyguardNotificationSuppressor; +import com.android.systemui.statusbar.NotificationLockscreenUserManager.NotificationStateChangedListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; @@ -324,6 +327,38 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase { assertTrue(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUser.id)); } + @Test + public void testUpdateIsPublicMode() { + when(mKeyguardStateController.isMethodSecure()).thenReturn(true); + + NotificationStateChangedListener listener = mock(NotificationStateChangedListener.class); + mLockscreenUserManager.addNotificationStateChangedListener(listener); + mLockscreenUserManager.mCurrentProfiles.append(0, mock(UserInfo.class)); + + // first call explicitly sets user 0 to not public; notifies + mLockscreenUserManager.updatePublicMode(); + assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0)); + verify(listener).onNotificationStateChanged(); + clearInvocations(listener); + + // calling again has no changes; does not notify + mLockscreenUserManager.updatePublicMode(); + assertFalse(mLockscreenUserManager.isLockscreenPublicMode(0)); + verify(listener, never()).onNotificationStateChanged(); + + // Calling again with keyguard now showing makes user 0 public; notifies + when(mKeyguardStateController.isShowing()).thenReturn(true); + mLockscreenUserManager.updatePublicMode(); + assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0)); + verify(listener).onNotificationStateChanged(); + clearInvocations(listener); + + // calling again has no changes; does not notify + mLockscreenUserManager.updatePublicMode(); + assertTrue(mLockscreenUserManager.isLockscreenPublicMode(0)); + verify(listener, never()).onNotificationStateChanged(); + } + @Test public void testShowSilentNotifications_settingSaysShow() { mSettings.putInt(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1);