diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index b81cb2be1c4d6..64fcfd8674299 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -4079,6 +4079,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (!mIsExpansionChanging) { cancelActiveSwipe(); } + finalizeClearAllAnimation(); } updateNotificationAnimationStates(); updateChronometers(); @@ -4174,20 +4175,30 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable runAnimationFinishedRunnables(); clearTransient(); clearHeadsUpDisappearRunning(); + finalizeClearAllAnimation(); + } + private void finalizeClearAllAnimation() { if (mAmbientState.isClearAllInProgress()) { setClearAllInProgress(false); if (mShadeNeedsToClose) { mShadeNeedsToClose = false; - postDelayed( - () -> { - mShadeController.animateCollapseShade(CommandQueue.FLAG_EXCLUDE_NONE); - }, - DELAY_BEFORE_SHADE_CLOSE /* delayMillis */); + if (mIsExpanded) { + collapseShadeDelayed(); + } } } } + private void collapseShadeDelayed() { + postDelayed( + () -> { + mShadeController.animateCollapseShade( + CommandQueue.FLAG_EXCLUDE_NONE); + }, + DELAY_BEFORE_SHADE_CLOSE /* delayMillis */); + } + private void clearHeadsUpDisappearRunning() { for (int i = 0; i < getChildCount(); i++) { View view = getChildAt(i); @@ -4535,6 +4546,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mFooterView.setFooterLabelVisible(mHasFilteredOutSeenNotifications); } + @VisibleForTesting public void setClearAllInProgress(boolean clearAllInProgress) { mClearAllInProgress = clearAllInProgress; mAmbientState.setClearAllInProgress(clearAllInProgress); @@ -5151,7 +5163,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mHeadsUpAppearanceController = headsUpAppearanceController; } - private boolean isVisible(View child) { + @VisibleForTesting + public boolean isVisible(View child) { boolean hasClipBounds = child.getClipBounds(mTmpRect); return child.getVisibility() == View.VISIBLE && (!hasClipBounds || mTmpRect.height() > 0); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java index a4ee349f5b710..a9cfe7f272028 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java @@ -41,6 +41,7 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -575,10 +576,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mStackScroller.inflateFooterView(); // add notification - ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); - NotificationEntry entry = mock(NotificationEntry.class); - when(row.getEntry()).thenReturn(entry); - when(entry.isClearable()).thenReturn(true); + ExpandableNotificationRow row = createClearableRow(); mStackScroller.addContainerView(row); mStackScroller.onUpdateRowStates(); @@ -647,6 +645,50 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { assertEquals(ROWS_GENTLE, selected[0]); } + @Test + public void testClearNotifications_clearAllInProgress() { + ExpandableNotificationRow row = createClearableRow(); + when(row.getEntry().hasFinishedInitialization()).thenReturn(true); + doReturn(true).when(mStackScroller).isVisible(row); + mStackScroller.addContainerView(row); + + mStackScroller.clearNotifications(ROWS_ALL, false); + + assertClearAllInProgress(true); + verify(mNotificationRoundnessManager).setClearAllInProgress(true); + } + + @Test + public void testOnChildAnimationFinished_resetsClearAllInProgress() { + mStackScroller.setClearAllInProgress(true); + + mStackScroller.onChildAnimationFinished(); + + assertClearAllInProgress(false); + verify(mNotificationRoundnessManager).setClearAllInProgress(false); + } + + @Test + public void testShadeCollapsed_resetsClearAllInProgress() { + mStackScroller.setClearAllInProgress(true); + + mStackScroller.setIsExpanded(false); + + assertClearAllInProgress(false); + verify(mNotificationRoundnessManager).setClearAllInProgress(false); + } + + @Test + public void testShadeExpanded_doesntChangeClearAllInProgress() { + mStackScroller.setClearAllInProgress(true); + clearInvocations(mNotificationRoundnessManager); + + mStackScroller.setIsExpanded(true); + + assertClearAllInProgress(true); + verify(mNotificationRoundnessManager, never()).setClearAllInProgress(anyBoolean()); + } + @Test public void testAddNotificationUpdatesSpeedBumpIndex() { // initial state calculated == 0 @@ -896,6 +938,21 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { mStackScroller.setStatusBarState(state); } + private ExpandableNotificationRow createClearableRow() { + ExpandableNotificationRow row = mock(ExpandableNotificationRow.class); + NotificationEntry entry = mock(NotificationEntry.class); + when(row.canViewBeCleared()).thenReturn(true); + when(row.getEntry()).thenReturn(entry); + when(entry.isClearable()).thenReturn(true); + + return row; + } + + private void assertClearAllInProgress(boolean expected) { + assertEquals(expected, mStackScroller.getClearAllInProgress()); + assertEquals(expected, mAmbientState.isClearAllInProgress()); + } + private static void mockBoundsOnScreen(View view, Rect bounds) { doAnswer(invocation -> { Rect out = invocation.getArgument(0);