Loading packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +9 −4 Original line number Diff line number Diff line Loading @@ -2093,7 +2093,8 @@ public final class NotificationPanelViewController { animator.start(); } private void onFlingEnd(boolean cancelled) { @VisibleForTesting void onFlingEnd(boolean cancelled) { mIsFlinging = false; // No overshoot when the animation ends setOverExpansionInternal(0, false /* isFromGesture */); Loading Loading @@ -3834,12 +3835,14 @@ public final class NotificationPanelViewController { } } private void setIsClosing(boolean isClosing) { @VisibleForTesting void setIsClosing(boolean isClosing) { boolean wasClosing = isClosing(); mClosing = isClosing; if (wasClosing != isClosing) { mPanelEventsEmitter.notifyPanelCollapsingChanged(isClosing); } mAmbientState.setIsClosing(isClosing); } private void updateDozingVisibilities(boolean animate) { Loading Loading @@ -4630,14 +4633,16 @@ public final class NotificationPanelViewController { Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args)); } private void notifyExpandingStarted() { @VisibleForTesting void notifyExpandingStarted() { if (!mExpanding) { mExpanding = true; onExpandingStarted(); } } private void notifyExpandingFinished() { @VisibleForTesting void notifyExpandingFinished() { endClosing(); if (mExpanding) { mExpanding = false; Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +20 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,11 @@ public class AmbientState implements Dumpable { */ private boolean mIsFlingRequiredAfterLockScreenSwipeUp = false; /** * Whether the shade is currently closing. */ private boolean mIsClosing; @VisibleForTesting public boolean isFlingRequiredAfterLockScreenSwipeUp() { return mIsFlingRequiredAfterLockScreenSwipeUp; Loading Loading @@ -717,6 +722,20 @@ public class AmbientState implements Dumpable { && mStatusBarKeyguardViewManager.isBouncerInTransit(); } /** * @param isClosing Whether the shade is currently closing. */ public void setIsClosing(boolean isClosing) { mIsClosing = isClosing; } /** * @return Whether the shade is currently closing. */ public boolean isClosing() { return mIsClosing; } @Override public void dump(PrintWriter pw, String[] args) { pw.println("mTopPadding=" + mTopPadding); Loading Loading @@ -761,5 +780,6 @@ public class AmbientState implements Dumpable { + mIsFlingRequiredAfterLockScreenSwipeUp); pw.println("mZDistanceBetweenElements=" + mZDistanceBetweenElements); pw.println("mBaseZHeight=" + mBaseZHeight); pw.println("mIsClosing=" + mIsClosing); } } packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +11 −3 Original line number Diff line number Diff line Loading @@ -255,7 +255,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mClearAllInProgress; private FooterClearAllListener mFooterClearAllListener; private boolean mFlingAfterUpEvent; /** * Was the scroller scrolled to the top when the down motion was observed? */ Loading Loading @@ -4020,8 +4019,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable setOwnScrollY(0); } @VisibleForTesting @ShadeViewRefactor(RefactorComponent.COORDINATOR) private void setIsExpanded(boolean isExpanded) { void setIsExpanded(boolean isExpanded) { boolean changed = isExpanded != mIsExpanded; mIsExpanded = isExpanded; mStackScrollAlgorithm.setIsExpanded(isExpanded); Loading Loading @@ -4842,13 +4842,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } @VisibleForTesting @ShadeViewRefactor(RefactorComponent.COORDINATOR) private void setOwnScrollY(int ownScrollY) { void setOwnScrollY(int ownScrollY) { setOwnScrollY(ownScrollY, false /* animateScrollChangeListener */); } @ShadeViewRefactor(RefactorComponent.COORDINATOR) private void setOwnScrollY(int ownScrollY, boolean animateStackYChangeListener) { // Avoid Flicking during clear all // when the shade finishes closing, onExpansionStopped will call // resetScrollPosition to setOwnScrollY to 0 if (mAmbientState.isClosing()) { return; } if (ownScrollY != mOwnScrollY) { // We still want to call the normal scrolled changed for accessibility reasons onScrollChanged(mScrollX, ownScrollY, mScrollX, mOwnScrollY); Loading packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading Loading @@ -173,6 +174,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; Loading Loading @@ -1540,6 +1542,33 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { ); } /** * When shade is flinging to close and this fling is not intercepted, * {@link AmbientState#setIsClosing(boolean)} should be called before * {@link NotificationStackScrollLayoutController#onExpansionStopped()} * to ensure scrollY can be correctly set to be 0 */ @Test public void onShadeFlingClosingEnd_mAmbientStateSetClose_thenOnExpansionStopped() { // Given: Shade is expanded mNotificationPanelViewController.notifyExpandingFinished(); mNotificationPanelViewController.setIsClosing(false); // When: Shade flings to close not canceled mNotificationPanelViewController.notifyExpandingStarted(); mNotificationPanelViewController.setIsClosing(true); mNotificationPanelViewController.onFlingEnd(false); // Then: AmbientState's mIsClosing should be set to false // before mNotificationStackScrollLayoutController.onExpansionStopped() is called // to ensure NotificationStackScrollLayout.resetScrollPosition() -> resetScrollPosition // -> setOwnScrollY(0) can set scrollY to 0 when shade is closed InOrder inOrder = inOrder(mAmbientState, mNotificationStackScrollLayoutController); inOrder.verify(mAmbientState).setIsClosing(false); inOrder.verify(mNotificationStackScrollLayoutController).onExpansionStopped(); } private static MotionEvent createMotionEvent(int x, int y, int action) { return MotionEvent.obtain( /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0); Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt +16 −0 Original line number Diff line number Diff line Loading @@ -361,6 +361,22 @@ class AmbientStateTest : SysuiTestCase() { assertThat(sut.isOnKeyguard).isFalse() } // endregion // region mIsClosing @Test fun isClosing_whenShadeClosing_shouldReturnTrue() { sut.setIsClosing(true) assertThat(sut.isClosing).isTrue() } @Test fun isClosing_whenShadeFinishClosing_shouldReturnFalse() { sut.setIsClosing(false) assertThat(sut.isClosing).isFalse() } // endregion } // region Arrange helper methods. Loading Loading
packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +9 −4 Original line number Diff line number Diff line Loading @@ -2093,7 +2093,8 @@ public final class NotificationPanelViewController { animator.start(); } private void onFlingEnd(boolean cancelled) { @VisibleForTesting void onFlingEnd(boolean cancelled) { mIsFlinging = false; // No overshoot when the animation ends setOverExpansionInternal(0, false /* isFromGesture */); Loading Loading @@ -3834,12 +3835,14 @@ public final class NotificationPanelViewController { } } private void setIsClosing(boolean isClosing) { @VisibleForTesting void setIsClosing(boolean isClosing) { boolean wasClosing = isClosing(); mClosing = isClosing; if (wasClosing != isClosing) { mPanelEventsEmitter.notifyPanelCollapsingChanged(isClosing); } mAmbientState.setIsClosing(isClosing); } private void updateDozingVisibilities(boolean animate) { Loading Loading @@ -4630,14 +4633,16 @@ public final class NotificationPanelViewController { Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args)); } private void notifyExpandingStarted() { @VisibleForTesting void notifyExpandingStarted() { if (!mExpanding) { mExpanding = true; onExpandingStarted(); } } private void notifyExpandingFinished() { @VisibleForTesting void notifyExpandingFinished() { endClosing(); if (mExpanding) { mExpanding = false; Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +20 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,11 @@ public class AmbientState implements Dumpable { */ private boolean mIsFlingRequiredAfterLockScreenSwipeUp = false; /** * Whether the shade is currently closing. */ private boolean mIsClosing; @VisibleForTesting public boolean isFlingRequiredAfterLockScreenSwipeUp() { return mIsFlingRequiredAfterLockScreenSwipeUp; Loading Loading @@ -717,6 +722,20 @@ public class AmbientState implements Dumpable { && mStatusBarKeyguardViewManager.isBouncerInTransit(); } /** * @param isClosing Whether the shade is currently closing. */ public void setIsClosing(boolean isClosing) { mIsClosing = isClosing; } /** * @return Whether the shade is currently closing. */ public boolean isClosing() { return mIsClosing; } @Override public void dump(PrintWriter pw, String[] args) { pw.println("mTopPadding=" + mTopPadding); Loading Loading @@ -761,5 +780,6 @@ public class AmbientState implements Dumpable { + mIsFlingRequiredAfterLockScreenSwipeUp); pw.println("mZDistanceBetweenElements=" + mZDistanceBetweenElements); pw.println("mBaseZHeight=" + mBaseZHeight); pw.println("mIsClosing=" + mIsClosing); } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +11 −3 Original line number Diff line number Diff line Loading @@ -255,7 +255,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private boolean mClearAllInProgress; private FooterClearAllListener mFooterClearAllListener; private boolean mFlingAfterUpEvent; /** * Was the scroller scrolled to the top when the down motion was observed? */ Loading Loading @@ -4020,8 +4019,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable setOwnScrollY(0); } @VisibleForTesting @ShadeViewRefactor(RefactorComponent.COORDINATOR) private void setIsExpanded(boolean isExpanded) { void setIsExpanded(boolean isExpanded) { boolean changed = isExpanded != mIsExpanded; mIsExpanded = isExpanded; mStackScrollAlgorithm.setIsExpanded(isExpanded); Loading Loading @@ -4842,13 +4842,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } @VisibleForTesting @ShadeViewRefactor(RefactorComponent.COORDINATOR) private void setOwnScrollY(int ownScrollY) { void setOwnScrollY(int ownScrollY) { setOwnScrollY(ownScrollY, false /* animateScrollChangeListener */); } @ShadeViewRefactor(RefactorComponent.COORDINATOR) private void setOwnScrollY(int ownScrollY, boolean animateStackYChangeListener) { // Avoid Flicking during clear all // when the shade finishes closing, onExpansionStopped will call // resetScrollPosition to setOwnScrollY to 0 if (mAmbientState.isClosing()) { return; } if (ownScrollY != mOwnScrollY) { // We still want to call the normal scrolled changed for accessibility reasons onScrollChanged(mScrollX, ownScrollY, mScrollX, mOwnScrollY); Loading
packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; Loading Loading @@ -173,6 +174,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; Loading Loading @@ -1540,6 +1542,33 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { ); } /** * When shade is flinging to close and this fling is not intercepted, * {@link AmbientState#setIsClosing(boolean)} should be called before * {@link NotificationStackScrollLayoutController#onExpansionStopped()} * to ensure scrollY can be correctly set to be 0 */ @Test public void onShadeFlingClosingEnd_mAmbientStateSetClose_thenOnExpansionStopped() { // Given: Shade is expanded mNotificationPanelViewController.notifyExpandingFinished(); mNotificationPanelViewController.setIsClosing(false); // When: Shade flings to close not canceled mNotificationPanelViewController.notifyExpandingStarted(); mNotificationPanelViewController.setIsClosing(true); mNotificationPanelViewController.onFlingEnd(false); // Then: AmbientState's mIsClosing should be set to false // before mNotificationStackScrollLayoutController.onExpansionStopped() is called // to ensure NotificationStackScrollLayout.resetScrollPosition() -> resetScrollPosition // -> setOwnScrollY(0) can set scrollY to 0 when shade is closed InOrder inOrder = inOrder(mAmbientState, mNotificationStackScrollLayoutController); inOrder.verify(mAmbientState).setIsClosing(false); inOrder.verify(mNotificationStackScrollLayoutController).onExpansionStopped(); } private static MotionEvent createMotionEvent(int x, int y, int action) { return MotionEvent.obtain( /* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0); Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt +16 −0 Original line number Diff line number Diff line Loading @@ -361,6 +361,22 @@ class AmbientStateTest : SysuiTestCase() { assertThat(sut.isOnKeyguard).isFalse() } // endregion // region mIsClosing @Test fun isClosing_whenShadeClosing_shouldReturnTrue() { sut.setIsClosing(true) assertThat(sut.isClosing).isTrue() } @Test fun isClosing_whenShadeFinishClosing_shouldReturnFalse() { sut.setIsClosing(false) assertThat(sut.isClosing).isFalse() } // endregion } // region Arrange helper methods. Loading