diff options
6 files changed, 67 insertions, 17 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index 456c321a0c14..2cbb6aea53a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -64,6 +64,7 @@ public class AmbientState implements Dumpable { * Used to read bouncer states. */ private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + private float mStackTop; private float mStackCutoff; private int mScrollY; private float mOverScrollTopAmount; @@ -186,6 +187,7 @@ public class AmbientState implements Dumpable { * @param stackY Distance of top of notifications panel from top of screen. */ public void setStackY(float stackY) { + SceneContainerFlag.assertInLegacyMode(); mStackY = stackY; } @@ -193,6 +195,7 @@ public class AmbientState implements Dumpable { * @return Distance of top of notifications panel from top of screen. */ public float getStackY() { + SceneContainerFlag.assertInLegacyMode(); return mStackY; } @@ -348,6 +351,18 @@ public class AmbientState implements Dumpable { return mZDistanceBetweenElements; } + /** Y coordinate in view pixels of the top of the notification stack */ + public float getStackTop() { + if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return 0f; + return mStackTop; + } + + /** @see #getStackTop() */ + public void setStackTop(float mStackTop) { + if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return; + this.mStackTop = mStackTop; + } + /** * Y coordinate in view pixels above which the bottom of the notification stack / shelf / footer * must be. @@ -769,6 +784,8 @@ public class AmbientState implements Dumpable { @Override public void dump(PrintWriter pw, String[] args) { + pw.println("mStackTop=" + mStackTop); + pw.println("mStackCutoff" + mStackCutoff); pw.println("mTopPadding=" + mTopPadding); pw.println("mStackTopMargin=" + mStackTopMargin); pw.println("mStackTranslation=" + mStackTranslation); 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 0e77ed44293a..c1d60ac48b6a 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 @@ -834,7 +834,7 @@ public class NotificationStackScrollLayout drawDebugInfo(canvas, y, Color.RED, /* label= */ "y = " + y); if (SceneContainerFlag.isEnabled()) { - y = (int) mScrollViewFields.getStackTop(); + y = (int) mAmbientState.getStackTop(); drawDebugInfo(canvas, y, Color.RED, /* label= */ "getStackTop() = " + y); y = (int) mAmbientState.getStackCutoff(); @@ -1214,7 +1214,7 @@ public class NotificationStackScrollLayout @Override public void setStackTop(float stackTop) { - mScrollViewFields.setStackTop(stackTop); + mAmbientState.setStackTop(stackTop); // TODO(b/332574413): replace the following with using stackTop updateTopPadding(stackTop, isAddOrRemoveAnimationPending()); } @@ -1424,11 +1424,7 @@ public class NotificationStackScrollLayout if (mAmbientState.isBouncerInTransit() && mQsExpansionFraction > 0f) { fraction = BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(fraction); } - // TODO(b/322228881): Clean up scene container vs legacy behavior in NSSL - if (SceneContainerFlag.isEnabled()) { - // stackY should be driven by scene container, not NSSL - mAmbientState.setStackY(getTopPadding()); - } else { + if (!SceneContainerFlag.isEnabled()) { final float stackY = MathUtils.lerp(0, endTopPosition, fraction); mAmbientState.setStackY(stackY); } @@ -3721,7 +3717,7 @@ public class NotificationStackScrollLayout protected boolean isInsideQsHeader(MotionEvent ev) { if (SceneContainerFlag.isEnabled()) { - return ev.getY() < mScrollViewFields.getStackTop(); + return ev.getY() < mAmbientState.getStackTop(); } mQsHeader.getBoundsOnScreen(mQsHeaderBound); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt index 2e86ad97a5f4..97ec39192cc8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt @@ -32,8 +32,6 @@ import java.util.function.Consumer class ScrollViewFields { /** Used to produce the clipping path */ var scrimClippingShape: ShadeScrimShape? = null - /** Y coordinate in view pixels of the top of the notification stack */ - var stackTop: Float = 0f /** Y coordinate in view pixels of the top of the HUN */ var headsUpTop: Float = 0f /** Whether the notifications are scrolled all the way to the top (i.e. when freshly opened) */ @@ -76,7 +74,6 @@ class ScrollViewFields { fun dump(pw: IndentingPrintWriter) { pw.printSection("StackViewStates") { pw.println("scrimClippingShape", scrimClippingShape) - pw.println("stackTop", stackTop) pw.println("headsUpTop", headsUpTop) pw.println("isScrolledToTop", isScrolledToTop) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java index f9efc07c67fb..ca74c0e6f9e1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java @@ -29,6 +29,7 @@ import com.android.internal.policy.SystemBarUtils; import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.animation.ShadeInterpolation; import com.android.systemui.res.R; +import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.NotificationShelf; @@ -332,8 +333,10 @@ public class StackScrollAlgorithm { private void updateClipping(StackScrollAlgorithmState algorithmState, AmbientState ambientState) { - float drawStart = ambientState.isOnKeyguard() ? 0 + float stackTop = SceneContainerFlag.isEnabled() ? ambientState.getStackTop() : ambientState.getStackY() - ambientState.getScrollY(); + float drawStart = ambientState.isOnKeyguard() ? 0 + : stackTop; float clipStart = 0; int childCount = algorithmState.visibleChildren.size(); boolean firstHeadsUp = true; @@ -641,7 +644,10 @@ public class StackScrollAlgorithm { // Incoming views have yTranslation=0 by default. viewState.setYTranslation(algorithmState.mCurrentYPosition); - float viewEnd = viewState.getYTranslation() + viewState.height + ambientState.getStackY(); + float stackTop = SceneContainerFlag.isEnabled() + ? ambientState.getStackTop() + : ambientState.getStackY(); + float viewEnd = stackTop + viewState.getYTranslation() + viewState.height; maybeUpdateHeadsUpIsVisible(viewState, ambientState.isShadeExpanded(), view.mustStayOnScreen(), /* topVisible= */ viewState.getYTranslation() >= mNotificationScrimPadding, @@ -681,7 +687,9 @@ public class StackScrollAlgorithm { } } else { if (view instanceof EmptyShadeView) { - float fullHeight = ambientState.getLayoutMaxHeight() + mMarginBottom + float fullHeight = SceneContainerFlag.isEnabled() + ? ambientState.getStackCutoff() - ambientState.getStackTop() + : ambientState.getLayoutMaxHeight() + mMarginBottom - ambientState.getStackY(); viewState.setYTranslation((fullHeight - getMaxAllowedChildHeight(view)) / 2f); } else if (view != ambientState.getTrackedHeadsUpRow()) { @@ -726,7 +734,7 @@ public class StackScrollAlgorithm { + mPaddingBetweenElements; setLocation(view.getViewState(), algorithmState.mCurrentYPosition, i); - viewState.setYTranslation(viewState.getYTranslation() + ambientState.getStackY()); + viewState.setYTranslation(viewState.getYTranslation() + stackTop); } @VisibleForTesting @@ -1002,8 +1010,11 @@ public class StackScrollAlgorithm { // Animate pinned HUN bottom corners to and from original roundness. final float originalCornerRadius = row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius); + final float stackTop = SceneContainerFlag.isEnabled() + ? ambientState.getStackTop() + : ambientState.getStackY(); final float bottomValue = computeCornerRoundnessForPinnedHun(mHostView.getHeight(), - ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius); + stackTop, getMaxAllowedChildHeight(row), originalCornerRadius); row.requestBottomRoundness(bottomValue, STACK_SCROLL_ALGO); row.addOnDetachResetRoundness(STACK_SCROLL_ALGO); } 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 12f3ef3cf553..967f95eb0ef6 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 @@ -214,6 +214,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test + @DisableSceneContainer // TODO(b/332574413) cover stack bounds integration with tests public void testUpdateStackHeight_qsExpansionGreaterThanZero() { final float expansionFraction = 0.2f; final float overExpansion = 50f; @@ -891,6 +892,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase { } @Test + @DisableSceneContainer // NSSL has no more scroll logic when SceneContainer is on public void testNormalShade_hasNoTopOverscroll() { mTestableResources .addOverride(R.bool.config_use_split_notification_shade, /* value= */ false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt index a6fb7187ff5f..93024af2ac84 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt @@ -10,6 +10,8 @@ import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerPr import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ShadeInterpolation.getContentAlpha import com.android.systemui.dump.DumpManager +import com.android.systemui.flags.DisableSceneContainer +import com.android.systemui.flags.EnableSceneContainer import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.res.R @@ -63,7 +65,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { EmptyShadeView(context, /* attrs= */ null).apply { layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100) } - private val footerView = FooterView(context, /*attrs=*/ null) + private val footerView = FooterView(context, /* attrs= */ null) @OptIn(ExperimentalCoroutinesApi::class) private val ambientState = AmbientState( @@ -123,6 +125,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } @Test + @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests fun resetViewStates_defaultHunWhenShadeIsOpening_yTranslationIsInset() { whenever(notificationRow.isPinned).thenReturn(true) whenever(notificationRow.isHeadsUp).thenReturn(true) @@ -165,6 +168,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } @Test + @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME) fun resetViewStates_defaultHun_showingQS_newHeadsUpAnim_hunTranslatedToMax() { // Given: the shade is open and scrolled to the bottom to show the QuickSettings @@ -181,6 +185,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } @Test + @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME) fun resetViewStates_hunAnimatingAway_showingQS_newHeadsUpAnim_hunTranslatedToBottomOfScreen() { // Given: the shade is open and scrolled to the bottom to show the QuickSettings @@ -269,6 +274,27 @@ class StackScrollAlgorithmTest : SysuiTestCase() { } @Test + @EnableSceneContainer + fun resetViewStates_emptyShadeView_isCenteredVertically_withSceneContainer() { + stackScrollAlgorithm.initView(context) + hostView.removeAllViews() + hostView.addView(emptyShadeView) + ambientState.layoutMaxHeight = maxPanelHeight.toInt() + + val stackTop = 200f + val stackBottom = 2000f + val stackHeight = stackBottom - stackTop + ambientState.stackTop = stackTop + ambientState.stackCutoff = stackBottom + + stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0) + + val centeredY = stackTop + stackHeight / 2f - emptyShadeView.height / 2f + assertThat(emptyShadeView.viewState.yTranslation).isEqualTo(centeredY) + } + + @Test + @DisableSceneContainer fun resetViewStates_emptyShadeView_isCenteredVertically() { stackScrollAlgorithm.initView(context) hostView.removeAllViews() @@ -1154,6 +1180,7 @@ class StackScrollAlgorithmTest : SysuiTestCase() { assertFalse(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState)) } + // endregion private fun createHunViewMock( |